Aggiunge il dettaglio esteso di partita: formazioni e scontri diretti dal CSI

In Campionato > Storico partite ogni gara diventa cliccabile: verso /partita/$id
se collegata a un evento CrAPP, verso la nuova /partita-csi/$id altrimenti (nessuna
creazione automatica di eventi dal calendario CSI, quindi molte gare ne sono prive).

Il dettaglio aggiunge formazioni (titolari/panchina/staff), storico scontri diretti
e probabilità di vittoria calcolata dal CSI, letti on-demand da tre nuovi endpoint
per-partita (match-main/players/stats.php) dietro /api/public/csi-partita/$id, con
cache server per-partita separata da quella di /api/public/csi — è un dato aperto a
richiesta, non precaricato per tutti come classifica e partite.

Include anche logo squadra e metadati leggeri (girone, n° gara, arbitro, link al
referto ufficiale) già presenti nel JSON esistente, a costo zero.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 12:07:03 +02:00
co-authored by Claude Sonnet 5
parent c628997934
commit 5569d08b59
12 changed files with 1207 additions and 38 deletions
+25
View File
@@ -7,6 +7,7 @@ import { convocatiEvento, useEvento } from "@/lib/eventi";
import { useRosa } from "@/lib/rosa";
import { useCsi } from "@/lib/csi";
import { matchDaPartitaCsi, partiteGiocate } from "@/lib/csi-core";
import { DettaglioCsiEsteso, LogoSquadra, MetaPartitaCsi } from "@/components/crapp/DettaglioCsi";
import { Pagelle } from "@/components/crapp/Pagelle";
import { SondaggioCacche } from "@/components/crapp/SondaggioCacche";
import { ScoutEntry } from "@/components/crapp/ScoutEntry";
@@ -72,10 +73,16 @@ function PartitaDetail() {
id: scout.id,
data: scout.data,
avversario: scout.avversario,
logoAvversario: "",
casa: scout.casa,
setNostri: scout.setNostri,
setLoro: scout.setLoro,
parziali: scout.parziali,
campo: "",
girone: "",
numeroGara: "",
arbitro: "",
link: "",
}
: csiMatch
? matchDaPartitaCsi(csiMatch)
@@ -105,6 +112,9 @@ function PartitaDetail() {
>
{casa ? <Swords className="h-6 w-6" /> : <Trophy className="h-6 w-6" />}
</div>
{match?.logoAvversario ? (
<LogoSquadra src={match.logoAvversario} alt={avversario} className="h-10 w-10" />
) : null}
<div className="min-w-0 flex-1">
<p className="text-xs font-bold uppercase tracking-wide text-muted-foreground">
{casa ? "In casa" : "Fuori casa"}
@@ -134,6 +144,15 @@ function PartitaDetail() {
Conferme: {presentiVeri}/{convocati.length}
</div>
{csiMatch ? (
<MetaPartitaCsi
girone={csiMatch.girone}
numeroGara={csiMatch.numeroGara}
arbitro={csiMatch.arbitro}
link={csiMatch.link}
/>
) : null}
<TurnoPalloni eventoId={evento.id} />
</div>
</Section>
@@ -171,6 +190,12 @@ function PartitaDetail() {
</Section>
) : null}
{csiMatch ? (
<Section titolo="Formazioni e scontri diretti">
<DettaglioCsiEsteso matchId={csiMatch.id} avversario={avversario} />
</Section>
) : null}
<Section titolo="MVP eletto dalla squadra">
<div className="rounded-3xl bg-card p-5 shadow-card">
<VotazioneMvp evento={evento} />