// groups.jsx — pantalla "Mundial": tablas de grupos, clasificados y cuadro automático. → window
const { useState: useStateG } = React;
function TeamCell({ code, size = 22 }) {
const t = window.TEAMS[code];
return (<>{t ? t.name : code} >);
}
function GroupMini({ g, state, thirdsQ }) {
const table = window.groupTable(g, state);
const complete = window.groupComplete(g, state);
const finals = window.MATCHES.filter((m) => m.group === g && window.isFinal(m, state)).length;
return (
Grupo {g}
PJ DG Pts
{table.map((t, i) => {
const thirdQual = i === 2 && thirdsQ[t.code];
return (
{i + 1}
{t.pj}
{t.dg > 0 ? "+" + t.dg : t.dg}
{t.pts}
);
})}
{complete ? "Grupo cerrado ✓" : finals + "/6 jugados"}
);
}
function ThirdsPanel({ state }) {
const ts = window.thirdsRanking(state);
return (
Mejores terceros clasifican 8 de 12
{ts.map((t) => (
{t.rank}
{t.group}
{t.complete ? t.pts + " pts" : "—"}
{t.qualifies ? Clasifica : Fuera }
))}
El orden final se confirma al terminar los 12 grupos (puntos · dif. de gol · goles a favor).
);
}
function GroupsView({ state }) {
const T = window.tournamentState(state);
const thirdsQ = {};
T.thirds.forEach((t) => { if (t.qualifies) thirdsQ[t.code] = true; });
const decided = Object.values(T.groups).filter((x) => x.complete).length;
return (
{decided} grupos cerrados
1º y 2º clasifican
mejor 3º
{Object.keys(window.GROUP_TEAMS).map((g) => (
))}
);
}
const ROUNDS = [
{ id: "r32", label: "16avos", n: 16, prefix: "r32" },
{ id: "r16", label: "8vos", n: 8, prefix: "r16" },
{ id: "qf", label: "4tos", n: 4, prefix: "qf" },
{ id: "sf", label: "Semis", n: 2, prefix: "sf" },
{ id: "third", label: "3º", n: 1, prefix: "third" },
{ id: "final", label: "Final", n: 1, prefix: "final" },
];
function KoSide({ slot, picked, canPick, onPick }) {
const t = slot.code ? window.TEAMS[slot.code] : null;
return (
{t
? <>{t.name} >
: {slot.label} }
);
}
function BracketView({ state, setKoWinner }) {
const [round, setRound] = useStateG("r32");
const { matches, T } = window.buildBracket(state);
const rd = ROUNDS.find((r) => r.id === round);
const keys = (round === "final" || round === "third") ? [round] : Array.from({ length: rd.n }, (_, i) => rd.prefix + "-" + (i + 1));
return (
{ROUNDS.map((r) => (
setRound(r.id)}>{r.label}
))}
{T.allComplete
? "El cuadro ya se llenó con los clasificados de grupos. Toca al equipo que avanza para simular las rondas."
: "El cuadro se llenará automáticamente cuando terminen los grupos. Mientras tanto verás los cupos pendientes."}
{keys.map((k) => {
const m = matches[k];
const pick = (state.koWinners || {})[k];
const canPick = !!(m.home.code && m.away.code);
return (
P{m.num}
setKoWinner(k, "home")} />
setKoWinner(k, "away")} />
);
})}
{round === "final" && (() => {
const f = matches["final"]; const pick = (state.koWinners || {}).final;
const champ = pick === "home" ? f.home.code : pick === "away" ? f.away.code : null;
return champ ? (
Campeón del Mundo {window.TEAMS[champ].flag} {window.TEAMS[champ].name}
) : null;
})()}
);
}
function MundialScreen({ state, setKoWinner }) {
const [view, setView] = useStateG("grupos");
return (
Clasificación automática
Mundial 26
setView("grupos")}>Grupos
setView("cuadro")}>Eliminatorias
{view === "grupos" ?
:
}
);
}
Object.assign(window, { MundialScreen });