diff --git a/src/components/layout/ComingSoonOverlay.tsx b/src/components/layout/ComingSoonOverlay.tsx index 22fef79..f3a1296 100644 --- a/src/components/layout/ComingSoonOverlay.tsx +++ b/src/components/layout/ComingSoonOverlay.tsx @@ -21,6 +21,25 @@ const faDigits = ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"]; const fa = (n: number | string) => String(n).replace(/[0-9]/g, (d) => faDigits[Number(d)]); +/** + * Local/dev hosts may close the curtain; the live (public) site is hard-locked. + * NODE_ENV can't distinguish them — both local Docker and the deploy are prod + * builds — so we key off the hostname: localhost + private LAN ranges = local. + */ +function isLocalHost(): boolean { + if (typeof window === "undefined") return false; + const h = window.location.hostname; + return ( + h === "localhost" || + h === "127.0.0.1" || + h === "0.0.0.0" || + h.endsWith(".local") || + /^10\./.test(h) || + /^192\.168\./.test(h) || + /^172\.(1[6-9]|2\d|3[01])\./.test(h) // 172.16–31.x (incl. the 172.28.x dev LAN) + ); +} + const FEATURES = [ { icon: "⚡", title: "رندر فوقسریع ویدیو", desc: "ویدیوهایتان را در چند دقیقه و در فضای ابری رندر کنید" }, { icon: "💰", title: "هزینهٔ بسیار پایین", desc: "پرداخت بر اساس ثانیه؛ مقرونبهصرفهتر از همیشه" }, @@ -49,14 +68,22 @@ function useCountdown(target: Date) { } export function ComingSoonOverlay() { - const [open, setOpen] = useState(false); + // Start UP so the live site never flashes the page before the curtain mounts. + const [open, setOpen] = useState(true); + // Only local/dev hosts get a way out; the live site stays locked. + const [canDismiss, setCanDismiss] = useState(false); const cd = useCountdown(LAUNCH); useEffect(() => { - // Show unless dismissed earlier this session. if (typeof window === "undefined") return; - const dismissed = sessionStorage.getItem(STORAGE_KEY); - setOpen(dismissed !== "1"); + const local = isLocalHost(); + setCanDismiss(local); + if (local) { + // Local: respect a prior dismissal so dev navigation isn't blocked. + const dismissed = sessionStorage.getItem(STORAGE_KEY); + setOpen(dismissed !== "1"); + } + // Live: no dismissal path — the curtain stays up, only the countdown shows. }, []); // Lock background scroll while the curtain is up. @@ -198,20 +225,22 @@ export function ComingSoonOverlay() { ))} - {/* CTA */} -
- میتوانید همین حالا نسخهٔ آزمایشی را ببینید -
-+ این دکمه فقط در نسخهٔ محلی نمایش داده میشود +
+