Rimuove i dati dummy della classifica e usa i risultati CSI reali

La classifica e lo storico partite mostravano dati inventati (squadre e
risultati finti) come base, poi sovrascritti dai dati CSI quando
disponibili. Ora classifica, ultimi risultati, storico match e obiettivi
di squadra legati alle vittorie usano solo dati reali (CSI o scout live),
con stati vuoti quando i dati CSI non sono ancora disponibili.

Include anche la correzione di tutti gli errori di formattazione
prettier segnalati da `npm run lint` sul resto del codice sorgente.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-01 13:38:33 +02:00
co-authored by Claude Sonnet 5
parent d813dee282
commit 0a04025fe9
55 changed files with 1038 additions and 879 deletions
+14 -10
View File
@@ -14,13 +14,7 @@ import {
DrawerTrigger,
} from "@/components/ui/drawer";
function DettaglioBadge({
def,
stato,
}: {
def: BadgeDef;
stato?: BadgeStato;
}) {
function DettaglioBadge({ def, stato }: { def: BadgeDef; stato?: BadgeStato }) {
const Icon = def.icon;
const grado = stato?.grado ?? null;
const meta = grado ? gradoMeta[grado] : null;
@@ -94,10 +88,20 @@ function DettaglioBadge({
raggiunto ? `${gm.bg} ${gm.ring}` : "bg-secondary ring-border",
)}
>
<p className={cn("text-[10px] font-bold uppercase", raggiunto ? gm.text : "text-muted-foreground")}>
<p
className={cn(
"text-[10px] font-bold uppercase",
raggiunto ? gm.text : "text-muted-foreground",
)}
>
{gm.label}
</p>
<p className={cn("font-display text-xl leading-none", raggiunto ? "text-foreground" : "text-muted-foreground")}>
<p
className={cn(
"font-display text-xl leading-none",
raggiunto ? "text-foreground" : "text-muted-foreground",
)}
>
{def.soglie[g]}
</p>
<p className="text-[10px] text-muted-foreground">{def.unita}</p>
@@ -130,7 +134,7 @@ export function BadgeDrawer({
return (
<Drawer open={open} onOpenChange={setOpen}>
<DrawerTrigger asChild>{children}</DrawerTrigger>
<DrawerContent>
<DrawerContent>
<DrawerHeader className="sr-only">
<DrawerTitle>{def.nome}</DrawerTitle>
<DrawerDescription>{def.descrizione}</DrawerDescription>
+1 -1
View File
@@ -27,4 +27,4 @@ export function BottomNav() {
</div>
</nav>
);
}
}
+1 -1
View File
@@ -76,4 +76,4 @@ export function CelebrazioneBadge() {
</div>
</div>
);
}
}
+10 -3
View File
@@ -10,7 +10,12 @@ import {
prossimoTraguardo,
type BadgeStato,
} from "@/lib/badges";
import { badgeSocialVinti, categorieSocial, type VotoSocial, type CategoriaSocial } from "@/lib/badge-social";
import {
badgeSocialVinti,
categorieSocial,
type VotoSocial,
type CategoriaSocial,
} from "@/lib/badge-social";
import { Reveal } from "@/components/motion/Reveal";
import { Barra } from "@/components/motion/Barra";
import { Numero } from "@/components/motion/Numero";
@@ -91,7 +96,9 @@ function SocialDrawer({
</div>
</div>
<div className="rounded-2xl bg-card p-4 shadow-card ring-1 ring-border">
<p className="text-[11px] font-bold uppercase tracking-wide text-muted-foreground">Vinto</p>
<p className="text-[11px] font-bold uppercase tracking-wide text-muted-foreground">
Vinto
</p>
<p className="mt-1 font-display text-3xl leading-none">
{conteggio}{" "}
<span className="text-lg text-muted-foreground">
@@ -246,4 +253,4 @@ export function CollezioneBadge({
</div>
</div>
);
}
}
+29 -27
View File
@@ -118,33 +118,35 @@ export function EventoCard({
<Barra percentuale={perc} altezza="h-1.5" trackClassName="mt-3" />
{io ? (
<div className="mt-4 flex flex-wrap gap-1.5">
{stati.map((s) => {
const meta = statoMeta[s];
const attivo = stato === s;
return (
<button
key={s}
type="button"
disabled={salva.isPending}
onClick={() =>
salva.mutate({
eventoId: evento.id,
giocatoreId: io.id,
stato: attivo ? null : s,
})
}
className={cn(
"rounded-full border border-border px-2.5 py-1.5 text-[11px] font-semibold transition-all active:scale-95",
attivo ? cn(meta.className, "border-transparent shadow-card") : "bg-background text-muted-foreground",
)}
>
{meta.label}
</button>
);
})}
</div>
<div className="mt-4 flex flex-wrap gap-1.5">
{stati.map((s) => {
const meta = statoMeta[s];
const attivo = stato === s;
return (
<button
key={s}
type="button"
disabled={salva.isPending}
onClick={() =>
salva.mutate({
eventoId: evento.id,
giocatoreId: io.id,
stato: attivo ? null : s,
})
}
className={cn(
"rounded-full border border-border px-2.5 py-1.5 text-[11px] font-semibold transition-all active:scale-95",
attivo
? cn(meta.className, "border-transparent shadow-card")
: "bg-background text-muted-foreground",
)}
>
{meta.label}
</button>
);
})}
</div>
) : null}
</article>
);
}
}
+3 -1
View File
@@ -104,7 +104,9 @@ export function Pagelle({
onClick={() => invia(g.id, v)}
className={cn(
"rounded-lg py-1.5 text-[11px] font-bold tabular-nums transition-transform active:scale-90",
mio === v ? "bg-accent text-accent-foreground" : "bg-card text-foreground",
mio === v
? "bg-accent text-accent-foreground"
: "bg-card text-foreground",
)}
>
{v}
+2 -7
View File
@@ -1,11 +1,6 @@
import { AlertCircle } from "lucide-react";
import { formatData } from "@/lib/crapp-data";
import {
eventiPalloni,
eventoPrecedente,
eventoSuccessivo,
oggiISO,
} from "@/lib/palloni-core";
import { eventiPalloni, eventoPrecedente, eventoSuccessivo, oggiISO } from "@/lib/palloni-core";
import { useTurniPalloni } from "@/lib/palloni";
import { useEventi } from "@/lib/eventi";
import { useGiocatoreCorrente } from "@/lib/user-store";
@@ -59,4 +54,4 @@ export function PromemoriaPalloni() {
))}
</div>
);
}
}
+2 -1
View File
@@ -21,7 +21,8 @@ export function RosaPresenze({ eventoId }: { eventoId: string }) {
const mancanti = giocatori.filter((g) => !risposte[g.id]);
const risposteN = giocatori.length - mancanti.length;
const perc = Math.round((risposteN / giocatori.length) * 100);
const daSollecitare = mancanti.length + giocatori.filter((g) => risposte[g.id] === "forse").length;
const daSollecitare =
mancanti.length + giocatori.filter((g) => risposte[g.id] === "forse").length;
async function sollecita() {
setSollecito(true);
+14 -6
View File
@@ -19,12 +19,20 @@ export function ScoutEntry({ variante = "grande" }: { variante?: "grande" | "com
const occupato = !!attiva && attiva.giocatore_id !== io?.id;
const disponibile = abilitato && pronto && !!partita && !occupato;
const titolo = !abilitato ? "Scout live" : !partita ? "Scout live non attivo" : occupato ? "Scout occupato" : "Scout live";
const sottotitolo = !abilitato ? "Riservato ad allenatori e referenti" : !partita
? "Si attiva il giorno della partita"
: occupato
? `In uso da ${attiva!.giocatore_nome}`
: "Segna punti, ace e muri in tempo reale";
const titolo = !abilitato
? "Scout live"
: !partita
? "Scout live non attivo"
: occupato
? "Scout occupato"
: "Scout live";
const sottotitolo = !abilitato
? "Riservato ad allenatori e referenti"
: !partita
? "Si attiva il giorno della partita"
: occupato
? `In uso da ${attiva!.giocatore_nome}`
: "Segna punti, ace e muri in tempo reale";
const contenuto = (
<>
+7 -3
View File
@@ -19,7 +19,9 @@ export function SerieGriglia({ g }: { g: Giocatore }) {
<span
className={cn(
"grid h-10 w-10 shrink-0 place-items-center rounded-2xl",
attiva ? "bg-accent-grad text-accent-foreground" : "bg-secondary text-muted-foreground",
attiva
? "bg-accent-grad text-accent-foreground"
: "bg-secondary text-muted-foreground",
)}
>
<Icon className="h-5 w-5" />
@@ -29,7 +31,9 @@ export function SerieGriglia({ g }: { g: Giocatore }) {
<p className="text-[11px] text-muted-foreground">{s.def.descrizione}</p>
</div>
<span className="inline-flex items-center gap-1 font-display text-2xl leading-none">
<Flame className={cn("h-4 w-4", attiva ? "text-accent" : "text-muted-foreground/40")} />
<Flame
className={cn("h-4 w-4", attiva ? "text-accent" : "text-muted-foreground/40")}
/>
{s.valore}
</span>
</div>
@@ -74,4 +78,4 @@ export function SerieHome({ g }: { g: Giocatore }) {
</div>
</div>
);
}
}
+4 -1
View File
@@ -68,7 +68,10 @@ export function SondaggioCacche({ eventoId }: { eventoId: string }) {
Media squadra {media}
</span>
{classifica.map((r, i) => (
<span key={r.giocatore_id} className="rounded-full bg-secondary px-2.5 py-1 font-semibold">
<span
key={r.giocatore_id}
className="rounded-full bg-secondary px-2.5 py-1 font-semibold"
>
{i === 0 ? "🥇" : i === 1 ? "🥈" : "🥉"} {r.nome} · {r.quantita}
</span>
))}
+1 -1
View File
@@ -78,4 +78,4 @@ export function TurnoPalloni({ eventoId }: { eventoId: string }) {
) : null}
</div>
);
}
}
+1 -1
View File
@@ -97,4 +97,4 @@ export function VotazioneMvp({ matchId }: { matchId: string }) {
) : null}
</div>
);
}
}
+2 -3
View File
@@ -122,8 +122,7 @@ export function VotoSocial({ matchId }: { matchId: string }) {
<p className="inline-flex items-center gap-1.5 text-xs font-bold">
<Crown className="h-3.5 w-3.5 text-oro" />
<Icon className="h-3.5 w-3.5 text-accent" />
{vincitore.nome} · {vincitore.voti}{" "}
{vincitore.voti === 1 ? "voto" : "voti"}
{vincitore.nome} · {vincitore.voti} {vincitore.voti === 1 ? "voto" : "voti"}
</p>
) : (
<p className="text-[11px] text-muted-foreground">
@@ -137,4 +136,4 @@ export function VotoSocial({ matchId }: { matchId: string }) {
})}
</div>
);
}
}
+2 -2
View File
@@ -62,7 +62,7 @@ export function StatoBadge({ stato, className }: { stato: Stato; className?: str
className,
)}
>
{meta.label}
{meta.label}
</span>
);
}
@@ -87,4 +87,4 @@ export function StatTile({
{hint ? <p className="mt-0.5 text-[11px] text-accent">{hint}</p> : null}
</div>
);
}
}
+1 -1
View File
@@ -22,4 +22,4 @@ export function Barra({
/>
</div>
);
}
}
+1 -1
View File
@@ -17,4 +17,4 @@ export function Numero({
{suffisso}
</span>
);
}
}
+1 -1
View File
@@ -26,4 +26,4 @@ export function Reveal({
{children}
</Tag>
);
}
}