// matches.jsx — lista de partidos por día + detalle de partido + carga rápida por jugador. Exported to window. const { useState: useStateM } = React; function statusOf(m, state) { if (m.archived) return { label: "Finalizado", cls: "st-final" }; if (window.isFinal(m, state)) return { label: "Final", cls: "st-final" }; const r = window.resultFor(m, state); if (r && (r.h != null || r.a != null)) return { label: "En curso", cls: "st-live" }; return { label: "Por jugar", cls: "st-soon" }; } function shortDate(d) { const parts = String(d || "").split("-").map(Number); if (parts.length !== 3 || parts.some(Number.isNaN)) return d; return `${parts[2]}/${parts[1]}`; } function MatchCard({ m, state, onOpen }) { const st = statusOf(m, state); const r = window.resultFor(m, state); const H = window.TEAMS[m.home], A = window.TEAMS[m.away]; const hasScore = r && r.h != null && r.a != null; const nPreds = state.preds && state.preds[m.id] ? Object.keys(state.preds[m.id]).length : 0; return ( ); } const GROUP_LETTERS = Object.keys(window.GROUP_TEAMS); function MatchListMode({ state, onOpen }) { const [filter, setFilter] = useStateM("today"); let list = window.MATCHES; if (filter === "today") list = list.filter((m) => m.day === window.TODAY); else if (filter !== "all") list = list.filter((m) => m.group === filter); const days = [...new Set(list.map((m) => m.day))]; const todayCount = window.MATCHES.filter((m) => m.day === window.TODAY).length; return ( <>
{GROUP_LETTERS.map((g) => ( ))}
{days.length === 0 &&
No hay partidos hoy. Toca “Todos” o una letra de grupo.
} {days.map((d) => (
{window.dayLabel(d)}
{list.filter((m) => m.day === d).map((m) => ( ))}
))}
); } function PlayerPredRow({ m, player, state, setPred, onOpen }) { const pred = ((state.preds || {})[m.id] && (state.preds || {})[m.id][player.id]) || {}; const H = window.TEAMS[m.home], A = window.TEAMS[m.away]; const isComplete = pred.h != null && pred.a != null; return (
setPred(m.id, player.id, "h", v)} /> VS. setPred(m.id, player.id, "a", v)} />
); } function PlayerEntryMode({ state, setPred, onOpen }) { const days = [...new Set(window.MATCHES.map((m) => m.day))]; const defaultDay = days.includes(window.TODAY) ? window.TODAY : days.find((d) => window.MATCHES.some((m) => m.day === d && !window.isFinal(m, state))) || days[0]; const [day, setDay] = useStateM(defaultDay); const [playerId, setPlayerId] = useStateM(window.PLAYERS[0].id); const player = window.PLAYERS.find((p) => p.id === playerId) || window.PLAYERS[0]; const dayMatches = window.MATCHES.filter((m) => m.day === day); const completed = dayMatches.filter((m) => { const pred = ((state.preds || {})[m.id] && (state.preds || {})[m.id][player.id]) || {}; return pred.h != null && pred.a != null; }).length; return (
{window.PLAYERS.map((p) => ( ))}
{days.map((d) => ( ))}
{player.full || player.name}

Juego para {day === window.TODAY ? "hoy" : "el día"} {shortDate(day)}

{completed}/{dayMatches.length}
Anota todos los pronósticos de una persona en una sola pantalla, como los envían por WhatsApp.
{dayMatches.map((m) => ( ))}
Guardado automático en este dispositivo.
); } function MatchesScreen({ state, setPred, onOpen }) { const [mode, setMode] = useStateM("player"); return (
Horario de Venezuela · 72 partidos

Partidos

{mode === "player" ? : }
); } function MatchDetail({ matchId, state, scoring, setResult, setPred, onClose }) { const m = window.MATCHES.find((x) => x.id === matchId); const H = window.TEAMS[m.home], A = window.TEAMS[m.away]; const r = window.resultFor(m, state) || {}; const final = window.isFinal(m, state); const locked = m.archived; const draftH = r.h, draftA = r.a; return (
P{m.num} · Grupo {m.group} · {window.dayLabel(m.day)}
{H.name} {H.prov && {H.hint}}
{final || (r.h != null && r.a != null) ?
{r.h ?? "–"}:{r.a ?? "–"}
:
VS
}
{statusOf(m, state).label}
{A.name} {A.prov && {A.hint}}
{m.kickoff} {m.venue}
{/* Resultado real */}
Resultado real {locked && archivado}
{locked ? (
Partido archivado · {r.h}-{r.a}. Sus puntos base ya están en el acumulado.
) : ( <>
setResult(m.id, { ...r, h: v })} accent="var(--blue-ink)" />
:
setResult(m.id, { ...r, a: v })} accent="var(--blue-ink)" />
)}
{/* Pronósticos por jugador */}
Pronósticos · {window.PLAYERS.length} jugadores {final && puntos calculados}
{window.PLAYERS.map((p) => { const pred = ((state.preds || {})[m.id] && (state.preds || {})[m.id][p.id]) || {}; const oc = final ? window.matchOutcome(pred, r) : null; const pts = final ? window.matchPoints(pred, r, scoring) : null; return (
{p.name}{p.padrino && padrino}
setPred(m.id, p.id, "h", v)} /> : setPred(m.id, p.id, "a", v)} />
); })}
); } Object.assign(window, { MatchesScreen, MatchDetail });