{"version":3,"file":"RoleGuard.C_hMAJ2L.mjs","names":["React.useRef","createClient","__esmMin","init_ssg_sandbox_shims","window","c","init_jsx_runtime","ce","init_npm_react_18_3_1","de","RenderTarget","addPropertyControls","init_framer_DcxuU94H","ControlType","init_supabase_js_2","Oe","installBodyHider","HIDE_STYLE_ID","style","uninstallBodyHider","isInFramerEditor","t","RoleGuard","props","uninstalledRef","latchedUninstall","supabaseUrl","supabaseAnonKey","supabase","cancelled","safetyTimerId","sess","user","expectedRole","profile","target","wrongRoleHref","signedOutHref","sep","returnTo","error","err","init_RoleGuard"],"sources":["https:/framerusercontent.com/modules/iRd4ZPhvqBb1LPjqLBEL/yPip3Uab7RKQtpAm2j62/RoleGuard.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import*as React from\"react\";import{addPropertyControls,ControlType,RenderTarget}from\"framer\";import{createClient}from\"https://esm.sh/@supabase/supabase-js@2\";const HIDE_STYLE_ID=\"c4c-role-guard-hide\";function installBodyHider(){if(typeof document===\"undefined\")return;if(document.getElementById(HIDE_STYLE_ID))return;const style=document.createElement(\"style\");style.id=HIDE_STYLE_ID;// Hide everything the user could see while we check the role.\n// Padding-top keeps the browser from showing a 100% blank\n// viewport — a tiny progress hint is friendlier than a white\n// void, and if the check hangs the user will at least see this.\nstyle.textContent=`\n        body > *:not(script):not(style) {\n            visibility: hidden !important;\n        }\n        html::before {\n            content: \"Checking access…\";\n            display: block;\n            position: fixed;\n            inset: 0;\n            padding-top: 40vh;\n            text-align: center;\n            font-family: Inter, system-ui, sans-serif;\n            font-size: 14px;\n            color: #5F6B70;\n            background: #FFFFFF;\n            z-index: 2147483647;\n        }\n    `;document.head.appendChild(style);}function uninstallBodyHider(){if(typeof document===\"undefined\")return;const style=document.getElementById(HIDE_STYLE_ID);if(style)style.remove();}function isInFramerEditor(){try{const t=RenderTarget.current();return t===RenderTarget.canvas||t===RenderTarget.thumbnail;}catch{return false;}}/**\n * @framerSupportedLayoutWidth any-prefer-fixed\n * @framerSupportedLayoutHeight auto\n */export default function RoleGuard(props){const{supabaseUrl,supabaseAnonKey,expectedRole,wrongRoleHref,signedOutHref}=props;// Per-instance \"already uninstalled\" latch. The hider is a global\n// singleton (one style tag), but React may re-render this component\n// many times after the auth check completes (parent state changes,\n// Framer breakpoint swaps, etc.). Without the latch, the render-body\n// install would re-install the hider AFTER the effect uninstalled\n// it — and the effect's deps don't change, so it never re-fires to\n// uninstall again. The hider would stay forever.\n//\n// Observed 2026-10-13 on `/login` (signed-out-only mode): fast\n// getSession() → uninstall at ~250ms → React re-render → re-install\n// → hider stuck for the life of the page.\nconst uninstalledRef=React.useRef(false);// Install the hider during render so it's active before any\n// layout work by other components on the page. useEffect runs too\n// late — content would flash first.\nif(!isInFramerEditor()&&typeof document!==\"undefined\"&&!uninstalledRef.current){installBodyHider();}const latchedUninstall=()=>{uninstalledRef.current=true;uninstallBodyHider();};React.useEffect(()=>{if(isInFramerEditor()){latchedUninstall();return;}if(typeof window===\"undefined\")return;if(!supabaseUrl||!supabaseAnonKey){// Dev misconfig — don't trap the user, just unhide.\nlatchedUninstall();return;}const supabase=createClient(supabaseUrl,supabaseAnonKey);let cancelled=false;// Safety unhide (D-087, 2026-10-08): if the whole auth check\n// hasn't completed in 4 seconds, unhide the page so the user\n// always sees something instead of a dead \"Checking access…\"\n// overlay. Known failure: coming from a post-signOut redirect\n// (ResetPasswordSubmit → /login), Supabase JS's first\n// getSession() can stall indefinitely because it inherits a\n// half-flushed GoTrue client state across the navigation. For a\n// signed-out-only page this is safe (unhiding shows the login\n// form); for role-guarded pages RLS still gates the actual data\n// underneath, so a brief flash of a wrong-role shell is bounded\n// by what the viewer could never read anyway.\nconst safetyTimerId=setTimeout(()=>{if(cancelled)return;// eslint-disable-next-line no-console\nconsole.warn(\"[RoleGuard] auth check timed out after 4s — unhiding\");latchedUninstall();},4e3);(async()=>{try{const{data:sess}=await supabase.auth.getSession();const user=sess?.session?.user;if(cancelled)return;clearTimeout(safetyTimerId);// \"signed-out-only\" mode: onboarding / login / signup\n// pages. Signed-out users pass; signed-in users get\n// redirected to their role's dashboard so they don't\n// accidentally re-run signup.\nif(expectedRole===\"signed-out-only\"){if(!user){latchedUninstall();return;}const{data:profile}=await supabase.from(\"profiles\").select(\"role\").eq(\"id\",user.id).maybeSingle();if(cancelled)return;const target=wrongRoleHref&&wrongRoleHref.trim()?wrongRoleHref.trim():profile?.role===\"family\"?\"/careseeker-dashboard\":profile?.role===\"caregiver\"?\"/caregiver-dashboard\":\"/\";window.location.replace(target);return;}// Standard role gates (caregiver / family).\nif(!user){const target=signedOutHref&&signedOutHref.trim()?signedOutHref.trim():\"/login\";const sep=target.includes(\"?\")?\"&\":\"?\";const returnTo=encodeURIComponent(window.location.pathname+window.location.search);window.location.replace(`${target}${sep}returnTo=${returnTo}`);return;}const{data:profile,error}=await supabase.from(\"profiles\").select(\"role\").eq(\"id\",user.id).maybeSingle();if(cancelled)return;if(error){// Can't verify — fail safe and unhide. Better to\n// show the page than lock the user out on a\n// transient Supabase error.\n// eslint-disable-next-line no-console\nconsole.warn(\"[RoleGuard] profile lookup failed\",error);latchedUninstall();return;}const role=profile?.role;if(role===expectedRole){latchedUninstall();return;}// Wrong role → redirect. Default: send careseekers\n// visiting a /caregiver-* page to /careseeker-dashboard\n// and vice versa.\nconst target=wrongRoleHref&&wrongRoleHref.trim()?wrongRoleHref.trim():expectedRole===\"caregiver\"?\"/careseeker-dashboard\":\"/caregiver-dashboard\";window.location.replace(target);}catch(err){// eslint-disable-next-line no-console\nconsole.warn(\"[RoleGuard] check threw\",err);clearTimeout(safetyTimerId);latchedUninstall();}})();return()=>{cancelled=true;clearTimeout(safetyTimerId);};},[supabaseUrl,supabaseAnonKey,expectedRole,wrongRoleHref,signedOutHref]);return /*#__PURE__*/_jsx(\"div\",{style:{width:1,height:1,overflow:\"hidden\",pointerEvents:\"none\",...props.style||{}},\"aria-hidden\":\"true\"});}addPropertyControls(RoleGuard,{supabaseUrl:{type:ControlType.String,title:\"Supabase URL\",defaultValue:\"https://xkatbssxeyumhfieshcu.supabase.co\"},supabaseAnonKey:{type:ControlType.String,title:\"Supabase Anon Key\",defaultValue:\"\",description:\"Public anon key. Safe in the browser.\"},expectedRole:{type:ControlType.Enum,title:\"Expected Role\",options:[\"caregiver\",\"family\",\"signed-out-only\"],optionTitles:[\"Caregiver\",\"Family (careseeker)\",\"Signed-Out Only\"],defaultValue:\"caregiver\"},wrongRoleHref:{type:ControlType.Link,title:\"Wrong-Role URL\",description:\"Where to redirect if the signed-in user has the wrong role (or is signed in at all, when Expected Role is Signed-Out Only). Default: the user's own dashboard.\"},signedOutHref:{type:ControlType.Link,title:\"Signed-Out URL\",description:\"Where to redirect if no one is signed in. Default: /login (with ?returnTo=<current path> appended). Ignored when Expected Role is Signed-Out Only.\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"RoleGuard\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\",\"framerSupportedLayoutWidth\":\"any-prefer-fixed\",\"framerSupportedLayoutHeight\":\"auto\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./RoleGuard.map"],"mappings":"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"}