'use client'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; import useSWR from 'swr'; import { REPORT_REASON_LABELS, timeAgo, type AdminReportDTO, type AdminStatsDTO, type ReportReason } from '@musicshare/shared'; import { Avatar } from '@/components/Avatar'; import { Modal } from '@/components/ProfileMenu'; import { client, fetcher, useMe } from '@/lib/api'; /** Moderation for the server's admin (the first account): reports and suspensions. */ export default function AdminPage() { const { me, loggedOut } = useMe(); const router = useRouter(); const [status, setStatus] = useState<'open' | 'resolved'>('open'); const isAdmin = me?.role === 'admin'; const { data: stats, mutate: refreshStats } = useSWR(isAdmin ? '/admin/stats' : null, fetcher); const { data: reports, mutate } = useSWR(isAdmin ? `/admin/reports?status=${status}` : null, fetcher); const [confirm, setConfirm] = useState(null); if (loggedOut) router.replace('/login'); if (!me) return null; if (!isAdmin) return

Admins only.

; const refresh = () => Promise.all([mutate(), refreshStats()]); const resolve = async (r: AdminReportDTO) => (await client.resolveReport(r.id), refresh()); const toggleSuspend = async (r: AdminReportDTO) => { setConfirm(null); await (r.reported.suspended ? client.unsuspend(r.reported.username) : client.suspend(r.reported.username)); await refresh(); }; return (

Admin

{stats && (
)}

Reports

{(['open', 'resolved'] as const).map((s) => ( ))}
{reports?.length === 0 &&

{status === 'open' ? 'Nothing to review. ๐ŸŽ‰' : 'No resolved reports yet.'}

}
    {reports?.map((r) => (
  • {r.reported.displayName ?? r.reported.username} @{r.reported.username} {r.reported.suspended && Suspended} {timeAgo(r.createdAt)}

    {REPORT_REASON_LABELS[r.reason as ReportReason] ?? r.reason} {r.reporter && ยท reported by @{r.reporter.username}}

    {r.comment && (

    Their comment{r.comment.id ? '' : ' (since deleted)'}: {r.comment.body}

    )} {r.note &&
    {r.note}
    }
    {r.status === 'open' && ( )}
  • ))}
{confirm && ( setConfirm(null)} >

{confirm.reported.suspended ? 'They can sign in again and their profile is visible again. Sharing stays paused until they turn it back on.' : "They're signed out everywhere, can't sign in, their profile is hidden and nothing they play is shared."}

)}
); } function Stat({ label, value }: { label: string; value: number }) { return (
{value}
{label}
); }