- Modello: tipo sugli slot, inRosa() al posto del filtro su attivo in tutte le letture della rosa di gioco (presenze, convocati, voti, palloni, classifiche, badge, sollecito); gli allenatori restano solo nei compleanni e in Squadra. - Permessi: user_roles letto una volta per tutti i ruoli; usePuoGestireEventi() apre /eventi e il sollecito presenze anche all'allenatore, lato server con richiediGestoreEventi(). Palloni, sondaggio e messaggi restano all'admin. - Identità: useGiocatoreInCampo() è null per l'allenatore, così non risponde alle presenze e non vota; useSonoAllenatore() decide cosa si vede. - Profilo: per l'allenatore solo Docs (nome, cognome, nascita, telefono, email) e Opzioni; card avatar e tab Opzioni estratte per riusarle. - Home, Squadra e partita: niente statistiche personali, badge, cacche e obiettivi per l'allenatore; in Rosa compare con la dicitura «Allenatore». - Admin: tipo in «Aggiungi», allenatori a parte in Profili, fuori da conteggi ed export CSI. Test unit su rosa di gioco e completamento, route test sull'allenatore. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
59 lines
2.0 KiB
TypeScript
59 lines
2.0 KiB
TypeScript
import { AlertCircle } from "lucide-react";
|
|
import { formatData } from "@/lib/crapp-data";
|
|
import { eventiPalloni, eventoPrecedente, eventoSuccessivo, oggiISO } from "@/lib/palloni-core";
|
|
import { useTurniPalloni } from "@/lib/palloni";
|
|
import { useEventi } from "@/lib/eventi";
|
|
import { useGiocatoreInCampo } from "@/lib/user-store";
|
|
|
|
/** Avvisi per chi è di turno: prendere i palloni oggi, o riportarli oggi. */
|
|
export function PromemoriaPalloni() {
|
|
// Solo `.id` serve qui, niente statistiche; `null` per l'allenatore, che non gioca (DD-034). Montato in Home.
|
|
const io = useGiocatoreInCampo();
|
|
const { turni } = useTurniPalloni();
|
|
const { eventi } = useEventi();
|
|
if (!io) return null;
|
|
|
|
const lista = eventiPalloni(eventi);
|
|
|
|
const oggi = oggiISO();
|
|
const messaggi: string[] = [];
|
|
|
|
for (const evento of lista) {
|
|
if (evento.data !== oggi) continue;
|
|
|
|
if (turni[evento.id] === io.id) {
|
|
const dopo = eventoSuccessivo(eventi, evento.id);
|
|
messaggi.push(
|
|
`Oggi tocca a te prendere i palloni a fine ${evento.tipo === "partita" ? "partita" : "allenamento"}` +
|
|
(dopo ? ` e riportarli il ${formatData(dopo.data)}.` : "."),
|
|
);
|
|
}
|
|
|
|
const prima = eventoPrecedente(eventi, evento.id);
|
|
if (prima && turni[prima.id] === io.id) {
|
|
messaggi.push("Ricordati di portare i palloni con te oggi: li hai presi tu la volta scorsa.");
|
|
}
|
|
}
|
|
|
|
if (messaggi.length === 0) {
|
|
const prossimo = lista.find((e) => e.data >= oggi && turni[e.id] === io.id);
|
|
if (!prossimo) return null;
|
|
messaggi.push(
|
|
`Sei incaricato dei palloni per ${prossimo.titolo} (${formatData(prossimo.data)}).`,
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="mx-5 mt-4 rounded-3xl bg-accent-grad p-4 text-accent-foreground shadow-pop">
|
|
<p className="flex items-center gap-2 font-display text-lg uppercase leading-none">
|
|
<AlertCircle className="h-5 w-5" /> Turno palloni
|
|
</p>
|
|
{messaggi.map((m) => (
|
|
<p key={m} className="mt-2 text-xs leading-snug opacity-90">
|
|
{m}
|
|
</p>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|