"use client"; import { useEffect, useState } from "react"; import Image from "next/image"; import { api } from "./StartGame"; import { PanoramaPreview } from "./PanoramaPreview"; type ReviewMap = { id: string; name: string; description: string; state: string; source: string; panorama_count: number; map: string | null; image: string | null; }; export function Moderation() { const [maps, setMaps] = useState([]), [reports, setReports] = useState< { id: string; dataset_id: string; reason: string }[] >([]), [error, setError] = useState(""), [busy, setBusy] = useState(false), [reasons, setReasons] = useState>({}); const [preview, setPreview] = useState(null), [loading, setLoading] = useState(true); async function load() { try { const d = await api<{ maps: ReviewMap[]; reports: typeof reports }>( "moderation", ); setMaps(d.maps); setReports(d.reports); setError(""); } catch (e) { setError((e as Error).message); } finally { setLoading(false); } } async function resolveReport(id: string) { setBusy(true); setError(""); try { await api(`reports/${id}`, { state: "resolved" }, "PATCH"); await load(); } catch (e) { setError((e as Error).message); } finally { setBusy(false); } } useEffect(() => { load(); }, []); async function decide(datasetId: string, decision: string) { setBusy(true); setError(""); try { await api("moderation", { datasetId, decision, reason: reasons[datasetId] || undefined, }); await load(); } catch (e) { setError((e as Error).message); } finally { setBusy(false); } } return ( <> {error && (

{error}

)} {loading &&

Loading review queue…

} {!loading && !maps.length && !error && (

The review queue is clear.

)} {maps.map((m) => (
{m.state}

{m.name}

{m.source} · {m.panorama_count} locations · {m.description}

{m.map && ( Map for moderator review )}