"use client"; import { useEffect, useState } from "react"; import Link from "next/link"; import { api } from "@/lib/client-api"; import { communityCategories, type CommunityReportView, } from "@/shared/community"; import { useI18n } from "./I18nProvider"; type Queue = { reports: CommunityReportView[]; nextCursor: string | null }; export function CommunityModeration() { const { t } = useI18n(); const [queue, setQueue] = useState(null); const [reasons, setReasons] = useState>({}); const [busy, setBusy] = useState(false); const [error, setError] = useState(""); async function load() { setQueue(await api("moderation/community-reports")); } useEffect(() => { let active = true; api("moderation/community-reports") .then((result) => { if (active) setQueue(result); }) .catch((e) => { if (active) setError(e.message); }); return () => { active = false; }; }, []); async function act(action: () => Promise) { setBusy(true); setError(""); try { await action(); await load(); } catch (e) { setError((e as Error).message); } finally { setBusy(false); } } async function more() { if (queue?.nextCursor == null) return; setBusy(true); setError(""); try { const next = await api( `moderation/community-reports?cursor=${encodeURIComponent(queue.nextCursor)}`, ); setQueue((current) => ({ ...next, reports: [ ...(current?.reports ?? []), ...next.reports.filter( (r) => !current?.reports.some((old) => old.id === r.id), ), ], })); } catch (e) { setError((e as Error).message); } finally { setBusy(false); } } return (

{t("Comment and account reports")}

{t( "Review the evidence before taking action. Resolving a report does not automatically ban an account or remove a comment.", )}

{error && (

{t(error)}{" "}

)} {!queue && !error &&

{t("Loading review queue…")}

} {queue?.reports.length === 0 && (

{t("No open comment or account reports.")}

)} {queue?.reports.map((report) => (

{t( report.target === "comment" ? "Reported comment" : "Reported account", )}{" "} · {t(communityCategories[report.category])}

{report.target === "account" && (

{report.accountName ?? t("Deleted player")} ·{" "} {report.account_id}

)} {report.comment && ( <>
{report.comment.body}

{t("Open map")} {" "} {report.comment.removed_at ? ( t("Comment removed.") ) : ( )}

{t("Account ID:")}{" "} {report.comment.author_id ?? t("Deleted player")}

)}

{report.reason}