diff --git a/src/components/motion/Reveal.tsx b/src/components/motion/Reveal.tsx index ca40e83..8845161 100644 --- a/src/components/motion/Reveal.tsx +++ b/src/components/motion/Reveal.tsx @@ -37,7 +37,7 @@ export function Reveal({ {...(style ? { style } : {})} initial={ridotto ? { opacity: 0 } : { opacity: 0, y: 10 }} whileInView={ridotto ? { opacity: 1 } : { opacity: 1, y: 0 }} - viewport={{ once: true, amount: 0.15, margin: "0px 0px -10% 0px" }} + viewport={{ once: true, amount: "some", margin: "0px 0px -10% 0px" }} transition={ridotto ? { duration: 0.2, delay: ritardo } : { ...molla.ui, delay: ritardo }} > {children} diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index 6c37d79..733da9e 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -18,6 +18,7 @@ import { CelebrazioneBadge } from "../components/crapp/CelebrazioneBadge"; import { Toaster } from "../components/ui/sonner"; import { TeamLogo } from "../components/crapp/ui-bits"; import { useGiocatoreBase } from "../lib/user-store"; +import { useGiocatoriSquadra } from "../lib/giocatori-squadra"; import { useSessione } from "../lib/auth"; import { mantieniWorkerPushAggiornato } from "../lib/push-client"; @@ -172,6 +173,7 @@ function AppShell() { const navigate = useNavigate(); const location = useLocation(); const giocatore = useGiocatoreBase(); + const { isPending: squadraInCorso } = useGiocatoriSquadra(); const { pronta, utenteId } = useSessione(); const [mounted, setMounted] = useState(false); const isBenvenuto = location.pathname === "/benvenuto"; @@ -180,15 +182,18 @@ function AppShell() { // Senza sessione Google non si entra: l'identità la dà il login, non la scelta del nome // (DD-011). Si aspetta `pronta`, altrimenti il primo render sloggato rimbalzerebbe fuori - // chi ha già la sessione in localStorage. + // chi ha già la sessione in localStorage. Si aspetta anche `squadraInCorso`: finché la + // rosa non è arrivata, `giocatore` risulta nullo anche per chi è già collegato (la rosa + // di riserva usa id diversi da quelli veri), e rimbalzerebbe su /benvenuto chi stava solo + // ricaricando una pagina profonda come /eventi. useEffect(() => { setMounted(true); - if (pronta && (!giocatore || !utenteId) && !isBenvenuto) { - navigate({ to: "/benvenuto" }); + if (pronta && !squadraInCorso && (!giocatore || !utenteId) && !isBenvenuto) { + navigate({ to: "/benvenuto", search: { next: location.pathname } }); } - }, [giocatore, utenteId, pronta, isBenvenuto, navigate]); + }, [giocatore, utenteId, pronta, squadraInCorso, isBenvenuto, navigate, location.pathname]); - if (!mounted || !pronta) { + if (!mounted || !pronta || squadraInCorso) { return (
diff --git a/src/routes/benvenuto.tsx b/src/routes/benvenuto.tsx index 24f3760..1b42ac2 100644 --- a/src/routes/benvenuto.tsx +++ b/src/routes/benvenuto.tsx @@ -13,6 +13,11 @@ import { import { impostaGiocatore, resetGiocatore, useGiocatoreCorrente } from "@/lib/user-store"; export const Route = createFileRoute("/benvenuto")({ + validateSearch: (search: Record): { next?: string } => { + const next = search["next"]; + // Solo un percorso interno: mai un URL assoluto, per non aprire un redirect esterno. + return typeof next === "string" && next.startsWith("/") ? { next } : {}; + }, head: () => ({ meta: [ { title: "Benvenuto — CrAPP" }, @@ -32,6 +37,7 @@ export const Route = createFileRoute("/benvenuto")({ function Benvenuto() { const navigate = useNavigate(); + const { next } = Route.useSearch(); const giocatore = useGiocatoreCorrente(); const { pronta, utenteId, emailUtente } = useSessione(); const { righe, daDatabase } = useGiocatoriSquadra(); @@ -45,8 +51,8 @@ function Benvenuto() { const puoEntrare = !!giocatore && !!utenteId; useEffect(() => { - if (puoEntrare) navigate({ to: "/" }); - }, [puoEntrare, navigate]); + if (puoEntrare) navigate({ to: next ?? "/" }); + }, [puoEntrare, navigate, next]); // Chi sei lo dice lo slot collegato all'account, non quello che c'è in localStorage: // senza slot la scelta salvata dalla vecchia selezione libera va buttata. diff --git a/src/routes/eventi.tsx b/src/routes/eventi.tsx index 1f6278f..13052a5 100644 --- a/src/routes/eventi.tsx +++ b/src/routes/eventi.tsx @@ -50,7 +50,7 @@ const tipi: Array<{ id: CategoriaEvento; label: string }> = [ function GestioneEventi() { const io = useGiocatoreCorrente(); const admin = useIsAdmin(); - const { eventi, isPending } = useEventi(); + const { eventi, isPending, isError, error, refetch } = useEventi(); const { righe: squadra } = useGiocatoriSquadra(); const salva = useSalvaEvento(); const elimina = useEliminaEvento(); @@ -275,6 +275,20 @@ function GestioneEventi() {

Carico gli eventi…

+ ) : isError ? ( +
+

+ Non sono riuscito a caricare gli eventi + {error instanceof Error ? `: ${error.message}` : ""}. +

+ +
) : (
{eventi.map((e) => (