// 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 });