// Pro Screens: Partidos, Asistencia, Agenda, Mensajes // ── PARTIDOS ───────────────────────────────────────────── function ProPartidos({ onPlayerSelect }) { const { games, players, rawStats } = window.TData; const [selected, setSelected] = React.useState(null); if (selected) return setSelected(null)} onPlayerSelect={onPlayerSelect} />; const cols = [ {key:"date", label:"Fecha"}, {key:"rival", label:"Rival"}, {key:"loc", label:"Sede"}, {key:"score", label:"Marcador", bold:true}, {key:"diff", label:"Dif."}, {key:"pts", label:"Pts nuestros", right:true}, {key:"con", label:"Pts rival", right:true, color:T.muted}, ]; const rows = [...games].reverse().map(g=>{ const win=g.result==="W", diff=g.scoreUs-g.scoreThem; return { _game:g, date: new Date(g.date).toLocaleDateString("es-MX",{day:"numeric",month:"short",year:"numeric"}), rival:{g.rival}, loc: , score:{g.scoreUs}–{g.scoreThem}, diff: {win?"+":""}{diff}, pts: g.scoreUs, con: g.scoreThem, }; }); const wins=games.filter(g=>g.result==="W").length; const avgPts=(games.reduce((s,g)=>s+g.scoreUs,0)/games.length).toFixed(1); const avgCon=(games.reduce((s,g)=>s+g.scoreThem,0)/games.length).toFixed(1); const avgDiff=((games.reduce((s,g)=>s+g.scoreUs,0)-games.reduce((s,g)=>s+g.scoreThem,0))/games.length).toFixed(1); return (

Partidos

Temporada 2025–26 · {games.length} partidos

0?T.green:T.red} sub="promedio" />
Historial de partidos — haz clic para ver estadísticas
setSelected(row._game)} />
g.scoreUs)} labels={games.map(g=>g.rival.slice(0,4))} color={T.accent} height={160} />
); } function ProGameDetail({ game:g, players, rawStats, onBack, onPlayerSelect }) { const stats = rawStats[g.id]||{}; const win = g.result==="W"; const played = players.filter(p=>stats[p.id]&&stats[p.id][9]>0).sort((a,b)=>(stats[b.id][0]||0)-(stats[a.id][0]||0)); const cols = [ {key:"player",label:"Jugadora"}, {key:"min", label:"Min", right:true}, {key:"pts", label:"Pts", right:true, bold:true, color:T.accent}, {key:"reb", label:"Reb", right:true}, {key:"ast", label:"Ast", right:true}, {key:"stl", label:"Rob", right:true}, {key:"fg", label:"FG", right:true}, {key:"fgpct", label:"FG%", right:true}, {key:"ft", label:"TL", right:true}, {key:"fouls", label:"F", right:true, color:T.muted}, {key:"to", label:"P", right:true, color:T.muted}, ]; const rows = played.map(p=>{ const s=stats[p.id]||[]; return { _player:p, player:(
#{p.num} {p.name}
), min:`${s[9]}'`,pts:s[0],reb:s[1],ast:s[2],stl:s[3], fg:`${s[6]}/${s[7]}`, fgpct:s[7]?`${Math.round(s[6]/s[7]*100)}%`:"—", ft:`${s[4]}/${s[5]}`,fouls:s[8],to:s[10] }; }); return (
{/* Result header */}
{new Date(g.date).toLocaleDateString("es-MX",{weekday:"long",day:"numeric",month:"long",year:"numeric"})} · {g.location}
Tormentas vs {g.rival}
{g.scoreUs}
TORMENTAS
{g.scoreThem}
{g.rival.toUpperCase()}
{win?"Victoria":"Derrota"}
Estadísticas individuales · haz clic para ver perfil
onPlayerSelect(row._player)} />
); } // ── ASISTENCIA ──────────────────────────────────────────── function ProAsistencia() { const { players, trainingDates, attendance } = window.TData; const [att, setAtt] = React.useState(()=>{ const s={}; players.forEach(p=>{ s[p.id]={}; trainingDates.forEach((d,i)=>{ s[p.id][d]=attendance[p.id][i].present; }); }); return s; }); const toggle=(pid,d)=>setAtt(p=>({...p,[pid]:{...p[pid],[d]:!p[pid][d]}})); const getPct=pid=>{ const v=Object.values(att[pid]); return Math.round(v.filter(Boolean).length/v.length*100); }; const dLabel=d=>new Date(d+"T12:00:00").toLocaleDateString("es-MX",{day:"numeric",month:"short"}).replace(".",""); const teamAvg=Math.round(players.reduce((s,p)=>s+getPct(p.id),0)/players.length); return (

