"use client"; import InviteFriendsModal from "@/components/InviteFriendsModal"; import { useSession } from "@/context/session"; import { fetchTournament, joinTournament, startTournament, addBotToTournament } from "@/lib/tournament"; import { BOTS } from "@/bots"; import type { Tournament, TournamentRound } from "@michess/types"; import Link from "next/link"; import { useParams } from "next/navigation"; import { useEffect, useRef, useState } from "react"; export default function TournamentDetailPage() { const { user } = useSession(); const params = useParams(); const code = params.code as string; const [tournament, setTournament] = useState(null); const [loading, setLoading] = useState(true); const [actionLoading, setActionLoading] = useState(false); const [selectedBot, setSelectedBot] = useState(BOTS[0].name); const intervalRef = useRef | null>(null); async function load() { const t = await fetchTournament(code); setTournament(t); } useEffect(() => { load().then(() => setLoading(false)); // eslint-disable-next-line react-hooks/exhaustive-deps }, [code]); // Auto-refresh every 10 seconds when active useEffect(() => { if (tournament?.status === "active") { intervalRef.current = setInterval(load, 10000); } return () => { if (intervalRef.current) clearInterval(intervalRef.current); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [tournament?.status]); async function handleJoin() { if (!user?.id) return; setActionLoading(true); const updated = await joinTournament(code); if (updated) setTournament(updated); setActionLoading(false); } async function handleAddBot() { setActionLoading(true); const updated = await addBotToTournament(code, selectedBot); if (updated) setTournament(updated); setActionLoading(false); } async function handleStart() { if (!user?.id) return; setActionLoading(true); const updated = await startTournament(code); if (updated) setTournament(updated); setActionLoading(false); } function statusBadge(status: Tournament["status"]) { if (status === "waiting") return Wartet auf Spieler; if (status === "active") return Aktiv; return Beendet; } function resultLabel(r: TournamentRound) { if (!r.result) return ; if (r.result === "draw") return Remis; return ( {r.result === "white" ? r.whiteName : r.blackName} ); } if (loading) { return (
); } if (!tournament) { return
Turnier nicht gefunden.
; } const isHost = tournament.hostId === user?.id; const isJoined = tournament.players?.some((p) => p.userId === user?.id); const canStart = isHost && tournament.status === "waiting" && (tournament.players?.length ?? 0) >= 2; // Group rounds const rounds: Record = {}; for (const r of tournament.rounds ?? []) { if (!rounds[r.round!]) rounds[r.round!] = []; rounds[r.round!].push(r); } return (
{/* Header */}

{tournament.name}

{statusBadge(tournament.status)} {tournament.timeControl ? {tournament.timeControl} Min/Spieler : Keine Uhr} {tournament.status === "active" && ( Runde {tournament.currentRound}/{tournament.totalRounds} )}
{tournament.status === "waiting" && user?.id && !isJoined && ( )} {tournament.status === "waiting" && isJoined && ( )} {isHost && tournament.status === "waiting" && (
)} {canStart && ( )}
{/* Standings */}

Tabelle

{!tournament.players?.length ? (

Noch keine Spieler.

) : ( {tournament.players.map((p, i) => ( ))}
# Spieler Punkte Partien
{i + 1} {p.userName} {p.score} {p.gamesPlayed}
)}
{/* Rounds */} {Object.keys(rounds).length > 0 && (
{Object.entries(rounds).map(([roundNum, games]) => (

Runde {roundNum} {parseInt(roundNum) === tournament.currentRound && tournament.status === "active" && ( Aktuell )}

{games.map((g) => { const isMyGame = g.whiteId === user?.id || g.blackId === user?.id; return (
{g.whiteName} vs {g.blackName}
{resultLabel(g)} {isMyGame && g.gameCode && !g.result && ( Spielen )} {g.gameCode && g.result && ( Ansehen )}
); })}
))}
)}
); }