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(sessionExpired ? "failed" : "loading"); const [failureDetails, setFailureDetails] = useState(() => @@ -319,7 +325,9 @@ export function EntryGate() { const trimmedEffectiveToken = (effectiveToken ?? "").trim(); const doEntryRef = useRef(doEntry); - doEntryRef.current = doEntry; + useEffect(() => { + doEntryRef.current = doEntry; + }, [doEntry]); useEffect(() => { if (sessionExpired || waitingForEmbeddedToken) return; @@ -354,7 +362,7 @@ export function EntryGate() { return (
-
+
-
+
diff --git a/src/features/results/check-winning-screen.tsx b/src/features/results/check-winning-screen.tsx index c2510d3..77aed47 100644 --- a/src/features/results/check-winning-screen.tsx +++ b/src/features/results/check-winning-screen.tsx @@ -212,17 +212,17 @@ function WinningResultDialog({ - -
+
+
@@ -236,7 +236,9 @@ function WinningResultDialog({ {t("results.check.ticketNumber")} +
+
{query}