import { useEffect, useState } from "react"; import { ApiError } from "../../api/client"; import { Spinner } from "../../components/Spinner"; import { WIN_REASONS, type WinReason } from "../../domain/winReasons"; import { useToast } from "../../context/ToastContext"; import { useAdminFactions, useAdminMatch, useAdminUpdateMatch } from "../../hooks/admin"; interface Row { user_id: number; nickname: string; faction_id: number; place: number; was_random: boolean; comment: string; } export function AdminMatchEdit({ matchId, onClose }: { matchId: number; onClose: () => void }) { const { data: match, isLoading } = useAdminMatch(matchId); const { data: factions } = useAdminFactions(); const update = useAdminUpdateMatch(); const toast = useToast(); const [rows, setRows] = useState([]); const [playedAt, setPlayedAt] = useState(""); const [overall, setOverall] = useState(""); const [winReason, setWinReason] = useState("objectives"); const [error, setError] = useState(null); useEffect(() => { if (match) { setRows( match.participants.map((p) => ({ user_id: p.user_id, nickname: p.nickname, faction_id: p.faction_id, place: p.place ?? 1, was_random: p.was_random, comment: p.comment ?? "", })), ); setPlayedAt(match.played_at); setOverall(match.overall_comment ?? ""); if (match.win_reason) setWinReason(match.win_reason); } }, [match]); const upd = (i: number, patch: Partial) => setRows((rs) => rs.map((r, idx) => (idx === i ? { ...r, ...patch } : r))); const save = async () => { setError(null); try { await update.mutateAsync({ matchId, body: { played_at: playedAt, overall_comment: overall.trim() || null, win_reason: winReason, participants: rows.map((r) => ({ user_id: r.user_id, faction_id: r.faction_id, place: r.place, was_random: r.was_random, comment: r.comment.trim() || null, })), }, }); toast.show("Партия обновлена"); onClose(); } catch (e) { setError(e instanceof ApiError ? e.message : "Не удалось сохранить"); } }; return ( // Полноэкранная страница правки (не нижний «лист»): занимает весь экран.

Правка партии #{matchId}

{isLoading || !match ? ( ) : ( <>
setPlayedAt(e.target.value)} />
{rows.map((r, i) => (
{r.nickname}
upd(i, { place: Math.max(1, Number(e.target.value) || 1) })} />
upd(i, { comment: e.target.value })} />
))}