Sposto rosa, classifica e storico partite dagli array hardcoded al CMS Strapi
Nuovi moduli src/lib/strapi-client.ts + rosa-base.ts/classifica-csi.ts/ storico-match.ts (hook TanStack Query, cache lunga, nessun polling). L'id stabile gN diventa il campo `codice` su Strapi, per non rompere le FK verso pagelle/cacche/mvp/palloni/presenze/azioni scout già chiavate su quella stringa. isAdmin ora prende il Giocatore invece di un id, così non dipende più dal roster. Rifattorizzati di conseguenza tutti i punti che importavano `giocatori`/`classifica`/`storicoMatch` come array sincroni (componenti, hook, due route server) per usare gli hook o un parametro esplicito. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+39
-18
@@ -4,7 +4,8 @@ import { Cake, ChevronDown, Crown } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { PageHeader, Section } from "@/components/crapp/ui-bits";
|
||||
import { Avatar } from "@/components/crapp/Avatar";
|
||||
import { formatData, storicoMatch } from "@/lib/crapp-data";
|
||||
import { formatData } from "@/lib/crapp-data";
|
||||
import { useStoricoMatch } from "@/lib/storico-match";
|
||||
import { microcopyObiettivo, progressoObiettivo } from "@/lib/obiettivi";
|
||||
import { useRosa, useObiettivi } from "@/lib/rosa";
|
||||
import { usePresenzeUltimoMeseTutti } from "@/lib/presenze-mese";
|
||||
@@ -43,7 +44,8 @@ export const Route = createFileRoute("/squadra")({
|
||||
{ title: "Squadra CRAP Volley — CrAPP" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Rosa completa del CRAP Volley: giocatori, dati anagrafici, statistiche stagionali e badge sbloccati.",
|
||||
content:
|
||||
"Rosa completa del CRAP Volley: giocatori, dati anagrafici, statistiche stagionali e badge sbloccati.",
|
||||
},
|
||||
{ property: "og:title", content: "Squadra CRAP Volley — CrAPP" },
|
||||
{
|
||||
@@ -55,7 +57,6 @@ export const Route = createFileRoute("/squadra")({
|
||||
component: Squadra,
|
||||
});
|
||||
|
||||
|
||||
const criteri = [
|
||||
{ id: "presenze", label: "Presenze" },
|
||||
{ id: "mediaVoto", label: "Media voto" },
|
||||
@@ -75,6 +76,7 @@ function valore(
|
||||
|
||||
function Squadra() {
|
||||
const rosa = useRosa();
|
||||
const storicoMatch = useStoricoMatch();
|
||||
const mese = usePresenzeUltimoMeseTutti();
|
||||
const scoutMatches = useScoutMatches();
|
||||
const votiMvp = useVotiMvp();
|
||||
@@ -85,7 +87,9 @@ function Squadra() {
|
||||
const obiettivi = useObiettivi();
|
||||
const team = totaliSquadra(scoutMatches);
|
||||
const mediaPresenze = rosa.length
|
||||
? Math.round((rosa.reduce((s, g) => s + g.presenze / (g.totaliEventi || 1), 0) / rosa.length) * 100)
|
||||
? Math.round(
|
||||
(rosa.reduce((s, g) => s + g.presenze / (g.totaliEventi || 1), 0) / rosa.length) * 100,
|
||||
)
|
||||
: 0;
|
||||
const ordinati = [...rosa].sort((a, b) => valore(b, criterio) - valore(a, criterio));
|
||||
const max = ordinati[0] ? valore(ordinati[0], criterio) || 1 : 1;
|
||||
@@ -116,7 +120,10 @@ function Squadra() {
|
||||
<div className="space-y-2">
|
||||
{rosa.map((g) => {
|
||||
const stati = badgeGiocatore(g);
|
||||
const sbloccati = [...stati.filter((b) => b.grado !== null), ...badgeSegretiSbloccati(g)];
|
||||
const sbloccati = [
|
||||
...stati.filter((b) => b.grado !== null),
|
||||
...badgeSegretiSbloccati(g),
|
||||
];
|
||||
const isOpen = aperto === g.id;
|
||||
return (
|
||||
<article key={g.id} className="overflow-hidden rounded-3xl bg-card shadow-card">
|
||||
@@ -126,7 +133,11 @@ function Squadra() {
|
||||
className="flex w-full items-center gap-3 p-3 text-left active:scale-[0.99]"
|
||||
aria-expanded={isOpen}
|
||||
>
|
||||
<Avatar id={g.id} fallback={g.numero ? String(g.numero) : g.iniziali} className="h-11 w-11 text-lg" />
|
||||
<Avatar
|
||||
id={g.id}
|
||||
fallback={g.numero ? String(g.numero) : g.iniziali}
|
||||
className="h-11 w-11 text-lg"
|
||||
/>
|
||||
<span className="min-w-0 flex-1">
|
||||
<span className="block truncate text-sm font-bold leading-tight">{g.nome}</span>
|
||||
<span className="mt-1 flex items-center gap-2">
|
||||
@@ -160,19 +171,20 @@ function Squadra() {
|
||||
<div className="border-t border-border px-4 pb-4 pt-3">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<p className="inline-flex items-center gap-1.5 text-xs text-muted-foreground">
|
||||
<Cake className="h-3.5 w-3.5" /> {formatData(g.nascita)} {g.nascita.slice(0, 4)}
|
||||
<Cake className="h-3.5 w-3.5" /> {formatData(g.nascita)}{" "}
|
||||
{g.nascita.slice(0, 4)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-3 grid grid-cols-3 gap-2">
|
||||
{[
|
||||
{ l: "Presenze", v: `${g.presenze}/${g.totaliEventi}` },
|
||||
{ l: "Presenze 30gg", v: `${mese[g.id]?.percentuale ?? 0}%` },
|
||||
{ l: "Presenze di fila", v: g.streak },
|
||||
{ l: "Media voto", v: g.mediaVoto || "—" },
|
||||
{ l: "MVP", v: g.mvp },
|
||||
{ l: "Cacche/partita 💩", v: g.cacchePartita || "—" },
|
||||
].map((s) => (
|
||||
{[
|
||||
{ l: "Presenze", v: `${g.presenze}/${g.totaliEventi}` },
|
||||
{ l: "Presenze 30gg", v: `${mese[g.id]?.percentuale ?? 0}%` },
|
||||
{ l: "Presenze di fila", v: g.streak },
|
||||
{ l: "Media voto", v: g.mediaVoto || "—" },
|
||||
{ l: "MVP", v: g.mvp },
|
||||
{ l: "Cacche/partita 💩", v: g.cacchePartita || "—" },
|
||||
].map((s) => (
|
||||
<div key={s.l} className="rounded-2xl bg-secondary p-2.5 text-center">
|
||||
<p className="font-display text-xl leading-none">{s.v}</p>
|
||||
<p className="mt-1 text-[10px] font-semibold uppercase text-muted-foreground">
|
||||
@@ -201,9 +213,16 @@ function Squadra() {
|
||||
<p className="mt-1 text-xs font-bold leading-tight">{b.def.nome}</p>
|
||||
<p className="text-[10px] text-muted-foreground">
|
||||
{b.valore} {b.def.unita}
|
||||
{b.prossimaSoglia ? ` · ${b.prossimaSoglia} per ${gradoMeta[b.prossimo!].label.toLowerCase()}` : ""}
|
||||
{b.prossimaSoglia
|
||||
? ` · ${b.prossimaSoglia} per ${gradoMeta[b.prossimo!].label.toLowerCase()}`
|
||||
: ""}
|
||||
</p>
|
||||
<p className={cn("mt-1.5 text-[10px] font-bold uppercase", meta.text)}>
|
||||
<p
|
||||
className={cn(
|
||||
"mt-1.5 text-[10px] font-bold uppercase",
|
||||
meta.text,
|
||||
)}
|
||||
>
|
||||
{meta.label}
|
||||
</p>
|
||||
</div>
|
||||
@@ -411,7 +430,9 @@ function Squadra() {
|
||||
const meta = gradoMeta[grado];
|
||||
const quanti = rosa.filter((g) => {
|
||||
const raggiunto = gradoRaggiunto(b, b.valore(g));
|
||||
return raggiunto ? gradiOrdine.indexOf(raggiunto) >= gradiOrdine.indexOf(grado) : false;
|
||||
return raggiunto
|
||||
? gradiOrdine.indexOf(raggiunto) >= gradiOrdine.indexOf(grado)
|
||||
: false;
|
||||
}).length;
|
||||
return (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user