feat: improve mobile responsiveness across login, entry, and result screens
Some checks failed
lotteryfront CI / build (push) Has been cancelled
Some checks failed
lotteryfront CI / build (push) Has been cancelled
- Updated HallDrawPanel to use responsive grid layout, switching from 3-column to single-column on mobile with appropriate dividers - Refactored EntryGate to use useMemo for gateReady state instead of useLayoutEffect, improving initialization logic - Reduced minimum height of hero sections from 320px to 200px on mobile (sm:320px) in login and entry screens - Enhanced WinningResultDialog layout with flexbox structure and
This commit is contained in:
@@ -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<Phase>(sessionExpired ? "failed" : "loading");
|
||||
const [failureDetails, setFailureDetails] = useState<FailureRow[]>(() =>
|
||||
@@ -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 (
|
||||
<div className="relative flex min-h-dvh flex-col bg-white">
|
||||
<div className={cn("relative h-[45vh] min-h-[320px]", phase === "success" ? "bg-white" : "bg-red-600")}>
|
||||
<div className={cn("relative h-[45vh] min-h-[200px] sm:min-h-[320px]", phase === "success" ? "bg-white" : "bg-red-600")}>
|
||||
<div className="pointer-events-none absolute inset-0 overflow-hidden">
|
||||
<Image
|
||||
src={phase === "success" ? "/entry/image4.png" : "/entry/image1.png"}
|
||||
|
||||
@@ -151,7 +151,7 @@ export function PlayerLoginScreen(): React.ReactElement {
|
||||
|
||||
return (
|
||||
<div className="relative flex min-h-dvh flex-col bg-white">
|
||||
<div className="relative h-[45vh] min-h-[320px] shrink-0 overflow-hidden bg-red-600">
|
||||
<div className="relative h-[45vh] min-h-[200px] shrink-0 overflow-hidden bg-red-600 sm:min-h-[320px]">
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<Image src="/entry/image1.png" alt="" fill className="object-cover object-center" priority />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user