Rimuove la serie «Conferme 24h» e i badge collegati
Toglie la serie dal profilo, dalla Home e dalle notifiche di traguardo, insieme ai badge «Risposta lampo» e «Mai un forfait» e al calcolo di serieConferme. La colonna risposto_il e il suo trigger restano nel database, inutilizzati. Test e documentazione allineati. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8d0a8c7971
commit
bfb768fb5a
17 files changed
+69
-718
No files matched your search
@@ -3,9 +3,7 @@ import {
|
||||
Repeat,
|
||||
Lock,
|
||||
Ghost,
|
||||
Zap,
|
||||
Rocket,
|
||||
Anchor,
|
||||
Stethoscope,
|
||||
AlarmClock,
|
||||
ClipboardCheck,
|
||||
@@ -114,15 +112,6 @@ export const badgeDefs: BadgeDef[] = [
|
||||
soglie: { bronzo: 3, argento: 6, oro: 10 },
|
||||
valore: (g) => g.serieAllenamenti,
|
||||
},
|
||||
{
|
||||
id: "serie-conferme",
|
||||
nome: "Risposta lampo",
|
||||
descrizione: "Conferme rapide agli eventi: la squadra sa subito che ci sei.",
|
||||
unita: "conferme entro 24h",
|
||||
icon: Zap,
|
||||
soglie: { bronzo: 3, argento: 8, oro: 15 },
|
||||
valore: (g) => g.serieConferme,
|
||||
},
|
||||
];
|
||||
|
||||
/** Badge segreti: non compaiono nella UI finché non vengono sbloccati. */
|
||||
@@ -141,18 +130,6 @@ export const badgeSegreti: BadgeDef[] = [
|
||||
valore: (g) => (g.mvp >= 2 && g.votiPagella >= VOTI_MINIMI_PAGELLA && g.mediaVoto >= 8 ? 1 : 0),
|
||||
celebrazione: "Nei momenti caldi ci sei sempre.",
|
||||
},
|
||||
{
|
||||
id: "s-mai-forfait",
|
||||
nome: "Mai un forfait",
|
||||
descrizione:
|
||||
"Sbloccato con 10 conferme rapide consecutive e 15 presenze: su di te la squadra può contare a occhi chiusi.",
|
||||
unita: "requisito nascosto",
|
||||
icon: Anchor,
|
||||
segreto: true,
|
||||
soglie: { bronzo: 1, argento: 1, oro: 1 },
|
||||
valore: (g) => (g.serieConferme >= 10 && g.presenze >= 15 ? 1 : 0),
|
||||
celebrazione: "Su di te la squadra può contare a occhi chiusi.",
|
||||
},
|
||||
{
|
||||
id: "s-infermeria",
|
||||
nome: "Cliente VIP dell'Infermeria",
|
||||
|
||||
@@ -34,7 +34,6 @@ export type Giocatore = {
|
||||
/** Serie consecutive per tipo: si azzerano in modo indipendente. */
|
||||
serieAllenamenti: number;
|
||||
seriePartite: number;
|
||||
serieConferme: number;
|
||||
/** MVP eletti dalla squadra. */
|
||||
mvp: number;
|
||||
/** Media delle pagelle ricevute dai compagni (1-10). */
|
||||
@@ -109,7 +108,6 @@ export const giocatori: Giocatore[] = rosaCSI
|
||||
streak: 0,
|
||||
serieAllenamenti: 0,
|
||||
seriePartite: 0,
|
||||
serieConferme: 0,
|
||||
mvp: 0,
|
||||
mediaVoto: 0,
|
||||
votiPagella: 0,
|
||||
|
||||
+1
-26
@@ -155,31 +155,6 @@ export function serieConsecutiva(
|
||||
);
|
||||
}
|
||||
|
||||
const ORE_24 = 24 * 60 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* Serie di conferme rapide: risposte arrivate entro 24 ore dalla convocazione
|
||||
* (`creatoIl` dell'evento). Gli eventi senza istante di creazione — quelli generati
|
||||
* dal client, non salvati a database — non spezzano la serie: vengono saltati.
|
||||
*/
|
||||
export function serieConferme(
|
||||
giocatoreId: string,
|
||||
eventi: Evento[],
|
||||
tempi: MappaTempiRisposta,
|
||||
oggi: string = dataOggi(),
|
||||
): number {
|
||||
return serieSu(
|
||||
giocatoreId,
|
||||
eventi.filter((e) => e.creatoIl),
|
||||
oggi,
|
||||
undefined,
|
||||
(e) => {
|
||||
const risposto = tempi[e.id]?.[giocatoreId];
|
||||
return risposto !== undefined && Date.parse(risposto) - Date.parse(e.creatoIl!) <= ORE_24;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** Scorre gli eventi già passati in ordine di data applicando la regola delle serie. */
|
||||
function serieSu(
|
||||
giocatoreId: string,
|
||||
@@ -228,7 +203,7 @@ export function usePresenzeEvento(eventoId: string) {
|
||||
*
|
||||
* - l'istante si scrive **solo se manca** (`??=`), come fa il database, dove `risposto_il`
|
||||
* non viene inviato sull'upsert e un trigger lo congela: è la prima risposta, non l'ultima,
|
||||
* e un ripensamento non deve far ripartire il cronometro della serie "Conferme 24h";
|
||||
* e un ripensamento non deve cambiare l'istante della prima risposta;
|
||||
* - cancellare la risposta (`stato: null`) elimina **anche** l'istante, così se il giocatore
|
||||
* risponde di nuovo il cronometro riparte davvero — ha ritirato la risposta.
|
||||
*/
|
||||
|
||||
+2
-15
@@ -12,7 +12,6 @@ import { useEventi } from "./eventi";
|
||||
import {
|
||||
contaPartiteGiocate,
|
||||
contaPresenzeGiocatore,
|
||||
serieConferme,
|
||||
serieConsecutiva,
|
||||
totaliEventiGiocatore,
|
||||
useRispostePresenze,
|
||||
@@ -68,7 +67,7 @@ export function useRosa(): Giocatore[] {
|
||||
const { salvati: turniSalvati } = useTurniPalloni();
|
||||
const { infortuni, ritardi } = useInfortuniERitardi();
|
||||
const { eventi } = useEventi();
|
||||
const { presenze: mappaPresenze, tempi } = useRispostePresenze();
|
||||
const { presenze: mappaPresenze } = useRispostePresenze();
|
||||
|
||||
const votiMvp = voti.data;
|
||||
|
||||
@@ -94,7 +93,6 @@ export function useRosa(): Giocatore[] {
|
||||
streak: serieConsecutiva(g.id, eventi, mappaPresenze),
|
||||
serieAllenamenti: serieConsecutiva(g.id, eventi, mappaPresenze, "allenamento"),
|
||||
seriePartite: serieConsecutiva(g.id, eventi, mappaPresenze, "partita"),
|
||||
serieConferme: serieConferme(g.id, eventi, tempi),
|
||||
mvp: mvpVinti[g.id] ?? 0,
|
||||
mediaVoto: medie[g.id]?.media ?? 0,
|
||||
votiPagella: medie[g.id]?.voti ?? 0,
|
||||
@@ -105,18 +103,7 @@ export function useRosa(): Giocatore[] {
|
||||
infortuni: infortuni[g.id] ?? 0,
|
||||
ritardi: ritardi[g.id] ?? 0,
|
||||
}));
|
||||
}, [
|
||||
squadra,
|
||||
votiMvp,
|
||||
pagelle,
|
||||
cacche,
|
||||
turniSalvati,
|
||||
infortuni,
|
||||
ritardi,
|
||||
eventi,
|
||||
mappaPresenze,
|
||||
tempi,
|
||||
]);
|
||||
}, [squadra, votiMvp, pagelle, cacche, turniSalvati, infortuni, ritardi, eventi, mappaPresenze]);
|
||||
}
|
||||
|
||||
/** Criteri di ordinamento della classifica interna di Squadra. */
|
||||
|
||||
+2
-10
@@ -1,8 +1,8 @@
|
||||
import { Dumbbell, Swords, Zap } from "lucide-react";
|
||||
import { Dumbbell, Swords } from "lucide-react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import type { Giocatore } from "./crapp-data";
|
||||
|
||||
export type SerieTipo = "allenamenti" | "partite" | "conferme";
|
||||
export type SerieTipo = "allenamenti" | "partite";
|
||||
|
||||
export type SerieDef = {
|
||||
tipo: SerieTipo;
|
||||
@@ -31,14 +31,6 @@ export const serieDefs: SerieDef[] = [
|
||||
traguardi: [2, 5, 8, 12],
|
||||
valore: (g) => g.seriePartite,
|
||||
},
|
||||
{
|
||||
tipo: "conferme",
|
||||
label: "Conferme 24h",
|
||||
descrizione: "Risposte date entro 24 ore dalla convocazione",
|
||||
icon: Zap,
|
||||
traguardi: [3, 8, 15, 20],
|
||||
valore: (g) => g.serieConferme,
|
||||
},
|
||||
];
|
||||
|
||||
export type SerieStato = {
|
||||
|
||||
Reference in new issue
Block a user