draupnir4all-web

git clone git://archive.git.mtrnord.blog/MTRNord/draupnir4all-web.git
Log | Files | Refs | README | LICENSE

report-list.tsx (13959B)


      1 "use client";
      2 
      3 import { Report } from "@/app/dashboard/mockData";
      4 import { AlertTriangle, Badge, Ban, CheckCircle, Filter, MessageSquare, UserPlus } from "lucide-react";
      5 import { useState } from "react";
      6 import { Button } from "../ui/button";
      7 import { BlurredText } from "../blurred-text";
      8 import { BlurredImage } from "../blurred-image";
      9 import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "../ui/dialog";
     10 
     11 interface ReportListProps {
     12     reports: Report[]
     13     filter: "all" | "message" | "invite" | "high"
     14 }
     15 
     16 export default function ReportList({ reports, filter }: ReportListProps) {
     17     const [selectedReport, setSelectedReport] = useState<string | null>(null)
     18 
     19     const filteredReports =
     20         filter === "all"
     21             ? reports
     22             : filter === "high"
     23                 ? reports.filter((r) => r.priority === "high")
     24                 : reports.filter((r) => r.type === filter)
     25     return (
     26         <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
     27             <div className="space-y-4">
     28                 <h3 className="text-sm font-medium text-gray-400">Report List</h3>
     29                 {filteredReports.length > 0 ? (
     30                     filteredReports.map((report) => (
     31                         <div
     32                             key={report.id}
     33                             className={`p-3 rounded-md border cursor-pointer transition-colors ${selectedReport === report.id
     34                                 ? "bg-gray-800 border-purple-600"
     35                                 : "bg-gray-900 border-gray-800 hover:border-gray-700"
     36                                 }`}
     37                             onClick={() => setSelectedReport(report.id)}
     38                         >
     39                             <div className="flex items-center justify-between mb-2">
     40                                 <div className="flex items-center gap-2">
     41                                     {report.type === "message" ? (
     42                                         <MessageSquare className="h-4 w-4 text-blue-400" />
     43                                     ) : (
     44                                         <UserPlus className="h-4 w-4 text-green-400" />
     45                                     )}
     46                                     <span className="text-sm font-medium">
     47                                         {report.type === "message" ? "Message Report" : "Invite Report"}
     48                                     </span>
     49                                 </div>
     50                                 <Badge
     51                                     className={
     52                                         report.priority === "high"
     53                                             ? "text-red-300 hover:bg-red-900/70"
     54                                             : "text-yellow-300 hover:bg-yellow-900/70"
     55                                     }
     56                                 >
     57                                     {report.priority}
     58                                 </Badge>
     59                             </div>
     60                             <p className="text-xs text-gray-400 mb-1">{report.room}</p>
     61                             <p className="text-xs text-gray-400 mb-1">
     62                                 {report.type === "message"
     63                                     ? `From: ${report.subject.sender}`
     64                                     : `From: ${report.subject.sender} To: ${report.subject.target}`}
     65                             </p>
     66                             <p className="text-xs text-gray-500">{new Date(report.timestamp).toLocaleString()}</p>
     67                         </div>
     68                     ))
     69                 ) : (
     70                     <div className="flex flex-col items-center justify-center p-8 text-center">
     71                         <CheckCircle className="h-8 w-8 text-gray-500 mb-2" />
     72                         <p className="text-gray-400">No active reports</p>
     73                     </div>
     74                 )}
     75             </div>
     76 
     77             <div className="space-y-4">
     78                 <h3 className="text-sm font-medium text-gray-400">Report Details</h3>
     79                 {selectedReport ? (
     80                     (() => {
     81                         const report = reports.find((r) => r.id === selectedReport)
     82                         if (!report) return <p>Select a report to view details</p>
     83 
     84                         return (
     85                             <div className="space-y-4">
     86                                 <div className="p-4 rounded-md bg-gray-900 border border-gray-800">
     87                                     <div className="flex items-center justify-between mb-3">
     88                                         <h4 className="font-medium">Report Information</h4>
     89                                         <Badge className="bg-purple-900/50 text-purple-300">{report.status}</Badge>
     90                                     </div>
     91 
     92                                     <div className="space-y-2 text-sm">
     93                                         <div className="flex justify-between">
     94                                             <span className="text-gray-400">Reported by:</span>
     95                                             <span>{report.reporter}</span>
     96                                         </div>
     97                                         <div className="flex justify-between">
     98                                             <span className="text-gray-400">Room:</span>
     99                                             <span>{report.room}</span>
    100                                         </div>
    101                                         <div className="flex justify-between">
    102                                             <span className="text-gray-400">Reason:</span>
    103                                             <span>{report.reason}</span>
    104                                         </div>
    105                                         <div className="flex justify-between">
    106                                             <span className="text-gray-400">Time:</span>
    107                                             <span>{new Date(report.timestamp).toLocaleString()}</span>
    108                                         </div>
    109                                     </div>
    110                                 </div>
    111 
    112                                 <div className="p-4 rounded-md bg-gray-900 border border-gray-800">
    113                                     <h4 className="font-medium mb-3">
    114                                         {report.type === "message" ? "Message Content" : "Invite Details"}
    115                                     </h4>
    116 
    117                                     {report.type === "message" && (
    118                                         <div className="space-y-3">
    119                                             <div className="flex justify-between text-sm">
    120                                                 <span className="text-gray-400">Sender:</span>
    121                                                 <span>{report.subject.sender}</span>
    122                                             </div>
    123                                             <div className="flex justify-between text-sm">
    124                                                 <span className="text-gray-400">Message ID:</span>
    125                                                 <span className="font-mono text-xs">{report.subject.id}</span>
    126                                             </div>
    127                                             <div className="flex justify-between text-sm">
    128                                                 <span className="text-gray-400">Time:</span>
    129                                                 <span>{new Date(report.subject.timestamp).toLocaleString()}</span>
    130                                             </div>
    131 
    132                                             <div className="mt-4">
    133                                                 <div className="flex items-center justify-between mb-2">
    134                                                     <span className="text-sm text-gray-400">Content:</span>
    135                                                     {report.subject.content?.msgtype === "m.text" && (
    136                                                         <Button variant="ghost" size="sm" className="h-6 px-2 text-gray-400">
    137                                                             <Filter className="h-3 w-3 mr-1" />
    138                                                             Filter
    139                                                         </Button>
    140                                                     )}
    141                                                 </div>
    142 
    143                                                 {report.subject.content?.msgtype === "m.text" ? (
    144                                                     <BlurredText text={report.subject.content?.body} />
    145                                                 ) : report.subject.content?.msgtype === "m.image" ? (
    146                                                     <div className="mt-2">
    147                                                         <BlurredImage
    148                                                             src="/placeholder.svg?height=300&width=400"
    149                                                             alt={report.subject.content?.body}
    150                                                             width={400}
    151                                                             height={300}
    152                                                         />
    153                                                         <p className="text-xs text-gray-500 mt-1">Image: {report.subject.content.body}</p>
    154                                                     </div>
    155                                                 ) : (
    156                                                     <p className="text-sm">Unsupported content type</p>
    157                                                 )}
    158                                             </div>
    159                                         </div>
    160                                     )}
    161 
    162                                     {report.type === "invite" && (
    163                                         <div className="space-y-3">
    164                                             <div className="flex justify-between text-sm">
    165                                                 <span className="text-gray-400">Sender:</span>
    166                                                 <span>{report.subject.sender}</span>
    167                                             </div>
    168                                             <div className="flex justify-between text-sm">
    169                                                 <span className="text-gray-400">Target:</span>
    170                                                 <span>{report.subject.target}</span>
    171                                             </div>
    172                                             <div className="flex justify-between text-sm">
    173                                                 <span className="text-gray-400">Time:</span>
    174                                                 <span>{new Date(report.subject.timestamp).toLocaleString()}</span>
    175                                             </div>
    176                                         </div>
    177                                     )}
    178                                 </div>
    179 
    180                                 <div className="flex gap-2 mt-4">
    181                                     <Button className="bg-green-600 text-white hover:bg-green-700">
    182                                         <CheckCircle className="mr-2 h-4 w-4" />
    183                                         Resolve
    184                                     </Button>
    185                                     <Dialog>
    186                                         <DialogTrigger asChild>
    187                                             <Button
    188                                                 variant="outline"
    189                                                 className="border-red-500 text-red-400 hover:bg-red-950 hover:text-red-300"
    190                                             >
    191                                                 <Ban className="mr-2 h-4 w-4" />
    192                                                 Ban User
    193                                             </Button>
    194                                         </DialogTrigger>
    195                                         <DialogContent className="bg-gray-950 border-gray-800">
    196                                             <DialogHeader>
    197                                                 <DialogTitle>Ban User</DialogTitle>
    198                                                 <DialogDescription className="text-gray-400">
    199                                                     Ban {report.subject.sender} from your Matrix rooms
    200                                                 </DialogDescription>
    201                                             </DialogHeader>
    202                                             {/* Ban dialog content */}
    203                                         </DialogContent>
    204                                     </Dialog>
    205                                     {report.type === "message" && (
    206                                         <Button
    207                                             variant="outline"
    208                                             className="border-gray-700 text-gray-400 hover:bg-gray-900 hover:text-gray-300"
    209                                         >
    210                                             <MessageSquare className="mr-2 h-4 w-4" />
    211                                             Delete Message
    212                                         </Button>
    213                                     )}
    214                                 </div>
    215                             </div>
    216                         )
    217                     })()
    218                 ) : (
    219                     <div className="flex flex-col items-center justify-center p-8 text-center">
    220                         <AlertTriangle className="h-8 w-8 text-gray-500 mb-2" />
    221                         <p className="text-gray-400">Select a report to view details</p>
    222                     </div>
    223                 )}
    224             </div>
    225         </div>
    226     )
    227 }