diff --git a/src/features/hall/hall-draw-panel.tsx b/src/features/hall/hall-draw-panel.tsx index 2a05f32..36380cd 100644 --- a/src/features/hall/hall-draw-panel.tsx +++ b/src/features/hall/hall-draw-panel.tsx @@ -186,7 +186,7 @@ export function HallDrawPanel({ drawLive }: { drawLive: HallDrawLiveSnapshot }) )} aria-label={t("draw.currentIssue")} > -
{t("draw.issueNo")}
diff --git a/src/features/player/entry-gate.tsx b/src/features/player/entry-gate.tsx index c82e79a..9ce4e6b 100644 --- a/src/features/player/entry-gate.tsx +++ b/src/features/player/entry-gate.tsx @@ -16,7 +16,6 @@ import { useRouter, useSearchParams } from "next/navigation"; import { useCallback, useEffect, - useLayoutEffect, useMemo, useRef, useState, @@ -124,26 +123,33 @@ export function EntryGate() { !tokenFromUrl && !(bearerToken ?? "").trim(); - const [gateReady, setGateReady] = useState(false); - - useLayoutEffect(() => { - if (typeof window === "undefined") return; + const gateReady = useMemo(() => { + if (typeof window === "undefined") return false; if (!isInIframe()) { - if (sessionExpired) { - router.replace("/login?session=expired"); - return; - } + if (sessionExpired) return false; + const hasToken = tokenFromUrl !== "" || (bearerToken ?? "").trim() !== ""; + if (!hasToken) return false; + } + + return true; + }, [bearerToken, sessionExpired, tokenFromUrl]); + + useEffect(() => { + if (gateReady) return; + if (typeof window === "undefined") return; + if (isInIframe()) return; + + if (sessionExpired) { + router.replace("/login?session=expired"); + } else { const hasToken = tokenFromUrl !== "" || (bearerToken ?? "").trim() !== ""; if (!hasToken) { router.replace("/login"); - return; } } - - setGateReady(true); - }, [bearerToken, router, sessionExpired, tokenFromUrl]); + }, [gateReady, router, sessionExpired, tokenFromUrl, bearerToken]); const [phase, setPhase] = useState