"use client"; import { useEffect, useState, useCallback } from "react"; import { GroupId, GroupTable, Match, Team, ThirdPlaceRow } from "@/lib/types"; import { ThirdAssignment } from "@/lib/bracket"; import Groups from "./components/Groups"; import ThirdPlace from "./components/ThirdPlace"; import Bracket from "./components/Bracket"; import Fixtures from "./components/Fixtures"; interface ApiData { updatedAt: string; teams: Team[]; matches: Match[]; groupTables: GroupTable[]; thirdTable: ThirdPlaceRow[]; annexAssignment: ThirdAssignment | null; annexResolved: boolean; } type Tab = "groups" | "fixtures" | "thirds" | "bracket"; export default function Home() { const [data, setData] = useState(null); const [error, setError] = useState(null); const [tab, setTab] = useState("groups"); // Zuletzt gewählte Gruppe für den Spiele-Tab. null = noch keine gewählt. const [fixturesGroup, setFixturesGroup] = useState(null); const load = useCallback(async () => { try { const res = await fetch("/api/matches", { cache: "no-store" }); if (!res.ok) { const body = await res.json().catch(() => ({})); throw new Error(body.detail || `Fehler ${res.status}`); } setData(await res.json()); setError(null); } catch (e) { setError(e instanceof Error ? e.message : "Verbindung fehlgeschlagen"); } }, []); useEffect(() => { load(); const id = setInterval(load, 30_000); // alle 30 s aktualisieren return () => clearInterval(id); }, [load]); // Klick auf einen Gruppen-Header: Gruppe merken und zum Spiele-Tab wechseln. const openGroupFixtures = useCallback((g: GroupId) => { setFixturesGroup(g); setTab("fixtures"); }, []); const anyLive = data?.matches.some( (m) => m.status === "LIVE" || m.status === "IN_PLAY" || m.status === "PAUSED", ); return ( <>
WM 26 USA · Kanada · Mexiko
{error ? "Feed offline" : data ? anyLive ? "Live" : `Aktualisiert ${new Date(data.updatedAt).toLocaleTimeString("de-DE")}` : "Lade Daten…"}
{error && (
Die Live-Feeds sind gerade nicht erreichbar: {error}. Prüfe den FOOTBALL_DATA_TOKEN und die Netzwerkfreigabe des Servers. Die Seite versucht es automatisch erneut.
)} {!data && !error && (
{Array.from({ length: 6 }).map((_, i) =>
)}
)} {data && tab === "groups" && ( )} {data && tab === "fixtures" && fixturesGroup && ( )} {data && tab === "thirds" && ( )} {data && tab === "bracket" && ( )}
); }