import { useEffect, useState } from 'react'; // A ready sandbox opens before its refreshed copy lands, so the sandbox says the latest setup changes // are on their way for as long as that is true. Read, never consumed: a remount must not swallow it. const LANDING_KEY = 'akashic_sandbox_landing'; const SHOWN_MS = 90_000; export const LANDING_COPY = 'Your latest setup changes arrive in about a minute.'; type NoticeStorage = Pick; export const markLanding = (storage: NoticeStorage, at: number = Date.now()): void => { try { storage.setItem(LANDING_KEY, String(at)); } catch { // Storage refused: entry still works, it just says nothing about the copy. } }; // Milliseconds left to show the notice; zero when unmarked, stale or unreadable. const landingLeft = (storage: NoticeStorage, now: number): number => { try { const at = Number(storage.getItem(LANDING_KEY)); const left = at ? at + SHOWN_MS - now : 0; return left > 0 && left <= SHOWN_MS ? left : 0; } catch { return 0; } }; export const SandboxLandingNotice = () => { const [left] = useState(() => landingLeft(sessionStorage, Date.now())); const [shown, setShown] = useState(left > 0); useEffect(() => { if (!shown) return; const timer = setTimeout(() => setShown(false), left); return () => clearTimeout(timer); }, [shown, left]); return shown ? {LANDING_COPY} : null; }; export default SandboxLandingNotice;