"use client"; import { useCallback, useState } from "react"; import { toast } from "sonner"; import { api, AdminError, type AdminReport, type ReportType } from "@/lib/api"; import { usePagedList } from "@/lib/use-paged-list"; import { ListShell, EmptyRow } from "@/components/list-shell"; import { Table, THead, TR, TH, TD } from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { useConfirm } from "@/components/confirm"; import { cn, fmtDate } from "@/lib/utils"; const TYPES: { key: ReportType; label: string }[] = [ { key: "post", label: "Posts" }, { key: "comment", label: "Comments" }, { key: "user", label: "Accounts" }, ]; export default function ReportsPage() { const [type, setType] = useState("post"); const [q, setQ] = useState(""); const fetcher = useCallback( (limit: number, offset: number) => api.reports(type, q, limit, offset), [type, q], ); const list = usePagedList(fetcher, [type, q]); const confirm = useConfirm(); async function run(action: Promise, successMsg: string) { try { await action; toast.success(successMsg); list.refresh(); } catch (err) { toast.error(err instanceof AdminError ? err.message : "Action failed."); } } // Per-report moderation buttons. Destructive actions confirm first. function actionsFor(r: AdminReport) { if (r.type === "post") { return ( <> ); } if (r.type === "comment") { return ( ); } return ( ); } const targetLabel = type === "user" ? "Reported account" : type === "comment" ? "Comment" : "Post"; return ( {TYPES.map((t) => ( ))} } > {list.items.length === 0 && !list.loading ? ( ) : ( list.items.map((r) => ( )) )}
{targetLabel} Reason Reporter Reported Actions
{type === "user" ? ( {r.target_text ? `@${r.target_text}` : "—"} ) : ( <>
{r.target_text || "—"}
{r.target_author_handle ? (
by @{r.target_author_handle}
) : null} )}
{r.category}
{r.reason ? (
{r.reason}
) : null}
{r.reporter_handle ? `@${r.reporter_handle}` : "—"} {fmtDate(r.created_at)}
{actionsFor(r)} {r.resolved_at ? ( Resolved ) : ( )}
); }