import { useId, useState, type ComponentPropsWithoutRef, type ReactNode } from "react";
import { Link } from "@tanstack/react-router";
import { ChevronDown } from "lucide-react";
import { cn } from "@/lib/utils";
import { inizialiDa, statoMeta, type Stato } from "@/lib/crapp-data";
import { nomeCompleto } from "@/lib/giocatori-squadra";
import { useGiocatoreBase } from "@/lib/user-store";
import { Avatar } from "@/components/crapp/Avatar";
import { Reveal } from "@/components/motion/Reveal";
import { Numero } from "@/components/motion/Numero";
export function TeamLogo({
className,
/**
* Di default l'icona della PWA, che ha dentro il nome dell'app. Dove serve lo
* stemma della squadra e basta si passa `/logo-nerorosso.svg`.
*/
src = "/icon-192.png",
}: {
className?: string;
src?: string;
}) {
return (
);
}
/**
* Superficie standard dell'app: era ripetuta a mano una ventina di volte come
* `rounded-3xl bg-card p-4 shadow-card`, quindi cambiare raggio od ombra
* voleva dire toccare venti file.
*
* Gerarchia dei raggi: contenitore `3xl` → elemento interno `2xl` →
* controllo `full`.
*/
export function Card({
className,
as: Tag = "div",
...props
}: ComponentPropsWithoutRef<"div"> & { as?: "div" | "article" | "section" }) {
return ;
}
/**
* Accesso al profilo in alto a destra: la BottomNav ha quattro voci e questa è
* l'unica porta verso `/profilo`. Sulla pagina del profilo si passa `azione` a
* `PageHeader` con il logo che porta alla home.
*
* Usa `useGiocatoreBase` (sola anagrafica) e non `useIo`: qui serve solo id e
* iniziali, mentre `useIo` calcola l'intera rosa con statistiche (MVP, pagelle,
* cacche, palloni, infortuni). Essendo in un componente montato su quasi ogni
* pagina, quei moduli finirebbero nel bundle condiviso di tutte le rotte.
*/
export function LinkProfilo() {
const g = useGiocatoreBase();
if (!g) return ;
return (
);
}
export function PageHeader({
titolo,
sottotitolo,
azione,
}: {
titolo: string;
sottotitolo?: string;
/** Sostituisce il link al profilo in alto a destra. */
azione?: ReactNode;
}) {
return (
) : null}
{children}
);
}
/** Sezione con titolo cliccabile: il contenuto si apre e chiude. `anteprima` resta sempre visibile. */
export function SezioneTendina({
titolo,
children,
anteprima,
azione,
defaultAperta = false,
indice = 0,
}: {
titolo: string;
children: ReactNode;
anteprima?: ReactNode;
azione?: ReactNode;
defaultAperta?: boolean;
indice?: number;
}) {
const [aperta, setAperta] = useState(defaultAperta);
const id = useId();
return (
{anteprima}
{aperta ? children : null}
);
}
/**
* Classi condivise di input, select e textarea nei form dell'app. `h-10`:
* `input[type="date"]` ha al suo interno segmenti e icona nativi che, anche
* con `appearance-none`, restano un filo più alti di un input di testo a
* parità di padding — un'altezza esplicita allinea tutti i campi tra loro.
*/
export const classiInput =
"h-10 w-full min-w-0 rounded-xl border border-border bg-background px-3 py-2 text-sm";
/**
* Etichetta + controllo di un form. `min-w-0`: dentro `grid-cols-2` questa label
* è l'elemento di griglia e ha `min-width: auto`, quindi si allarga fino al
* contenuto invece di stare nella colonna. Con un controllo nativo largo dentro
* (una data o un'ora su iOS) la coppia sfonda la card.
*/
export function Campo({ label, children }: { label: string; children: ReactNode }) {
return (
);
}
/**
* `