"use client"; import { useCallback, useEffect, useState } from "react"; import { api } from "@/lib/client-api"; import { useI18n } from "./I18nProvider"; type Community = { owner: boolean; moderator: boolean; slowSeconds: number; moderators: string[]; tags: Record; bans: { accountId?: string; id?: string; name: string }[]; }; export function TournamentModeration({ id, players, ownerId, you, party = false, playing = false, }: { id: string; players: { accountId: string; name: string }[]; ownerId: string | null; you: string | null; party?: boolean; playing?: boolean; }) { const { t } = useI18n(); const [community, setCommunity] = useState(null); const [error, setError] = useState(""); const [busy, setBusy] = useState(false); const [tags, setTags] = useState>({}); const endpoint = `${party ? "rooms" : "tournaments"}/${id}/community`; const load = useCallback(async () => { try { setCommunity(await api(endpoint)); } catch (failure) { setCommunity(null); setError((failure as Error).message); } }, [endpoint]); useEffect(() => { void load(); const timer = window.setInterval(() => { if (!document.hidden) void load(); }, 5000); return () => window.clearInterval(timer); }, [load]); async function act(action: string, fields: object = {}) { if (busy) return; setBusy(true); setError(""); try { await api(endpoint, { action, ...fields }); await load(); } catch (failure) { setError((failure as Error).message); } finally { setBusy(false); } } if (!community) return null; if (!community.moderator) { const tagged = players.filter((player) => community.tags[player.accountId]); return tagged.length ? (

{tagged .map( (player) => `${player.name} · ${community.tags[player.accountId]}`, ) .join(" | ")}

) : null; } const panel = (

{t(party ? "Party moderation" : "Tournament moderation")}

{error && (

{t(error)}

)}
{ event.preventDefault(); const data = new FormData(event.currentTarget); void act("slow", { seconds: Number(data.get("seconds")) }); }} >
    {players .filter( (player) => player.accountId !== ownerId && player.accountId !== you && (community.owner || !community.moderators.includes(player.accountId)), ) .map((player) => (
  • {player.name} {community.moderators.includes(player.accountId) && ` · ${t("Moderator")}`} {community.tags[player.accountId] && ` · ${community.tags[player.accountId]}`}
    {community.owner && ( )}
    { event.preventDefault(); void act("tag", { [party ? "playerId" : "accountId"]: player.accountId, tag: tags[player.accountId] ?? community.tags[player.accountId] ?? "", }); }} >
  • ))}
{community.bans.length > 0 && ( <>

{t("Banned players")}

    {community.bans.map((player) => (
  • {player.name}{" "}
  • ))}
)}
); if (!playing) return panel; return (
{t("Party moderation")} {panel}
); }