Corregge il dettaglio MVP in classifica: solo partite, non tutti gli eventi

Il sottotitolo "N partite giocate" per il criterio MVP usava totaliEventiGiocatore(),
che conta anche gli allenamenti: un numero fuorviante perché l'MVP si vota solo alle
partite del calendario interno (eventi_app), non a quelle del sito CSI. Aggiunge
contaPartiteGiocate() (presenze.ts) e Giocatore.partiteGiocate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 11:02:38 +02:00
co-authored by Claude Sonnet 5
parent 15f058f760
commit 8353761b6e
7 changed files with 60 additions and 9 deletions
+3
View File
@@ -28,6 +28,8 @@ export type Giocatore = {
nascita: string;
presenze: number;
totaliEventi: number;
/** Solo partite (non allenamenti) a cui era presente o in ritardo. */
partiteGiocate: number;
streak: number;
/** Serie consecutive per tipo: si azzerano in modo indipendente. */
serieAllenamenti: number;
@@ -103,6 +105,7 @@ export const giocatori: Giocatore[] = rosaCSI
iniziali: inizialiDa(r.nome),
presenze: 0,
totaliEventi: 0,
partiteGiocate: 0,
streak: 0,
serieAllenamenti: 0,
seriePartite: 0,
+28 -3
View File
@@ -14,28 +14,53 @@ export type MappaPresenze = Record<string, Record<string, Stato>>;
export type MappaTempiRisposta = Record<string, Record<string, string>>;
/** Allenamenti e partite CrAPP già passati, che contano per le statistiche di presenza. */
function eventiContanoPresenze(eventi: Evento[], giocatoreId?: string, oggi = dataOggi()) {
function eventiContanoPresenze(
eventi: Evento[],
giocatoreId?: string,
oggi = dataOggi(),
tipo?: "partita" | "allenamento",
) {
return eventi.filter(
(e) =>
(e.tipo === "partita" || e.tipo === "allenamento") &&
(tipo === undefined || e.tipo === tipo) &&
e.data < oggi &&
(giocatoreId === undefined || e.convocati.length === 0 || e.convocati.includes(giocatoreId)),
);
}
/** Presenze effettive (presente o in ritardo) su eventi CrAPP. Senza eventi rilevanti restituisce 0. */
/**
* Presenze effettive (presente o in ritardo) su eventi CrAPP. Senza eventi rilevanti
* restituisce 0. `tipo` filtra a un solo tipo di evento (es. solo partite); di default
* conta partite e allenamenti insieme, come il resto delle statistiche di presenza.
*/
export function contaPresenzeGiocatore(
giocatoreId: string,
eventi: Evento[],
presenze: MappaPresenze,
oggi: string = dataOggi(),
tipo?: "partita" | "allenamento",
): number {
return eventiContanoPresenze(eventi, giocatoreId, oggi).filter((e) => {
return eventiContanoPresenze(eventi, giocatoreId, oggi, tipo).filter((e) => {
const stato = presenze[e.id]?.[giocatoreId];
return stato === "presente" || stato === "ritardo";
}).length;
}
/**
* Partite (non allenamenti) a cui il giocatore era presente o in ritardo: il dato giusto
* per contesti legati alle prestazioni in campo (es. MVP), a differenza di
* `totaliEventiGiocatore()` che è il denominatore delle presenze e include gli allenamenti.
*/
export function contaPartiteGiocate(
giocatoreId: string,
eventi: Evento[],
presenze: MappaPresenze,
oggi: string = dataOggi(),
): number {
return contaPresenzeGiocatore(giocatoreId, eventi, presenze, oggi, "partita");
}
/** Eventi CrAPP rilevanti per il denominatore presenze di un giocatore. */
export function totaliEventiGiocatore(
giocatoreId: string,
+4 -2
View File
@@ -10,6 +10,7 @@ import { useInfortuniERitardi } from "./infortuni";
import { useGiocatoreId } from "./user-store";
import { useEventi } from "./eventi";
import {
contaPartiteGiocate,
contaPresenzeGiocatore,
serieConferme,
serieConsecutiva,
@@ -88,6 +89,7 @@ export function useRosa(): Giocatore[] {
iniziali: iniziali(g.nome, g.cognome),
presenze: contaPresenzeGiocatore(g.id, eventi, mappaPresenze),
totaliEventi: totaliEventiGiocatore(g.id, eventi),
partiteGiocate: contaPartiteGiocate(g.id, eventi, mappaPresenze),
streak: serieConsecutiva(g.id, eventi, mappaPresenze),
serieAllenamenti: serieConsecutiva(g.id, eventi, mappaPresenze, "allenamento"),
seriePartite: serieConsecutiva(g.id, eventi, mappaPresenze, "partita"),
@@ -128,7 +130,7 @@ export function dettaglioClassifica(
g: {
streak: number;
votiPagella: number;
totaliEventi: number;
partiteGiocate: number;
cacche: number;
seriePalloni: number;
},
@@ -138,7 +140,7 @@ export function dettaglioClassifica(
case "mediaVoto":
return `${g.votiPagella} voti pagella`;
case "mvp":
return `${g.totaliEventi} partite giocate`;
return `${g.partiteGiocate} partite giocate`;
case "cacchePartita":
return `${g.cacche} giornate top`;
case "palloni":