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:
@@ -139,8 +139,7 @@ export function mioVotoSocial(
|
||||
) {
|
||||
return (
|
||||
voti.find(
|
||||
(v) =>
|
||||
v.match_id === matchId && v.categoria === categoria && v.votante_id === votanteId,
|
||||
(v) => v.match_id === matchId && v.categoria === categoria && v.votante_id === votanteId,
|
||||
) ?? null
|
||||
);
|
||||
}
|
||||
@@ -156,4 +155,4 @@ export function badgeSocialVinti(voti: VotoSocial[], giocatoreId: string) {
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-11
@@ -19,10 +19,7 @@ export type Grado = "bronzo" | "argento" | "oro";
|
||||
|
||||
export const gradiOrdine: Grado[] = ["bronzo", "argento", "oro"];
|
||||
|
||||
export const gradoMeta: Record<
|
||||
Grado,
|
||||
{ label: string; text: string; bg: string; ring: string }
|
||||
> = {
|
||||
export const gradoMeta: Record<Grado, { label: string; text: string; bg: string; ring: string }> = {
|
||||
bronzo: { label: "Bronzo", text: "text-bronzo", bg: "bg-bronzo/15", ring: "ring-bronzo/40" },
|
||||
argento: { label: "Argento", text: "text-argento", bg: "bg-argento/20", ring: "ring-argento/50" },
|
||||
oro: { label: "Oro", text: "text-oro", bg: "bg-oro/20", ring: "ring-oro/50" },
|
||||
@@ -50,7 +47,8 @@ export const badgeDefs: BadgeDef[] = [
|
||||
{
|
||||
id: "mvp",
|
||||
nome: "MVP",
|
||||
descrizione: "Riconoscimento per il miglior giocatore della partita, scelto dai compagni a fine match.",
|
||||
descrizione:
|
||||
"Riconoscimento per il miglior giocatore della partita, scelto dai compagni a fine match.",
|
||||
unita: "MVP",
|
||||
icon: Trophy,
|
||||
soglie: { bronzo: 1, argento: 3, oro: 5 },
|
||||
@@ -59,7 +57,8 @@ export const badgeDefs: BadgeDef[] = [
|
||||
{
|
||||
id: "pagella",
|
||||
nome: "Pagellone",
|
||||
descrizione: "Media dei voti che i compagni ti danno a fine partita: conta come giochi, non quanti punti fai.",
|
||||
descrizione:
|
||||
"Media dei voti che i compagni ti danno a fine partita: conta come giochi, non quanti punti fai.",
|
||||
unita: "di media voto",
|
||||
icon: ClipboardCheck,
|
||||
soglie: { bronzo: 6.5, argento: 7.5, oro: 8.5 },
|
||||
@@ -68,7 +67,8 @@ export const badgeDefs: BadgeDef[] = [
|
||||
{
|
||||
id: "palloni",
|
||||
nome: "Sherpa dei palloni",
|
||||
descrizione: "Quante volte ti sei caricato la sacca dei palloni: lavoro oscuro, badge luminoso.",
|
||||
descrizione:
|
||||
"Quante volte ti sei caricato la sacca dei palloni: lavoro oscuro, badge luminoso.",
|
||||
unita: "turni palloni",
|
||||
icon: CircleDot,
|
||||
soglie: { bronzo: 3, argento: 6, oro: 10 },
|
||||
@@ -86,7 +86,8 @@ export const badgeDefs: BadgeDef[] = [
|
||||
{
|
||||
id: "serie-allenamenti",
|
||||
nome: "Sempre in palestra",
|
||||
descrizione: "Allenamenti consecutivi a cui sei stato presente: la costanza paga più del talento.",
|
||||
descrizione:
|
||||
"Allenamenti consecutivi a cui sei stato presente: la costanza paga più del talento.",
|
||||
unita: "allenamenti di fila",
|
||||
icon: Rocket,
|
||||
soglie: { bronzo: 3, argento: 6, oro: 10 },
|
||||
@@ -108,7 +109,8 @@ export const badgeSegreti: BadgeDef[] = [
|
||||
{
|
||||
id: "s-tiebreak",
|
||||
nome: "Uomo tie-break",
|
||||
descrizione: "Sbloccato da chi ha almeno 2 MVP e una media voto alta: nei momenti caldi ci sei sempre.",
|
||||
descrizione:
|
||||
"Sbloccato da chi ha almeno 2 MVP e una media voto alta: nei momenti caldi ci sei sempre.",
|
||||
unita: "MVP con media alta",
|
||||
icon: Ghost,
|
||||
segreto: true,
|
||||
@@ -119,7 +121,8 @@ export const badgeSegreti: BadgeDef[] = [
|
||||
{
|
||||
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.",
|
||||
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,
|
||||
@@ -268,4 +271,4 @@ export function badgeSbloccati(g: Giocatore): BadgeStato[] {
|
||||
|
||||
export function descrizioneSoglie(def: BadgeDef) {
|
||||
return `${def.soglie.bronzo}/${def.soglie.argento}/${def.soglie.oro} ${def.unita}`;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -63,7 +63,13 @@ function arrotonda(n: number) {
|
||||
export function statisticheCacche(righe: RigaCacche[]): Record<string, StatCacche> {
|
||||
const out: Record<string, StatCacche> = {};
|
||||
for (const r of righe) {
|
||||
const cur = out[r.giocatore_id] ?? { totale: 0, giornate: 0, media: 0, record: 0, giornateTop: 0 };
|
||||
const cur = out[r.giocatore_id] ?? {
|
||||
totale: 0,
|
||||
giornate: 0,
|
||||
media: 0,
|
||||
record: 0,
|
||||
giornateTop: 0,
|
||||
};
|
||||
cur.totale += r.quantita;
|
||||
cur.giornate += 1;
|
||||
cur.record = Math.max(cur.record, r.quantita);
|
||||
|
||||
+10
-30
@@ -2,10 +2,18 @@ export type Stato = "presente" | "assente" | "forse" | "ritardo" | "infortunato"
|
||||
|
||||
export const statoMeta: Record<Stato, { label: string; emoji: string; className: string }> = {
|
||||
presente: { label: "Presente", emoji: "✅", className: "bg-success text-success-foreground" },
|
||||
assente: { label: "Assente", emoji: "❌", className: "bg-destructive text-destructive-foreground" },
|
||||
assente: {
|
||||
label: "Assente",
|
||||
emoji: "❌",
|
||||
className: "bg-destructive text-destructive-foreground",
|
||||
},
|
||||
forse: { label: "Forse", emoji: "🤔", className: "bg-warning text-warning-foreground" },
|
||||
ritardo: { label: "In ritardo", emoji: "⏱️", className: "bg-info text-info-foreground" },
|
||||
infortunato: { label: "Infortunato", emoji: "🩹", className: "bg-primary text-primary-foreground" },
|
||||
infortunato: {
|
||||
label: "Infortunato",
|
||||
emoji: "🩹",
|
||||
className: "bg-primary text-primary-foreground",
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -125,24 +133,6 @@ export const giocatori: Giocatore[] = rosaCSI.map((r, i) => ({
|
||||
...serieDa(statsDemo[r.nome]),
|
||||
}));
|
||||
|
||||
export type Match = {
|
||||
id: string;
|
||||
data: string;
|
||||
avversario: string;
|
||||
casa: boolean;
|
||||
setNostri: number;
|
||||
setLoro: number;
|
||||
parziali: Array<[number, number]>;
|
||||
mvp: string;
|
||||
};
|
||||
|
||||
export const storicoMatch: Match[] = [
|
||||
{ id: "m1", data: "2026-07-25", avversario: "Pallavolo Sesto", casa: true, setNostri: 3, setLoro: 1, parziali: [[25, 19], [23, 25], [25, 21], [25, 18]], mvp: "Davide Grilli" },
|
||||
{ id: "m2", data: "2026-07-18", avversario: "ASD Rondinella", casa: false, setNostri: 2, setLoro: 3, parziali: [[25, 22], [19, 25], [25, 23], [20, 25], [12, 15]], mvp: "Ivan Cacciari" },
|
||||
{ id: "m3", data: "2026-07-11", avversario: "Virtus Cinisello", casa: true, setNostri: 3, setLoro: 0, parziali: [[25, 15], [25, 20], [25, 17]], mvp: "Laura Passabì" },
|
||||
{ id: "m4", data: "2026-07-04", avversario: "Nuova Bovisa", casa: false, setNostri: 3, setLoro: 2, parziali: [[21, 25], [25, 23], [18, 25], [25, 20], [15, 11]], mvp: "Nicola Pezzoli" },
|
||||
];
|
||||
|
||||
export type RigaClassifica = {
|
||||
pos: number;
|
||||
squadra: string;
|
||||
@@ -154,16 +144,6 @@ export type RigaClassifica = {
|
||||
punti: number;
|
||||
};
|
||||
|
||||
export const classifica: RigaClassifica[] = [
|
||||
{ pos: 1, squadra: "ASD Rondinella", giocate: 12, vinte: 10, perse: 2, setFatti: 33, setSubiti: 12, punti: 29 },
|
||||
{ pos: 2, squadra: "CRAP Volley", giocate: 12, vinte: 9, perse: 3, setFatti: 31, setSubiti: 16, punti: 26 },
|
||||
{ pos: 3, squadra: "Pallavolo Sesto", giocate: 12, vinte: 8, perse: 4, setFatti: 29, setSubiti: 19, punti: 24 },
|
||||
{ pos: 4, squadra: "Volley Bruzzano", giocate: 12, vinte: 7, perse: 5, setFatti: 26, setSubiti: 21, punti: 21 },
|
||||
{ pos: 5, squadra: "Aurora Nera", giocate: 12, vinte: 5, perse: 7, setFatti: 22, setSubiti: 25, punti: 16 },
|
||||
{ pos: 6, squadra: "Virtus Cinisello", giocate: 12, vinte: 3, perse: 9, setFatti: 15, setSubiti: 30, punti: 10 },
|
||||
{ pos: 7, squadra: "Nuova Bovisa", giocate: 12, vinte: 2, perse: 10, setFatti: 13, setSubiti: 32, punti: 7 },
|
||||
];
|
||||
|
||||
export function formatData(iso: string) {
|
||||
const d = new Date(iso + "T00:00:00");
|
||||
return d.toLocaleDateString("it-IT", { weekday: "short", day: "2-digit", month: "long" });
|
||||
|
||||
@@ -161,3 +161,16 @@ export function partiteDaEventi(eventi: unknown): PartitaCsi[] {
|
||||
export function partiteGiocate(partite: PartitaCsi[]): PartitaCsi[] {
|
||||
return partite.filter((p) => p.setNostri !== null && p.setLoro !== null);
|
||||
}
|
||||
|
||||
/** Converte una gara CSI già giocata nella forma comune usata nelle liste risultati. */
|
||||
export function matchDaPartitaCsi(p: PartitaCsi) {
|
||||
return {
|
||||
id: p.id,
|
||||
data: p.data,
|
||||
avversario: p.avversario,
|
||||
casa: p.casa,
|
||||
setNostri: p.setNostri ?? 0,
|
||||
setLoro: p.setLoro ?? 0,
|
||||
parziali: p.parziali,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -57,4 +57,4 @@ export function useInfortuniERitardi(): { infortuni: ContoInfortuni; ritardi: Co
|
||||
() => ({ infortuni: contaInfortuni(presenze), ritardi: contaRitardi(presenze) }),
|
||||
[presenze],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -90,4 +90,4 @@ export async function coriandoli(ridotto = false) {
|
||||
origin: { y: 0.7 },
|
||||
disableForReducedMotion: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -83,4 +83,4 @@ export function vincitoriMvp(voti: VotoMvp[]): Record<string, string> {
|
||||
|
||||
export function mioVoto(voti: VotoMvp[], matchId: string, votanteId: string) {
|
||||
return voti.find((v) => v.match_id === matchId && v.votante_id === votanteId) ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import type { Giocatore } from "./crapp-data";
|
||||
import {
|
||||
microcopyObiettivo,
|
||||
progressoObiettivo,
|
||||
type ObiettivoSquadra,
|
||||
} from "./obiettivi";
|
||||
import {
|
||||
badgeGiocatore,
|
||||
badgeSegretiSbloccati,
|
||||
gradoMeta,
|
||||
prossimoTraguardo,
|
||||
} from "./badges";
|
||||
import { microcopyObiettivo, progressoObiettivo, type ObiettivoSquadra } from "./obiettivi";
|
||||
import { badgeGiocatore, badgeSegretiSbloccati, gradoMeta, prossimoTraguardo } from "./badges";
|
||||
import { serieGiocatore } from "./serie";
|
||||
import { badgeSocialVinti, categorieSocial, type VotoSocial } from "./badge-social";
|
||||
|
||||
@@ -166,4 +157,4 @@ export function useNotificheSmart(g: Giocatore | null, votiSocial: VotoSocial[]
|
||||
const chiudi = useCallback(() => setCoda((c) => c.slice(1)), []);
|
||||
|
||||
return { notifica: coda[0] ?? null, restanti: Math.max(0, coda.length - 1), chiudi };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { giocatori, storicoMatch, type Giocatore } from "./crapp-data";
|
||||
import { giocatori, type Giocatore } from "./crapp-data";
|
||||
import type { Evento } from "./eventi";
|
||||
import type { MappaPresenze } from "./presenze";
|
||||
import { mediaSquadra, type VotoPagella } from "./pagelle";
|
||||
@@ -20,6 +20,8 @@ export type ContestoObiettivi = {
|
||||
eventi: Evento[];
|
||||
presenze: MappaPresenze;
|
||||
pagelle: VotoPagella[];
|
||||
/** Vittorie ufficiali in campionato (dato CSI). */
|
||||
vittorie?: number;
|
||||
};
|
||||
|
||||
export const contestoVuoto: ContestoObiettivi = { eventi: [], presenze: {}, pagelle: [] };
|
||||
@@ -50,8 +52,6 @@ function percentualeRisposte(ctx: ContestoObiettivi) {
|
||||
return Math.round((risposte / posti) * 100);
|
||||
}
|
||||
|
||||
const vittorie = storicoMatch.filter((m) => m.setNostri > m.setLoro).length;
|
||||
|
||||
/** Obiettivi collaborativi: si muovono con il contributo di tutta la rosa. */
|
||||
export function obiettiviSquadra(
|
||||
rosa: Giocatore[] = giocatori,
|
||||
@@ -59,6 +59,7 @@ export function obiettiviSquadra(
|
||||
): ObiettivoSquadra[] {
|
||||
const somma = (f: (g: Giocatore) => number) => rosa.reduce((s, g) => s + f(g), 0);
|
||||
const continui = rosa.filter((g) => g.serieAllenamenti >= 3).length;
|
||||
const vittorie = ctx.vittorie ?? 0;
|
||||
return [
|
||||
{
|
||||
id: "o1",
|
||||
|
||||
@@ -60,8 +60,7 @@ export function usePresenzeUltimoMeseTutti(): Record<
|
||||
|
||||
const out: Record<string, { presenti: number; totali: number; percentuale: number }> = {};
|
||||
for (const e of rilevanti) {
|
||||
const ids =
|
||||
e.convocati.length > 0 ? e.convocati : giocatori.map((g) => g.id);
|
||||
const ids = e.convocati.length > 0 ? e.convocati : giocatori.map((g) => g.id);
|
||||
for (const id of ids) {
|
||||
const rec = (out[id] ??= { presenti: 0, totali: 0, percentuale: 0 });
|
||||
rec.totali += 1;
|
||||
@@ -74,4 +73,4 @@ export function usePresenzeUltimoMeseTutti(): Record<
|
||||
}
|
||||
return out;
|
||||
}, [eventi, presenze]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,4 +69,4 @@ export async function disattivaNotifiche(): Promise<void> {
|
||||
await sub.unsubscribe();
|
||||
}
|
||||
await reg?.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -11,6 +11,8 @@ import { useGiocatoreBase } from "./user-store";
|
||||
import { useEventi } from "./eventi";
|
||||
import { useRispostePresenze } from "./presenze";
|
||||
import { obiettiviOrdinati } from "./obiettivi";
|
||||
import { useCsi } from "./csi";
|
||||
import { partiteGiocate } from "./csi-core";
|
||||
|
||||
/**
|
||||
* Rosa completa con tutte le statistiche personali (presenze, MVP, media voto,
|
||||
@@ -57,7 +59,11 @@ export function useObiettivi() {
|
||||
const { eventi } = useEventi();
|
||||
const { presenze } = useRispostePresenze();
|
||||
const { voti: pagelle } = usePagelle();
|
||||
return obiettiviOrdinati(rosa, { eventi, presenze, pagelle });
|
||||
const { data: csi } = useCsi();
|
||||
const vittorie = csi
|
||||
? partiteGiocate(csi.partite).filter((p) => (p.setNostri ?? 0) > (p.setLoro ?? 0)).length
|
||||
: 0;
|
||||
return obiettiviOrdinati(rosa, { eventi, presenze, pagelle, vittorie });
|
||||
}
|
||||
|
||||
export { giocatori };
|
||||
|
||||
@@ -14,7 +14,14 @@ export function rigaCsv(campi: Array<string | number>) {
|
||||
/** Esporta la scoutizzazione di una partita in CSV (separatore ";" per Excel IT). */
|
||||
export function csvScoutMatch(match: ScoutMatch): string {
|
||||
const righe: string[] = [];
|
||||
righe.push(rigaCsv(["Partita", match.casa ? "CRAP Volley" : match.avversario, "vs", match.casa ? match.avversario : "CRAP Volley"]));
|
||||
righe.push(
|
||||
rigaCsv([
|
||||
"Partita",
|
||||
match.casa ? "CRAP Volley" : match.avversario,
|
||||
"vs",
|
||||
match.casa ? match.avversario : "CRAP Volley",
|
||||
]),
|
||||
);
|
||||
righe.push(rigaCsv(["Data", match.data, "Set", `${match.setNostri}-${match.setLoro}`]));
|
||||
righe.push("");
|
||||
righe.push(rigaCsv(["Set", "Parziale nostro", "Parziale loro"]));
|
||||
|
||||
+44
-48
@@ -1,24 +1,54 @@
|
||||
import { useSyncExternalStore } from "react";
|
||||
import { giocatori, classifica, type Giocatore, type RigaClassifica } from "./crapp-data";
|
||||
import { giocatori, type Giocatore } from "./crapp-data";
|
||||
|
||||
export type AzioneTipo =
|
||||
| "attacco"
|
||||
| "ace"
|
||||
| "muro"
|
||||
| "errore"
|
||||
| "punto_avv"
|
||||
| "errore_avv";
|
||||
export type AzioneTipo = "attacco" | "ace" | "muro" | "errore" | "punto_avv" | "errore_avv";
|
||||
|
||||
export const azioniMeta: Record<
|
||||
AzioneTipo,
|
||||
{ label: string; short: string; nostro: boolean; richiedeGiocatore: boolean; className: string }
|
||||
> = {
|
||||
attacco: { label: "Punto attacco", short: "Punto", nostro: true, richiedeGiocatore: true, className: "bg-accent text-accent-foreground" },
|
||||
ace: { label: "Ace", short: "Ace", nostro: true, richiedeGiocatore: true, className: "bg-success text-success-foreground" },
|
||||
muro: { label: "Muro", short: "Muro", nostro: true, richiedeGiocatore: true, className: "bg-info text-info-foreground" },
|
||||
errore: { label: "Errore nostro", short: "Errore", nostro: false, richiedeGiocatore: true, className: "bg-destructive text-destructive-foreground" },
|
||||
punto_avv: { label: "Punto avversario", short: "Punto avv.", nostro: false, richiedeGiocatore: false, className: "bg-muted text-muted-foreground" },
|
||||
errore_avv: { label: "Errore avversario", short: "Err. avv.", nostro: true, richiedeGiocatore: false, className: "bg-secondary text-foreground" },
|
||||
attacco: {
|
||||
label: "Punto attacco",
|
||||
short: "Punto",
|
||||
nostro: true,
|
||||
richiedeGiocatore: true,
|
||||
className: "bg-accent text-accent-foreground",
|
||||
},
|
||||
ace: {
|
||||
label: "Ace",
|
||||
short: "Ace",
|
||||
nostro: true,
|
||||
richiedeGiocatore: true,
|
||||
className: "bg-success text-success-foreground",
|
||||
},
|
||||
muro: {
|
||||
label: "Muro",
|
||||
short: "Muro",
|
||||
nostro: true,
|
||||
richiedeGiocatore: true,
|
||||
className: "bg-info text-info-foreground",
|
||||
},
|
||||
errore: {
|
||||
label: "Errore nostro",
|
||||
short: "Errore",
|
||||
nostro: false,
|
||||
richiedeGiocatore: true,
|
||||
className: "bg-destructive text-destructive-foreground",
|
||||
},
|
||||
punto_avv: {
|
||||
label: "Punto avversario",
|
||||
short: "Punto avv.",
|
||||
nostro: false,
|
||||
richiedeGiocatore: false,
|
||||
className: "bg-muted text-muted-foreground",
|
||||
},
|
||||
errore_avv: {
|
||||
label: "Errore avversario",
|
||||
short: "Err. avv.",
|
||||
nostro: true,
|
||||
richiedeGiocatore: false,
|
||||
className: "bg-secondary text-foreground",
|
||||
},
|
||||
};
|
||||
|
||||
export type Azione = {
|
||||
@@ -143,37 +173,3 @@ export function giocatoriConScout(
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/** Classifica demo aggiornata con i match scoutati (solo la nostra riga). */
|
||||
export function classificaConScout(matches: ScoutMatch[]): RigaClassifica[] {
|
||||
if (matches.length === 0) return classifica;
|
||||
const agg = matches.reduce(
|
||||
(s, m) => {
|
||||
const vinta = m.setNostri > m.setLoro;
|
||||
s.giocate += 1;
|
||||
s.vinte += vinta ? 1 : 0;
|
||||
s.perse += vinta ? 0 : 1;
|
||||
s.setFatti += m.setNostri;
|
||||
s.setSubiti += m.setLoro;
|
||||
s.punti += vinta ? (m.setLoro <= 1 ? 3 : 2) : m.setLoro === 3 && m.setNostri === 2 ? 1 : 0;
|
||||
return s;
|
||||
},
|
||||
{ giocate: 0, vinte: 0, perse: 0, setFatti: 0, setSubiti: 0, punti: 0 },
|
||||
);
|
||||
return classifica
|
||||
.map((r) =>
|
||||
r.squadra === "CRAP Volley"
|
||||
? {
|
||||
...r,
|
||||
giocate: r.giocate + agg.giocate,
|
||||
vinte: r.vinte + agg.vinte,
|
||||
perse: r.perse + agg.perse,
|
||||
setFatti: r.setFatti + agg.setFatti,
|
||||
setSubiti: r.setSubiti + agg.setSubiti,
|
||||
punti: r.punti + agg.punti,
|
||||
}
|
||||
: r,
|
||||
)
|
||||
.sort((a, b) => b.punti - a.punti || b.setFatti - b.setSubiti - (a.setFatti - a.setSubiti))
|
||||
.map((r, i) => ({ ...r, pos: i + 1 }));
|
||||
}
|
||||
+1
-1
@@ -87,4 +87,4 @@ export function serieGiocatore(g: Giocatore): SerieStato[] {
|
||||
/** La serie migliore da mostrare in home. */
|
||||
export function serieMigliore(g: Giocatore): SerieStato {
|
||||
return serieGiocatore(g).sort((a, b) => b.valore - a.valore)[0]!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,12 @@ async function importaChiave(publicKey: string, privateKey: string) {
|
||||
);
|
||||
}
|
||||
|
||||
async function creaVapidJwt(audience: string, subject: string, publicKey: string, privateKey: string) {
|
||||
async function creaVapidJwt(
|
||||
audience: string,
|
||||
subject: string,
|
||||
publicKey: string,
|
||||
privateKey: string,
|
||||
) {
|
||||
const header = encodeJson({ typ: "JWT", alg: "ES256" });
|
||||
const payload = encodeJson({
|
||||
aud: audience,
|
||||
@@ -74,4 +79,4 @@ export async function inviaPush(endpoint: string): Promise<number> {
|
||||
},
|
||||
});
|
||||
return res.status;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user