diff --git a/app/components/Simulation.tsx b/app/components/Simulation.tsx index 1682998..93855b0 100644 --- a/app/components/Simulation.tsx +++ b/app/components/Simulation.tsx @@ -3,13 +3,14 @@ import { useState, useMemo, useCallback, useEffect } from "react"; import { Match, Team } from "@/lib/types"; import { computeGroupTables, computeThirdPlaceTable } from "@/lib/standings"; -import { qualifiedThirdGroups, resolveAnnexC } from "@/lib/bracket"; -import { resolveBracket } from "@/lib/resolve-bracket"; +import { qualifiedThirdGroups, resolveAnnexC, LATER_ROUNDS } from "@/lib/bracket"; +import { resolveBracket, ResolvedTie } from "@/lib/resolve-bracket"; import { loadOverrides, saveOverrides, buildSimMatches, defaultScore, SimOverrides, } from "@/lib/simulation"; import Bracket from "./Bracket"; +import ThirdPlace from "./ThirdPlace"; import Flag from "./Flag"; function teamById(teams: Team[], id: string | null) { @@ -80,8 +81,73 @@ export default function Simulation({ teams, matches }: { teams: Team[]; matches: () => resolveBracket(simMatches, teams, simTables, simThirds, simAnnex, simAnnexResolved, true), [simMatches, teams, simTables, simThirds, simAnnex, simAnnexResolved], ); - const { r32, later } = simBracket; - const preResolved = useMemo(() => ({ r32, later }), [r32, later]); + + // Echte Tabellen/Bracket für fix/provisional-Flags (nur tatsächlich FINISHED). + const realTables = useMemo(() => computeGroupTables(teams, matches), [teams, matches]); + const realThirds = useMemo(() => computeThirdPlaceTable(realTables), [realTables]); + const realQGroups = useMemo(() => qualifiedThirdGroups(realThirds), [realThirds]); + const realAnnex = useMemo( + () => (realQGroups.length === 8 ? resolveAnnexC(realQGroups) : null), + [realQGroups], + ); + const realBracket = useMemo( + () => resolveBracket(matches, teams, realTables, realThirds, realAnnex, realAnnex != null), + [matches, teams, realTables, realThirds, realAnnex], + ); + + // R32: provisional-Flags aus dem echten Bracket übernehmen. + const realProvisional = useMemo(() => { + const m = new Map(); + for (const tie of realBracket.r32) { + m.set(tie.matchNumber, { home: tie.home.provisional, away: tie.away.provisional }); + } + return m; + }, [realBracket]); + + // Folgerunden: decided-Flags aus echten Matches (status === FINISHED). + const realDecided = useMemo(() => { + const m = new Map(); + for (const mt of matches) { + if (mt.group == null && mt.matchNumber >= 73) { + m.set(mt.matchNumber, mt.status === "FINISHED"); + } + } + return m; + }, [matches]); + + // Sim-Bracket mit echten provisional-Flags mergen (inkl. Tooltip-Korrektur). + const preResolved = useMemo(() => { + const fixTooltip = (t: string | null, prov: boolean): string | null => { + if (!t) return t; + if (prov) return t.startsWith("aktuell ") ? t : `aktuell ${t}`; + return t.startsWith("aktuell ") ? t.slice(8) : t; + }; + + const r32Fixed: ResolvedTie[] = simBracket.r32.map((tie) => { + const rp = realProvisional.get(tie.matchNumber); + if (!rp) return tie; + return { + ...tie, + home: { ...tie.home, provisional: rp.home, tooltip: fixTooltip(tie.home.tooltip, rp.home) }, + away: { ...tie.away, provisional: rp.away, tooltip: fixTooltip(tie.away.tooltip, rp.away) }, + }; + }); + + const laterFixed: Record = {}; + for (const km of LATER_ROUNDS) { + const tie = simBracket.later[km.matchNumber]; + if (!tie) continue; + const homeProv = !(realDecided.get(km.fromHome) ?? false); + const awayProv = !(realDecided.get(km.fromAway) ?? false); + laterFixed[km.matchNumber] = { + ...tie, + home: { ...tie.home, provisional: homeProv }, + away: { ...tie.away, provisional: awayProv }, + }; + } + + return { r32: r32Fixed, later: laterFixed }; + }, [simBracket, realProvisional, realDecided]); // ---- Eingabeliste: offene Spiele aus dem echten Feed ---- const openMatches = useMemo( @@ -164,8 +230,14 @@ export default function Simulation({ teams, matches }: { teams: Team[]; matches: )} - {/* ---- Simulierter K.o.-Baum ---- */} + {/* ---- Drittplatzierte (simuliert) ---- */}

+ Drittplatzierte (simuliert) +

+ + + {/* ---- Simulierter K.o.-Baum ---- */} +

Simulierter K.o.-Baum