"use client"; import { useEffect, useSyncExternalStore } from "react"; import { getEffectiveRole } from "./user-view-policy"; const USER_VIEW_STORAGE_KEY = "magent_user_view_preview"; const USER_VIEW_EVENT = "magent:user-view-change"; let fallbackPreview = false; const readUserViewPreview = () => { if (typeof window === "undefined") return false; try { return window.sessionStorage.getItem(USER_VIEW_STORAGE_KEY) === "1"; } catch { return fallbackPreview; } }; const applyDocumentMode = (enabled: boolean) => { if (typeof document === "undefined") return; document.documentElement.dataset.userView = enabled ? "true" : "false"; }; export const setUserViewPreview = (enabled: boolean) => { if (typeof window === "undefined") return; fallbackPreview = enabled; try { if (enabled) { window.sessionStorage.setItem(USER_VIEW_STORAGE_KEY, "1"); } else { window.sessionStorage.removeItem(USER_VIEW_STORAGE_KEY); } } catch { // Preview still works for this document when browser storage is unavailable. } applyDocumentMode(enabled); window.dispatchEvent(new CustomEvent(USER_VIEW_EVENT, { detail: { enabled } })); }; const subscribe = (notify: () => void) => { window.addEventListener(USER_VIEW_EVENT, notify); window.addEventListener("storage", notify); return () => { window.removeEventListener(USER_VIEW_EVENT, notify); window.removeEventListener("storage", notify); }; }; // Unknown during server rendering/initial hydration: admin pages must not mount // and fetch privileged data before the saved per-tab preview mode is known. const serverSnapshot = (): boolean | null => null; export const useUserViewState = () => { const value = useSyncExternalStore(subscribe, readUserViewPreview, serverSnapshot); useEffect(() => { if (value !== null) applyDocumentMode(value); }, [value]); return { enabled: value === true, ready: value !== null }; }; export const useUserViewPreview = () => useUserViewState().enabled; export const useEffectiveRole = (role?: string | null) => { const { enabled, ready } = useUserViewState(); return getEffectiveRole(role, !ready || enabled); };