fixes
This commit is contained in:
@@ -12,7 +12,10 @@ function Side({
|
||||
// fix = ein echtes Team steht fest (nicht vorläufig). Eigene Klasse für klares Styling.
|
||||
const fix = s.teamId != null && !s.provisional;
|
||||
return (
|
||||
<div className={`side ${s.isWinner ? "win" : ""} ${s.provisional ? "prov" : ""} ${fix ? "fix" : ""}`}>
|
||||
<div
|
||||
className={`side ${s.isWinner ? "win" : ""} ${s.provisional ? "prov" : ""} ${fix ? "fix" : ""}`}
|
||||
title={s.tooltip ?? undefined}
|
||||
>
|
||||
<span className="nm">
|
||||
{s.teamId ? (
|
||||
<>
|
||||
|
||||
@@ -189,10 +189,15 @@ table.standings { width: 100%; border-collapse: collapse; }
|
||||
font-family: var(--font-mono); font-size: 12px; color: var(--ink-dim);
|
||||
}
|
||||
.bracket-banner .v { font-family: var(--font-mono); font-size: 12px; color: var(--turf); }
|
||||
.bracket-scroll { overflow-x: auto; padding-bottom: 36px; }
|
||||
.bracket-scroll {
|
||||
max-height: calc(100vh - 260px);
|
||||
overflow: auto;
|
||||
padding-bottom: 8px;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
.bracket {
|
||||
display: flex; gap: 26px; min-width: max-content; align-items: stretch;
|
||||
padding-bottom: 16px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.round { display: flex; flex-direction: column; min-width: 220px; }
|
||||
.round-label {
|
||||
|
||||
@@ -21,6 +21,7 @@ export interface ResolvedSide {
|
||||
score: number | null;
|
||||
isWinner: boolean;
|
||||
provisional: boolean; // true = nur auf Basis aktueller Tabelle, noch nicht fix
|
||||
tooltip: string | null; // Hover-Erklärung (Herkunft + ob fix)
|
||||
}
|
||||
|
||||
export interface ResolvedTie {
|
||||
@@ -64,19 +65,23 @@ function resolveR32Slot(
|
||||
matches: Match[],
|
||||
teams: Team[],
|
||||
annexResolved: boolean,
|
||||
): { teamId: string | null; provisional: boolean } {
|
||||
): { teamId: string | null; provisional: boolean; tooltip: string | null } {
|
||||
const table = (g: GroupId) => tables.find((t) => t.group === g);
|
||||
if (slot.type === "W") {
|
||||
const t = table(slot.group!);
|
||||
const teamId = t?.rows.find((r) => r.rank === 1)?.teamId ?? null;
|
||||
// Sieger fix, sobald Platz 1 rechnerisch gesichert ist (auch vor Gruppenende).
|
||||
return { teamId, provisional: !placeIsSecure(slot.group!, 1, teams, matches) };
|
||||
const provisional = !placeIsSecure(slot.group!, 1, teams, matches);
|
||||
const prefix = provisional ? "aktuell " : "";
|
||||
return { teamId, provisional, tooltip: `${prefix}1. Gruppe ${slot.group}` };
|
||||
}
|
||||
if (slot.type === "R") {
|
||||
const t = table(slot.group!);
|
||||
const teamId = t?.rows.find((r) => r.rank === 2)?.teamId ?? null;
|
||||
// Zweiter fix, sobald Platz 2 rechnerisch gesichert ist.
|
||||
return { teamId, provisional: !placeIsSecure(slot.group!, 2, teams, matches) };
|
||||
const provisional = !placeIsSecure(slot.group!, 2, teams, matches);
|
||||
const prefix = provisional ? "aktuell " : "";
|
||||
return { teamId, provisional, tooltip: `${prefix}2. Gruppe ${slot.group}` };
|
||||
}
|
||||
// 3. Platz: braucht Annex-C-Zuordnung + den Gruppensieger dieses Spiels
|
||||
if (slot.type === "3" && assignment && winnerGroup) {
|
||||
@@ -86,16 +91,27 @@ function resolveR32Slot(
|
||||
// Fix nur, wenn Annex C aufgelöst UND die Quellgruppe abgeschlossen ist
|
||||
// (Drittplatzierten-Qualifikation ist gruppenübergreifend, bis zuletzt offen).
|
||||
const fix = annexResolved && groupFinished(thirdGroup, matches);
|
||||
return { teamId: row?.teamId ?? null, provisional: !fix };
|
||||
const provisional = !fix;
|
||||
const prefix = provisional ? "aktuell " : "";
|
||||
return {
|
||||
teamId: row?.teamId ?? null,
|
||||
provisional,
|
||||
tooltip: `${prefix}3. der Gruppe ${thirdGroup}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
return { teamId: null, provisional: true };
|
||||
if (slot.type === "3") {
|
||||
const pool = slot.thirdPool?.join("") ?? "?";
|
||||
return { teamId: null, provisional: true, tooltip: `aktuell 3. Gruppe ${pool}` };
|
||||
}
|
||||
return { teamId: null, provisional: true, tooltip: null };
|
||||
}
|
||||
|
||||
function sideFrom(
|
||||
teamId: string | null, fallbackLabel: string,
|
||||
teams: Team[], feed: Match | undefined, which: "home" | "away",
|
||||
provisional: boolean,
|
||||
tooltip: string | null,
|
||||
): ResolvedSide {
|
||||
const team = teamId ? teams.find((t) => t.id === teamId) : undefined;
|
||||
const score = feed
|
||||
@@ -109,6 +125,7 @@ function sideFrom(
|
||||
score,
|
||||
isWinner: teamId != null && w === teamId,
|
||||
provisional: teamId != null && provisional,
|
||||
tooltip,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -133,8 +150,8 @@ export function resolveBracket(
|
||||
|
||||
const h = resolveR32Slot(rm.home, winnerGroup, tables, assignment, thirds, matches, teams, annexResolved);
|
||||
const a = resolveR32Slot(rm.away, winnerGroup, tables, assignment, thirds, matches, teams, annexResolved);
|
||||
const home = sideFrom(h.teamId, slotLabel(rm.home, assignment, winnerGroup), teams, feed, "home", h.provisional);
|
||||
const away = sideFrom(a.teamId, slotLabel(rm.away, assignment, winnerGroup), teams, feed, "away", a.provisional);
|
||||
const home = sideFrom(h.teamId, slotLabel(rm.home, assignment, winnerGroup), teams, feed, "home", h.provisional, h.tooltip);
|
||||
const away = sideFrom(a.teamId, slotLabel(rm.away, assignment, winnerGroup), teams, feed, "away", a.provisional, a.tooltip);
|
||||
|
||||
winners.set(rm.matchNumber, winnerOf(feed));
|
||||
losers.set(rm.matchNumber, loserOf(feed));
|
||||
@@ -156,8 +173,10 @@ export function resolveBracket(
|
||||
const awayProv = !(decided.get(km.fromAway) ?? false);
|
||||
const homeLabel = `${km.losers ? "Verlierer" : "Sieger"} ${km.fromHome}`;
|
||||
const awayLabel = `${km.losers ? "Verlierer" : "Sieger"} ${km.fromAway}`;
|
||||
const home = sideFrom(homeId, homeLabel, teams, feed, "home", homeProv);
|
||||
const away = sideFrom(awayId, awayLabel, teams, feed, "away", awayProv);
|
||||
const homeTtip = `${km.losers ? "Verlierer" : "Sieger"} aus Spiel ${km.fromHome}`;
|
||||
const awayTtip = `${km.losers ? "Verlierer" : "Sieger"} aus Spiel ${km.fromAway}`;
|
||||
const home = sideFrom(homeId, homeLabel, teams, feed, "home", homeProv, homeTtip);
|
||||
const away = sideFrom(awayId, awayLabel, teams, feed, "away", awayProv, awayTtip);
|
||||
winners.set(km.matchNumber, winnerOf(feed));
|
||||
losers.set(km.matchNumber, loserOf(feed));
|
||||
decided.set(km.matchNumber, feed?.status === "FINISHED");
|
||||
|
||||
Reference in New Issue
Block a user