import { createFileRoute, Link } from "@tanstack/react-router"; import { useEffect, useRef, useState } from "react"; import { toast } from "sonner"; import { Flame, Trash2, Bell, LogOut, ShieldCheck, Bug, Lightbulb } from "lucide-react"; import { cn } from "@/lib/utils"; import { Card, PageHeader, StatTile, TeamLogo } from "@/components/crapp/ui-bits"; import { BarraSottosezioni } from "@/components/crapp/BarraSottosezioni"; import { Avatar } from "@/components/crapp/Avatar"; import { caricaAvatar, rimuoviAvatar, useAvatarEsiste, useImpostaAvatarEsiste, } from "@/lib/avatar-store"; import { SerieGriglia } from "@/components/crapp/SerieCard"; import { CollezioneBadge } from "@/components/crapp/CollezioneBadge"; import { ProfiloAmministrativo } from "@/components/crapp/ProfiloAmministrativo"; import { useVotiSocial } from "@/lib/badge-social"; import { useIo } from "@/lib/rosa"; import { usePresenzeUltimoMese } from "@/lib/presenze-mese"; import { attivaNotifiche, disattivaNotifiche, pushSupportato, statoNotifiche, } from "@/lib/push-client"; import { resetGiocatore } from "@/lib/user-store"; import { esci } from "@/lib/auth"; import { useIsAdmin } from "@/lib/ruoli"; import { Reveal } from "@/components/motion/Reveal"; import { version as APP_VERSION } from "../../package.json"; const TAB_PROFILO = ["stagione", "badge", "documenti", "impostazioni"] as const; type TabProfilo = (typeof TAB_PROFILO)[number]; function isTabProfilo(v: unknown): v is TabProfilo { return typeof v === "string" && (TAB_PROFILO as readonly string[]).includes(v); } export const Route = createFileRoute("/profilo")({ validateSearch: (search: Record): { tab?: TabProfilo } => { const tab = isTabProfilo(search["tab"]) ? search["tab"] : undefined; return tab ? { tab } : {}; }, head: () => ({ meta: [ { title: "Profilo giocatore — CrAPP" }, { name: "description", content: "Foto, ruolo, statistiche personali, badge e obiettivi del giocatore CRAP Volley.", }, { property: "og:title", content: "Profilo giocatore — CrAPP" }, { property: "og:description", content: "Statistiche personali, badge e presenze della stagione.", }, ], }), component: Profilo, }); function Profilo() { const { tab } = Route.useSearch(); const tabIniziale = tab ?? "stagione"; const votiSocial = useVotiSocial(); const g = useIo(); const admin = useIsAdmin(); const ultimoMese = usePresenzeUltimoMese(g?.id); const inputRef = useRef(null); const fotoEsiste = useAvatarEsiste(g?.id); const impostaAvatarEsiste = useImpostaAvatarEsiste(); const [bust, setBust] = useState(0); const [notifiche, setNotifiche] = useState(false); const [inCorso, setInCorso] = useState(false); const [supportate, setSupportate] = useState(true); useEffect(() => { setSupportate(pushSupportato()); statoNotifiche() .then(setNotifiche) .catch(() => setNotifiche(false)); }, []); if (!g) return null; async function cambiaNotifiche() { if (!g || inCorso) return; setInCorso(true); try { if (notifiche) { await disattivaNotifiche(); setNotifiche(false); toast.success("Notifiche disattivate"); } else { await attivaNotifiche(g.id); setNotifiche(true); toast.success("Notifiche attive"); } } catch (error) { toast.error(error instanceof Error ? error.message : "Notifiche non disponibili"); } finally { setInCorso(false); } } async function logout() { try { await esci(); resetGiocatore(); } catch (error) { toast.error(error instanceof Error ? error.message : "Uscita non riuscita"); } } const percPresenze = g.totaliEventi ? Math.round((g.presenze / g.totaliEventi) * 100) : 0; async function onFile(e: React.ChangeEvent) { const file = e.target.files?.[0]; e.target.value = ""; if (!file || !g) return; try { await caricaAvatar(g.id, file); setBust(Date.now()); impostaAvatarEsiste(g.id, true); toast.success("Immagine profilo aggiornata"); } catch { toast.error("Non sono riuscito a caricare l'immagine"); } } return ( <> {/* Sul profilo il logo torna in home al posto del link al profilo. */} } />
{fotoEsiste.data ? ( ) : null}
{g.streak} } label="Presenze di fila" />
), }, { id: "badge", label: "Badge", contenuto: , }, { id: "documenti", label: "Docs", contenuto: , }, { id: "impostazioni", label: "Opzioni", contenuto: (
{admin ? ( Dashboard amministratore ) : null} Segnala un bug Suggerisci una nuova funzionalità

CrAPP v{APP_VERSION}

), }, ]} /> ); }