diff --git a/app/components/Bracket.tsx b/app/components/Bracket.tsx index d044711..2f7f2ce 100644 --- a/app/components/Bracket.tsx +++ b/app/components/Bracket.tsx @@ -4,7 +4,7 @@ import { useMemo, useState, useCallback } from "react"; import { GroupTable, Match, Team, ThirdPlaceRow } from "@/lib/types"; import { ThirdAssignment, orderedRound } from "@/lib/bracket"; import { resolveBracket, ResolvedSide, ResolvedTie } from "@/lib/resolve-bracket"; -import { STADIUMS, MATCH_STADIUMS } from "@/lib/stadiums"; +import { STADIUMS, MATCH_STADIUMS, MATCH_DATES } from "@/lib/stadiums"; import Flag from "./Flag"; interface TipState { x: number; y: number; text: string } @@ -49,11 +49,11 @@ function Side({ } function fmtMatchInfo(utcDate?: string, stadiumId?: string): string { - const city = stadiumId ? STADIUMS[stadiumId]?.city : ""; - if (!utcDate) return city; // Stadt auch ohne Datum anzeigen + if (!utcDate) return ""; const d = new Date(utcDate); const dateStr = d.toLocaleDateString("de-DE", { day: "numeric", month: "numeric" }); const timeStr = d.toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" }); + const city = stadiumId ? STADIUMS[stadiumId]?.city : ""; const parts = [`${dateStr}`, `${timeStr}`]; if (city) parts.push(city); return parts.join(" · "); @@ -91,32 +91,17 @@ export default function Bracket({ const r32ByNum = new Map(r32Array.map((t) => [t.matchNumber, t])); - // Baue slotNumber → formatted info (Stadt aus MATCH_STADIUMS, Datum/Uhrzeit aus Feed-Match) - const feedByNum = useMemo(() => { - const m = new Map(); - for (const fm of matches) { - if (fm.group == null) m.set(fm.matchNumber, fm); - } - return m; - }, [matches]); - + // Slot-Nummer → formatierte Anzeige (Datum/Uhrzeit aus MATCH_DATES, Stadt aus MATCH_STADIUMS) const matchMeta = useMemo(() => { const meta = new Map(); for (let n = 73; n <= 104; n++) { + const utcDate = MATCH_DATES[n]; const stadiumId = MATCH_STADIUMS[n]; - const feedMatch = feedByNum.get(n); - const info = fmtMatchInfo(feedMatch?.utcDate, stadiumId); + const info = fmtMatchInfo(utcDate, stadiumId); if (info) meta.set(n, info); - if (feedMatch?.matchNumber === 0 || !feedMatch) { - console.log("[KO-SLOT-DATE]", - "slot:", n, - "| match.matchNumber:", feedMatch?.matchNumber ?? "—", - "| match.utcDate:", feedMatch?.utcDate ?? "—", - "| stadt:", STADIUMS[MATCH_STADIUMS[n]]?.city ?? "—"); - } } return meta; - }, [feedByNum]); + }, []); const sfOrder = orderedRound([104]); const qfOrder = orderedRound(sfOrder); diff --git a/lib/stadiums.ts b/lib/stadiums.ts index 01bc785..82fda3a 100644 --- a/lib/stadiums.ts +++ b/lib/stadiums.ts @@ -18,6 +18,30 @@ export const STADIUMS: Record = { "16": { name: "SoFi Stadium", city: "Los Angeles" }, }; +// K.o.-Spielnummer → ISO-8601 UTC-Anstoßzeit (FIFA-Spielplan, statisch). +export const MATCH_DATES: Record = { + // R32 (28.6.–3.7.) + 73: "2026-06-28T19:00:00Z", 74: "2026-06-29T21:00:00Z", 75: "2026-06-29T22:00:00Z", + 76: "2026-06-29T22:00:00Z", 77: "2026-06-30T17:00:00Z", 78: "2026-06-30T21:00:00Z", + 79: "2026-07-01T19:00:00Z", 80: "2026-07-01T21:00:00Z", 81: "2026-07-01T19:00:00Z", + 82: "2026-07-02T19:00:00Z", 83: "2026-07-02T21:00:00Z", 84: "2026-07-02T19:00:00Z", + 85: "2026-07-03T17:00:00Z", 86: "2026-07-03T21:00:00Z", 87: "2026-07-03T22:00:00Z", + 88: "2026-07-03T22:00:00Z", + // R16 (6.7.–9.7.) + 89: "2026-07-06T21:00:00Z", 90: "2026-07-06T22:00:00Z", 91: "2026-07-07T21:00:00Z", + 92: "2026-07-07T19:00:00Z", 93: "2026-07-08T22:00:00Z", 94: "2026-07-08T19:00:00Z", + 95: "2026-07-09T21:00:00Z", 96: "2026-07-09T19:00:00Z", + // QF (12.7.–13.7.) + 97: "2026-07-12T21:00:00Z", 98: "2026-07-12T19:00:00Z", 99: "2026-07-13T21:00:00Z", + 100: "2026-07-13T22:00:00Z", + // SF (16.7.–17.7.) + 101: "2026-07-16T22:00:00Z", 102: "2026-07-17T21:00:00Z", + // 3RD (19.7.) + 103: "2026-07-19T17:00:00Z", + // FINAL (20.7.) + 104: "2026-07-20T17:00:00Z", +}; + // K.o.-Spielnummer → stadium_id (FIFA-Quelle, statisch). export const MATCH_STADIUMS: Record = { 73: "16", 74: "9", 75: "3", 76: "5", 77: "11", 78: "4", 79: "1", 80: "7",