Scout live: selezione giocatore ordinabile e conteggio dei + nel riquadro
Il titolo diventa «Selezione giocatore», con un selettore (componente Select dell'app) per ordinare per cognome o per numero. Nel riquadro di ogni giocatore, al posto dei punti delle azioni (sempre 0), compaiono i + del set in corso senza la ricezione. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
44194d6d54
commit
5fd7c895b3
3 files changed
+64
-9
No files matched your search
@@ -96,6 +96,24 @@ export function contaValutazioni(
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I + di un giocatore in un set, esclusa la ricezione (che qui non vale come punto messo a
|
||||||
|
* terra): quello che compare nel suo riquadro dello scout.
|
||||||
|
*/
|
||||||
|
export function contaPiuSenzaRicezione(
|
||||||
|
valutazioni: Valutazione[],
|
||||||
|
giocatoreId: string,
|
||||||
|
set: number,
|
||||||
|
): number {
|
||||||
|
return valutazioni.filter(
|
||||||
|
(v) =>
|
||||||
|
v.giocatoreId === giocatoreId &&
|
||||||
|
v.set === set &&
|
||||||
|
v.segno === "+" &&
|
||||||
|
v.fondamentale !== "ricezione",
|
||||||
|
).length;
|
||||||
|
}
|
||||||
|
|
||||||
export type ScoutMatch = {
|
export type ScoutMatch = {
|
||||||
id: string;
|
id: string;
|
||||||
data: string;
|
data: string;
|
||||||
|
|||||||
+27
-9
@@ -3,6 +3,7 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router";
|
|||||||
import { Undo2, Save, CheckCircle2, Radio, Lock, CalendarX2, LogOut } from "lucide-react";
|
import { Undo2, Save, CheckCircle2, Radio, Lock, CalendarX2, LogOut } from "lucide-react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import { Select } from "@/components/crapp/ui-bits";
|
||||||
import { formatData } from "@/lib/crapp-data";
|
import { formatData } from "@/lib/crapp-data";
|
||||||
import type { Evento } from "@/lib/eventi";
|
import type { Evento } from "@/lib/eventi";
|
||||||
import { useAnagraficaRosa } from "@/lib/rosa";
|
import { useAnagraficaRosa } from "@/lib/rosa";
|
||||||
@@ -26,10 +27,10 @@ import {
|
|||||||
} from "@/lib/scout-live";
|
} from "@/lib/scout-live";
|
||||||
import {
|
import {
|
||||||
azioniMeta,
|
azioniMeta,
|
||||||
|
contaPiuSenzaRicezione,
|
||||||
contaValutazioni,
|
contaValutazioni,
|
||||||
fondamentali,
|
fondamentali,
|
||||||
useSalvaScoutMatch,
|
useSalvaScoutMatch,
|
||||||
totaliPerGiocatore,
|
|
||||||
type Azione,
|
type Azione,
|
||||||
type AzioneTipo,
|
type AzioneTipo,
|
||||||
type Fondamentale,
|
type Fondamentale,
|
||||||
@@ -202,6 +203,7 @@ function ScoutBoard({
|
|||||||
const [setChiusi, setSetChiusi] = useState<Array<[number, number]>>(base.setChiusi);
|
const [setChiusi, setSetChiusi] = useState<Array<[number, number]>>(base.setChiusi);
|
||||||
const [azioni, setAzioni] = useState<Azione[]>(base.azioni);
|
const [azioni, setAzioni] = useState<Azione[]>(base.azioni);
|
||||||
const [valutazioni, setValutazioni] = useState<Valutazione[]>(base.valutazioni ?? []);
|
const [valutazioni, setValutazioni] = useState<Valutazione[]>(base.valutazioni ?? []);
|
||||||
|
const [ordine, setOrdine] = useState<"cognome" | "numero">("cognome");
|
||||||
const [selezionato, setSelezionato] = useState<string | null>(null);
|
const [selezionato, setSelezionato] = useState<string | null>(null);
|
||||||
const salva = useSalvaStatoScout();
|
const salva = useSalvaStatoScout();
|
||||||
const cancella = useCancellaStatoScout();
|
const cancella = useCancellaStatoScout();
|
||||||
@@ -216,8 +218,13 @@ function ScoutBoard({
|
|||||||
const presenti = rosa.filter(
|
const presenti = rosa.filter(
|
||||||
(g) => risposte[g.id] === "presente" || risposte[g.id] === "ritardo",
|
(g) => risposte[g.id] === "presente" || risposte[g.id] === "ritardo",
|
||||||
);
|
);
|
||||||
return presenti.length > 0 ? presenti : rosa;
|
const elenco = presenti.length > 0 ? presenti : rosa;
|
||||||
}, [risposte, rosa]);
|
return [...elenco].sort((a, b) =>
|
||||||
|
ordine === "numero"
|
||||||
|
? a.numero - b.numero
|
||||||
|
: a.cognome.localeCompare(b.cognome, "it") || a.numero - b.numero,
|
||||||
|
);
|
||||||
|
}, [risposte, rosa, ordine]);
|
||||||
|
|
||||||
// Salvataggio condiviso: se chi scouta si disconnette, il prossimo riprende da qui.
|
// Salvataggio condiviso: se chi scouta si disconnette, il prossimo riprende da qui.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -236,7 +243,6 @@ function ScoutBoard({
|
|||||||
const azioniSet = azioni.filter((a) => a.set === setCorrente);
|
const azioniSet = azioni.filter((a) => a.set === setCorrente);
|
||||||
const puntiNoi = azioniSet.filter((a) => azioniMeta[a.tipo].nostro).length;
|
const puntiNoi = azioniSet.filter((a) => azioniMeta[a.tipo].nostro).length;
|
||||||
const puntiLoro = azioniSet.length - puntiNoi;
|
const puntiLoro = azioniSet.length - puntiNoi;
|
||||||
const totali = useMemo(() => totaliPerGiocatore(azioni), [azioni]);
|
|
||||||
|
|
||||||
function valuta(fondamentale: Fondamentale, segno: Valutazione["segno"]) {
|
function valuta(fondamentale: Fondamentale, segno: Valutazione["segno"]) {
|
||||||
if (!selezionato) {
|
if (!selezionato) {
|
||||||
@@ -351,13 +357,25 @@ function ScoutBoard({
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section className="px-5 pt-4">
|
<section className="px-5 pt-4">
|
||||||
<p className="mb-2 text-[13px] font-bold uppercase tracking-wide text-muted-foreground">
|
<div className="mb-2 flex items-center justify-between gap-2">
|
||||||
1. Tocca il giocatore
|
<p className="text-[13px] font-bold uppercase tracking-wide text-muted-foreground">
|
||||||
</p>
|
Selezione giocatore
|
||||||
|
</p>
|
||||||
|
<div className="w-40 shrink-0">
|
||||||
|
<Select
|
||||||
|
value={ordine}
|
||||||
|
onChange={(e) => setOrdine(e.target.value as "cognome" | "numero")}
|
||||||
|
aria-label="Ordina i giocatori"
|
||||||
|
>
|
||||||
|
<option value="cognome">Per cognome</option>
|
||||||
|
<option value="numero">Per numero</option>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="grid grid-cols-4 gap-2">
|
<div className="grid grid-cols-4 gap-2">
|
||||||
{convocati.map((g) => {
|
{convocati.map((g) => {
|
||||||
const attivo = selezionato === g.id;
|
const attivo = selezionato === g.id;
|
||||||
const t = totali.get(g.id);
|
const piu = contaPiuSenzaRicezione(valutazioni, g.id, setCorrente);
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
key={g.id}
|
key={g.id}
|
||||||
@@ -376,7 +394,7 @@ function ScoutBoard({
|
|||||||
attivo ? "text-accent-foreground/70" : "text-muted-foreground",
|
attivo ? "text-accent-foreground/70" : "text-muted-foreground",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{t ? `${t.punti}p` : "0p"}
|
+{piu}
|
||||||
</p>
|
</p>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import assert from "node:assert/strict";
|
|||||||
import { giocatori } from "@/lib/crapp-data";
|
import { giocatori } from "@/lib/crapp-data";
|
||||||
import {
|
import {
|
||||||
azioniMeta,
|
azioniMeta,
|
||||||
|
contaPiuSenzaRicezione,
|
||||||
contaValutazioni,
|
contaValutazioni,
|
||||||
fondamentali,
|
fondamentali,
|
||||||
giocatoriConScout,
|
giocatoriConScout,
|
||||||
@@ -139,3 +140,21 @@ assert.deepEqual(
|
|||||||
"giocatore senza valutazioni",
|
"giocatore senza valutazioni",
|
||||||
);
|
);
|
||||||
assert.equal(totaliPerGiocatore([]).size, 0, "le valutazioni non sono azioni: nessun punto");
|
assert.equal(totaliPerGiocatore([]).size, 0, "le valutazioni non sono azioni: nessun punto");
|
||||||
|
|
||||||
|
// --- + del riquadro giocatore: tutti i fondamentali tranne la ricezione, nel set -------
|
||||||
|
const piuVal = [
|
||||||
|
v("g1", "battuta", "+"),
|
||||||
|
v("g1", "attacco", "+"),
|
||||||
|
v("g1", "muro", "+"),
|
||||||
|
v("g1", "ricezione", "+"),
|
||||||
|
v("g1", "attacco", "-"),
|
||||||
|
v("g1", "battuta", "+", 2),
|
||||||
|
v("g2", "attacco", "+"),
|
||||||
|
];
|
||||||
|
assert.equal(
|
||||||
|
contaPiuSenzaRicezione(piuVal, "g1", 1),
|
||||||
|
3,
|
||||||
|
"niente ricezione, niente −, solo il set 1",
|
||||||
|
);
|
||||||
|
assert.equal(contaPiuSenzaRicezione(piuVal, "g1", 2), 1);
|
||||||
|
assert.equal(contaPiuSenzaRicezione(piuVal, "g3", 1), 0);
|
||||||
Reference in new issue
Block a user