import { MapPin, Clock, Users, Cake, ChevronRight, Check, HelpCircle, X, Bandage, } from "lucide-react"; import { Link } from "@tanstack/react-router"; import { cn } from "@/lib/utils"; import { Card } from "@/components/crapp/ui-bits"; import { formatData, statoMeta, type Stato } from "@/lib/crapp-data"; import type { Evento } from "@/lib/eventi"; import { useGiocatoriSquadra } from "@/lib/giocatori-squadra"; import { usePresenzeEvento, useSalvaPresenza } from "@/lib/presenze"; import { useGiocatoreBase } from "@/lib/user-store"; import { dataOggi } from "@/lib/scout-live"; const tipoMeta = { partita: { label: "Partita", className: "bg-accent text-accent-foreground" }, allenamento: { label: "Allenamento", className: "bg-training text-training-foreground" }, evento: { label: "Evento", className: "bg-warning text-warning-foreground" }, compleanno: { label: "Compleanno", className: "bg-success text-success-foreground" }, } as const; const statiSportivi: Stato[] = ["presente", "forse", "ritardo", "assente", "infortunato"]; /** Eventi extra-campo (pizze, uscite…): l'infortunio non è una risposta pertinente. */ const statiEventoExtra: Stato[] = ["presente", "forse", "ritardo", "assente"]; /** Icone compatte per la riga unica dei controlli presenza (mockup). */ const iconeStato: Record = { presente: Check, forse: HelpCircle, ritardo: Clock, assente: X, /** Cerotto singolo: leggibile a 16px e allineato all'emoji 🩹. */ infortunato: Bandage, }; export function linkPerEvento(e: Evento) { if (e.tipo === "partita") { return { to: "/partita/$id" as const, params: { id: e.id }, label: "Dettaglio partita" }; } if (e.tipo === "allenamento") { return { to: "/allenamento/$id" as const, params: { id: e.id }, label: "Dettaglio allenamento", }; } return undefined; } function etichettaData(iso: string) { const giorno = iso.slice(8, 10); const mese = formatData(iso).split(" ")[2]?.slice(0, 3)?.toUpperCase() ?? ""; return `${giorno} ${mese}`; } export function EventoCard({ evento, linkTo, }: { evento: Evento; linkTo?: { to: string; params: Record; label: string }; }) { const { risposte } = usePresenzeEvento(evento.id); const salva = useSalvaPresenza(); // Solo `io.id` serve qui (per leggere/scrivere la propria risposta): `useGiocatoreBase` // legge la sola anagrafica, non le statistiche di tutta la rosa di `useGiocatoreCorrente`. // Rilevante perché ogni card monta questo hook: il Calendario ne rende diverse insieme. const io = useGiocatoreBase(); const { righe: squadra } = useGiocatoriSquadra(); const rosa = squadra.filter((g) => g.attivo); const stato = io ? risposte[io.id] : undefined; const presentiVeri = rosa.filter( (g) => risposte[g.id] === "presente" || risposte[g.id] === "ritardo", ).length; const tipo = evento.tipo === "partita" && !evento.campionato ? { label: "Amichevole", className: "bg-accent/70 text-accent-foreground" } : tipoMeta[evento.tipo]; const totale = rosa.length; const isCompleanno = evento.tipo === "compleanno"; const passato = evento.data < dataOggi(); const cliccabile = Boolean(linkTo); /** Solo gli eventi extra-campo non hanno scheda dedicata: le note restano sulla card. */ const noteCard = evento.tipo === "evento" ? evento.note.trim() : ""; const stati = evento.tipo === "evento" ? // Se resta un vecchio "infortunato", mostra il bottone solo per poterlo togliere. stato === "infortunato" ? [...statiEventoExtra, "infortunato" as const] : statiEventoExtra : statiSportivi; if (isCompleanno) { return (

{evento.titolo}

{evento.luogo}

{etichettaData(evento.data)}
); } const sottotitoloPartita = evento.tipo === "partita" ? `${evento.casa ? "Casa" : "Trasferta"}${evento.campionato ? " · Campionato" : " · Amichevole"}` : null; const metaStato = stato ? statoMeta[stato] : null; return ( {/* Link a tutta card: i controlli sopra (z-10) restano indipendenti. */} {linkTo ? ( ) : null}
{tipo.label} {etichettaData(evento.data)} {linkTo ? : null}

{evento.titolo}

{sottotitoloPartita ? (

{sottotitoloPartita}

) : null}
{evento.ora} {evento.luogo} {presentiVeri}/{totale}
{noteCard ? (

📝 {noteCard}

) : null} {metaStato ? (

{metaStato.emoji} {metaStato.label}

) : null} {io ? (
{stati.map((s) => { const meta = statoMeta[s]; const Icon = iconeStato[s]; const attivo = stato === s; return ( ); })}
) : null}
); }