Le azioni da referente (/scout, /eventi, sollecito presenze, export CSV scout) non dipendono più da quale giocatore hai scelto di essere in /benvenuto (chiunque poteva scegliere "Ivan Cacciari" senza password), ma da un login reale contro l'account admin di Strapi (già usato per gestire rosa/classifica/storico), verificato via /admin/login. Nuovi src/lib/admin-auth.ts (loginAdmin/logoutAdmin/useAdminSession, sessione locale di 8h) e src/components/crapp/AdminLogin.tsx (form riutilizzabile), raggiungibile da /profilo e dalle schermate riservate. Rimossi adminNomi/ isAdmin da crapp-data.ts. Resta un limite noto: questo protegge solo la UI dell'app, le tabelle Supabase coinvolte hanno ancora RLS aperta e restano scrivibili in diretto con la chiave anon — un fix più ampio (Supabase Auth + RLS reale) è documentato ma non ancora fatto. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
79 lines
2.2 KiB
TypeScript
79 lines
2.2 KiB
TypeScript
export type Stato = "presente" | "assente" | "forse" | "ritardo" | "infortunato";
|
|
|
|
export const statoMeta: Record<Stato, { label: string; emoji: string; className: string }> = {
|
|
presente: { label: "Presente", emoji: "✅", className: "bg-success text-success-foreground" },
|
|
assente: {
|
|
label: "Assente",
|
|
emoji: "❌",
|
|
className: "bg-destructive text-destructive-foreground",
|
|
},
|
|
forse: { label: "Forse", emoji: "🤔", className: "bg-warning text-warning-foreground" },
|
|
ritardo: { label: "In ritardo", emoji: "⏱️", className: "bg-info text-info-foreground" },
|
|
infortunato: {
|
|
label: "Infortunato",
|
|
emoji: "🩹",
|
|
className: "bg-primary text-primary-foreground",
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Statistiche personali: solo dati equi per tutti i ruoli.
|
|
* Punti, ace e muri restano nello Scout Live come dato tecnico di squadra.
|
|
*/
|
|
export type Giocatore = {
|
|
id: string;
|
|
nome: string;
|
|
numero: number;
|
|
ruolo: string;
|
|
nascita: string;
|
|
presenze: number;
|
|
totaliEventi: number;
|
|
streak: number;
|
|
/** Serie consecutive per tipo: si azzerano in modo indipendente. */
|
|
serieAllenamenti: number;
|
|
seriePartite: number;
|
|
serieConferme: number;
|
|
/** MVP eletti dalla squadra. */
|
|
mvp: number;
|
|
/** Media delle pagelle ricevute dai compagni (1-10). */
|
|
mediaVoto: number;
|
|
/** Quante volte ha portato i palloni. */
|
|
palloni: number;
|
|
/** Partite di campionato con almeno 3 cacche dichiarate. */
|
|
cacche: number;
|
|
/** Media di cacche dichiarate per partita. */
|
|
cacchePartita: number;
|
|
/** Eventi (allenamenti o partite) saltati per infortunio. */
|
|
infortuni: number;
|
|
/** Eventi (allenamenti o partite) a cui sei arrivato in ritardo. */
|
|
ritardi: number;
|
|
iniziali: string;
|
|
};
|
|
|
|
export type Match = {
|
|
id: string;
|
|
data: string;
|
|
avversario: string;
|
|
casa: boolean;
|
|
setNostri: number;
|
|
setLoro: number;
|
|
parziali: Array<[number, number]>;
|
|
mvp: string;
|
|
};
|
|
|
|
export type RigaClassifica = {
|
|
pos: number;
|
|
squadra: string;
|
|
giocate: number;
|
|
vinte: number;
|
|
perse: number;
|
|
setFatti: number;
|
|
setSubiti: number;
|
|
punti: number;
|
|
};
|
|
|
|
export function formatData(iso: string) {
|
|
const d = new Date(iso + "T00:00:00");
|
|
return d.toLocaleDateString("it-IT", { weekday: "short", day: "2-digit", month: "long" });
|
|
}
|