Asistencia

Haz clic en una celda para marcar o desmarcar asistencia

=80?T.green:T.yellow} /> getPct(p.id)===100).length} sub="jugadoras" color={T.green} /> getPct(p.id)<70).length} sub="menos de 70%" color={T.red} />
{trainingDates.map(d=>( ))} {players.map((p,pi)=>{ const pct=getPct(p.id); const attColor=pct>=85?T.green:pct>=70?T.yellow:T.red; return ( {trainingDates.map(d=>( ))} ); })}
Jugadora{dLabel(d)}%
#{p.num} {p.name}
toggle(p.id,d)} style={{ width:30,height:30,borderRadius:5,cursor:"pointer",margin:"0 auto", background:att[p.id][d]?T.accentLt:T.redLt, border:`1px solid ${att[p.id][d]?T.accentMd:"#fecaca"}`, display:"flex",alignItems:"center",justifyContent:"center", fontSize:13,color:att[p.id][d]?T.accent:T.red, fontWeight:700,transition:"all 0.12s",userSelect:"none" }}>{att[p.id][d]?"✓":"–"}
{pct}%
); } // ── AGENDA ──────────────────────────────────────────────── function ProAgenda() { const { upcomingEvents, trainingSessions, games } = window.TData; const [tab, setTab] = React.useState("proximos"); return (

Agenda

Partidos y plan de entrenamiento

{tab==="proximos" && (
{upcomingEvents.map(ev=>(
{ev.date}
{ev.type==="partido"?`vs ${ev.rival}`:ev.title}
{ev.location}
{ev.time} hrs
))}
)} {tab==="entrenamientos" && (
{trainingSessions.map(s=>(
{new Date(s.date).toLocaleDateString("es-MX",{day:"numeric",month:"short"})}
{s.duration} min
{s.title}
{s.focus}
{s.drills.map(d=>( {d} ))}
))}
)} {tab==="historial" && ( { const win=g.result==="W"; return { date:new Date(g.date).toLocaleDateString("es-MX",{day:"numeric",month:"long",year:"numeric"}), rival:g.rival, loc:, score:{g.scoreUs}–{g.scoreThem}, diff:{win?"+":" "}{g.scoreUs-g.scoreThem} }; })} />
)}
); } // ── MENSAJES ────────────────────────────────────────────── function ProMensajes() { const { messages, players } = window.TData; const [selected, setSelected] = React.useState(null); const [compose, setCompose] = React.useState(false); const [newMsg, setNewMsg] = React.useState({subject:"",body:""}); const [localMsgs, setLocalMsgs] = React.useState(messages); const send=()=>{ if(!newMsg.subject.trim()) return; setLocalMsgs(p=>[{id:Date.now(),date:new Date().toISOString().split("T")[0],from:"Entrenadora García",to:"Todos",subject:newMsg.subject,body:newMsg.body,avatar:"EG"},...p]); setNewMsg({subject:"",body:""}); setCompose(false); }; return (

Comunicación

Avisos y mensajes para padres de familia

{compose && ( Nuevo aviso para padres
setNewMsg(p=>({...p,subject:e.target.value}))} placeholder="Asunto del mensaje..." style={{width:"100%",padding:"9px 12px",border:`1px solid ${T.border}`,borderRadius:6, fontSize:13,color:T.text,outline:"none",fontFamily:"inherit",boxSizing:"border-box"}} />