{"version":3,"file":"UserInfoFields.COGdrgOI.mjs","names":["createClient","useState"],"sources":["https:/framerusercontent.com/modules/5AIqapckuyCvFcNCNqZv/dgLAT1Ln18p5ulxL5rCP/UserInfoFields.js"],"sourcesContent":["// ============================================================================\n// LicenseOverrides.tsx\n// ----------------------------------------------------------------------------\n// One Framer code-override file that shows/hides component VARIANTS based on\n// the user's Supabase login status and their LemonSqueezy plan.\n//\n// HOW TO USE IN FRAMER\n//   1. Framer -> Assets -> Code -> \"+\" -> New Code File -> name it\n//      \"LicenseOverrides\" and paste this whole file in.\n//   2. Select the component on the canvas that has the variants.\n//   3. In the right panel -> Code Overrides -> pick this file, then choose\n//      one of:  withNoActiveLicense | withPlanBasic | withPlanStandard | withVariant\n//   4. Make sure that component actually HAS variants whose names match the\n//      VARIANTS config below (rename here if your variants are named differently).\n//\n// WHAT EACH OVERRIDE DOES\n//   withNoActiveLicense -> shows the \"locked / visitor\" variant to people who are\n//                          NOT signed in (or signed in but with no active plan).\n//   withPlanBasic       -> shows the unlocked variant ONLY to Basic plan holders.\n//   withPlanStandard    -> shows the unlocked variant ONLY to Standard plan holders.\n//   withVariant         -> simple two-variant case (locked / unlocked). Unlocks for\n//                          ANY signed-in user with ANY active plan.\n// ============================================================================\nimport{jsx as _jsx}from\"react/jsx-runtime\";import{useState,useEffect}from\"react\";import{createClient}from\"https://esm.sh/@supabase/supabase-js@2\";// ─── CONFIG ─────────────────────────────────────────────────────────────────\nconst SUPABASE_URL=\"https://jjgvykxvggpjdvshmzuc.supabase.co\";const SUPABASE_ANON=\"sb_publishable_ZXcN0qMNARsXp8oDEf8v7w_e012QHaW\";// Where to send the user after they sign out.\nconst SIGN_OUT_REDIRECT=\"https://www.framerstacks.com/\";// Where the nav avatar links to.\nconst ACCOUNT_PAGE=\"https://www.framerstacks.com/account/\";// Nav avatar size (square, in px). Change this to resize the nav avatar.\nconst NAV_AVATAR_SIZE=38;// The names of the variants on your Framer components.\n// Rename the right-hand strings to EXACTLY match your variant names in Framer.\nconst VARIANTS={locked:\"Locked\",unlocked:\"Unlocked\",basic:\"Basic\",standard:\"Standard\",visitor:\"Visitor\",loggedIn:\"LoggedIn\",loggedOut:\"LoggedOut\"};// ─────────────────────────────────────────────────────────────────────────────\n// Single shared Supabase client (created once, reused by every override)\nlet _client=null;function getClient(){if(!_client)_client=createClient(SUPABASE_URL,SUPABASE_ANON,{auth:{storageKey:\"framerstacks-auth\",persistSession:true,autoRefreshToken:true}});return _client;}let _authInfo={loading:true,firstName:\"\",lastName:\"\",email:\"\",plan:\"\"};let _authFetchStarted=false;const _authListeners=new Set;function _notify(){_authListeners.forEach(fn=>{try{fn();}catch{}});}function _setAuthInfo(next){_authInfo={..._authInfo,...next};_notify();}// Kicks off the one-time fetch. Safe to call many times; only runs once.\nfunction ensureAuthFetch(){if(_authFetchStarted)return;_authFetchStarted=true;const sb=getClient();async function load(){try{const{data}=await sb.auth.getSession();const user=data?.session?.user;if(!user){_setAuthInfo({loading:false,firstName:\"\",lastName:\"\",email:\"\",plan:\"\"});return;}const meta=user.user_metadata||{};const email=user.email||\"\";const displayName=meta.display_name||meta.name||meta.full_name||\"\";const parts=displayName.trim().split(/\\s+/);const firstName=meta.first_name||meta.firstName||meta.given_name||parts[0]||\"\";const lastName=meta.last_name||meta.lastName||meta.family_name||(parts.length>1?parts.slice(1).join(\" \"):\"\")||\"\";// Publish name + email immediately\n_setAuthInfo({loading:false,firstName,lastName,email});// Then add the plan when it arrives\ntry{const{data:profile}=await sb.from(\"profiles\").select(\"plan\").eq(\"id\",user.id).single();const plan=profile&&profile.plan?String(profile.plan).toLowerCase():\"\";_setAuthInfo({plan});}catch{}}catch{_setAuthInfo({loading:false,firstName:\"\",lastName:\"\",email:\"\",plan:\"\"});}}load();// Re-fetch on auth changes (sign in / out)\ntry{sb.auth.onAuthStateChange(()=>{_authFetchStarted=true;load();});}catch{}}// Hook for overrides: returns the shared auth info, re-rendering on updates.\nfunction useAuthInfo(){const[snapshot,setSnapshot]=useState(_authInfo);useEffect(()=>{const listener=()=>setSnapshot({..._authInfo});_authListeners.add(listener);listener()// sync immediately in case data already arrived\n;return()=>{_authListeners.delete(listener);};},[]);// Render-time reconcile: if the module store is further along than our\n// local snapshot (e.g. the effect hasn't run on this Text layer), use the\n// live store value directly so the data still shows.\nif(snapshot.loading!==_authInfo.loading||snapshot.email!==_authInfo.email||snapshot.firstName!==_authInfo.firstName||snapshot.lastName!==_authInfo.lastName||snapshot.plan!==_authInfo.plan){return _authInfo;}return snapshot;}// Start fetching as soon as the file loads in the browser — not waiting for any\n// override to mount. This is the key to text-layer support: the data is ready\n// (or arriving) independently of whether a given layer runs effects.\nif(typeof window!==\"undefined\"){ensureAuthFetch();// Nudge any mounted listeners a few times while data settles, so layers\n// that did subscribe update promptly.\nlet _ticks=0;const _tick=setInterval(()=>{_notify();_ticks++;if(_ticks>10||!_authInfo.loading){if(!_authInfo.loading)clearInterval(_tick);}if(_ticks>20)clearInterval(_tick);},300);}// ─── Shared hook: figures out the user's plan once, caches it ────────────────\n// Returns one of: \"loading\" | \"none\" | \"basic\" | \"standard\"\n//   \"loading\"  -> still checking (we keep the component on its default variant)\n//   \"none\"     -> not signed in, or signed in with no active plan\n//   \"basic\"    -> signed in + profiles.plan === \"basic\"\n//   \"standard\" -> signed in + profiles.plan === \"standard\"\nfunction usePlan(){const[plan,setPlan]=useState(\"loading\");useEffect(()=>{let active=true;const sb=getClient();async function resolve(){try{const{data:{session}}=await sb.auth.getSession();if(!session){if(active)setPlan(\"none\");return;}const{data:profile,error}=await sb.from(\"profiles\").select(\"plan\").eq(\"id\",session.user.id).single();if(error||!profile||!profile.plan){if(active)setPlan(\"none\");return;}if(active)setPlan(String(profile.plan).toLowerCase());}catch{if(active)setPlan(\"none\");}}resolve();// React to login / logout happening while the page is open\nconst{data:{subscription}}=sb.auth.onAuthStateChange(()=>resolve());return()=>{active=false;subscription?.unsubscribe();};},[]);return plan;}// Helper: render the element for matching users, or remove it entirely\n// (return null) for everyone else. Returning null is the reliable way to hide\n// in Framer — setting style.display=\"none\" is often ignored because Framer\n// controls layout with its own inline styles. While the plan is still loading\n// we render nothing, so non-matching content never flashes.\nfunction showForPlan(Component,props,planNow,allowed){if(planNow===\"loading\")return null;const show=allowed.indexOf(planNow)>-1;if(!show)return null;return /*#__PURE__*/_jsx(Component,{...props});}// ─── OVERRIDE 1: withNoActiveLicense ─────────────────────────────────────────\n// SHOW/HIDE. Apply to a stack/component meant for VISITORS — people who are not\n// signed in OR signed in with no active plan (\"none\").\n//   - shown  when: no active license (plan === \"none\")\n//   - hidden when: the user has any active plan (basic or standard)\nexport function withNoActiveLicense(Component){return props=>{const plan=usePlan();return showForPlan(Component,props,plan,[\"none\"]);};}// ─── OVERRIDE 2: withPlanBasic ───────────────────────────────────────────────\n// SHOW/HIDE. Apply to a stack/component meant ONLY for Basic-plan users.\n//   - shown  when: plan === \"basic\"\n//   - hidden for everyone else (standard, visitors, signed-out)\nexport function withPlanBasic(Component){return props=>{const plan=usePlan();return showForPlan(Component,props,plan,[\"basic\"]);};}// ─── OVERRIDE 3: withPlanStandard ────────────────────────────────────────────\n// SHOW/HIDE. Apply to a stack/component meant ONLY for Standard-plan users.\n//   - shown  when: plan === \"standard\"\n//   - hidden for everyone else (basic, visitors, signed-out)\nexport function withPlanStandard(Component){return props=>{const plan=usePlan();return showForPlan(Component,props,plan,[\"standard\"]);};}// ─── OVERRIDE 3b: withPlanGate (RECOMMENDED — single component, 3 variants) ───\n// Apply this ONE override to a SINGLE component that has THREE variants named:\n//   \"Visitor\"  -> shown to visitors / not signed in / no active plan\n//   \"Basic\"    -> shown to Basic-plan users\n//   \"Standard\" -> shown to Standard-plan users\n// It switches the component to the right variant based on the user's plan.\n// This is more reliable than three separate stacks because Framer's variant\n// system handles the swap natively (no hiding/removing of layers needed).\n//\n// Set the component's CANVAS DEFAULT variant to \"Visitor\" so nothing premium\n// flashes during the brief plan check on load.\nexport function withPlanGate(Component){return props=>{const plan=usePlan();if(plan===\"loading\")return /*#__PURE__*/_jsx(Component,{...props});const target=plan===\"standard\"?VARIANTS.standard:plan===\"basic\"?VARIANTS.basic:VARIANTS.visitor;return /*#__PURE__*/_jsx(Component,{...props,variant:target});};}// ─── OVERRIDE 4: withVariant ─────────────────────────────────────────────────\n// Simple two-variant component: \"Unlocked\" and \"Locked\".\n// Shows based purely on SIGN-IN STATE (not plan):\n//   - signed in   -> \"Unlocked\" variant (confidential info, buttons, links)\n//   - signed out  -> \"Locked\" variant (for visitors / not signed up)\n//   - still loading -> stays on the component's canvas default (keep it Locked)\nexport function withVariant(Component){return props=>{const state=useLoginState();if(state===\"loading\")return /*#__PURE__*/_jsx(Component,{...props});const target=state===\"in\"?VARIANTS.unlocked:VARIANTS.locked;return /*#__PURE__*/_jsx(Component,{...props,variant:target});};}// ─── Login-only hook: just checks if a session exists ────────────────────────\n// Lighter than usePlan() because it skips the profiles lookup.\n// Returns one of: \"loading\" | \"in\" | \"out\"\nfunction useLoginState(){const[state,setState]=useState(\"loading\");useEffect(()=>{let active=true;const sb=getClient();async function resolve(){try{const{data:{session}}=await sb.auth.getSession();if(active)setState(session?\"in\":\"out\");}catch{if(active)setState(\"out\");}}resolve();const{data:{subscription}}=sb.auth.onAuthStateChange((_event,session)=>{if(active)setState(session?\"in\":\"out\");});return()=>{active=false;subscription?.unsubscribe();};},[]);return state;}// ─── OVERRIDE 5: withLoggedIn ────────────────────────────────────────────────\n// VARIANT override for a SINGLE component that has two variants:\n// \"LoggedIn\" and \"LoggedOut\".\n//   - signed in   -> shows the \"LoggedIn\" variant\n//   - signed out  -> shows the \"LoggedOut\" variant\n//   - still loading -> stays on the component's canvas default\nexport function withLoggedIn(Component){return props=>{const state=useLoginState();if(state===\"loading\")return /*#__PURE__*/_jsx(Component,{...props});const target=state===\"in\"?VARIANTS.loggedIn:VARIANTS.loggedOut;return /*#__PURE__*/_jsx(Component,{...props,variant:target});};}// ─── OVERRIDE 6: withLoggedOut ───────────────────────────────────────────────\n// VARIANT override for a SINGLE component that has two variants:\n// \"LoggedIn\" and \"LoggedOut\". Same result as withLoggedIn — use whichever\n// name reads more naturally for the element you're applying it to.\n//   - signed out  -> shows the \"LoggedOut\" variant\n//   - signed in   -> shows the \"LoggedIn\" variant\nexport function withLoggedOut(Component){return props=>{const state=useLoginState();if(state===\"loading\")return /*#__PURE__*/_jsx(Component,{...props});const target=state===\"out\"?VARIANTS.loggedOut:VARIANTS.loggedIn;return /*#__PURE__*/_jsx(Component,{...props,variant:target});};}// ─── OVERRIDE 7: withLoggedInNav (COMBINED) ──────────────────────────────────\n// Put this ONE override on your NAV COMPONENT (the one with LoggedIn/LoggedOut\n// variants). It does two jobs:\n//   1. Switches the component variant based on auth state.\n//   2. On page load, checks for a \"?signout=true\" marker in the URL and, if\n//      present, signs the user out and redirects to SIGN_OUT_REDIRECT.\n//\n// WIRING IN FRAMER (no overrides on the buttons themselves):\n//   • Sign-out button  -> set its Link to:  /?signout=true\n//   • Account button   -> set its Link to:  /account/\n//   • Any other button -> its normal link\n// This works even when buttons are icon-only (no text), because detection is\n// by URL marker, not by reading button text.\n//\n// CONFIG: SIGN_OUT_PARAM is the query flag the Sign-out button links to.\nconst SIGN_OUT_PARAM=\"signout\";export function withLoggedInNav(Component){return props=>{const state=useLoginState();useEffect(()=>{// Read the marker from the top-level URL (handles Framer iframe).\nlet search=\"\";try{search=window.location.search||\"\";}catch{}try{if(window.top&&window.top!==window.self&&window.top.location){search=window.top.location.search||search;}}catch{}const params=new URLSearchParams(search);if(params.get(SIGN_OUT_PARAM)!==\"true\")return;// Strip the marker from the URL IMMEDIATELY so it can never fire a\n// second time (e.g. on a later click or re-render). We replace the\n// history entry so ?signout=true no longer sits in the address bar.\ntry{const topWin=window.top&&window.top!==window.self?window.top:window;const loc=topWin.location;const cleanParams=new URLSearchParams(loc.search||\"\");cleanParams.delete(SIGN_OUT_PARAM);const qs=cleanParams.toString();const cleanUrl=loc.pathname+(qs?\"?\"+qs:\"\")+(loc.hash||\"\");topWin.history.replaceState({},\"\",cleanUrl);}catch{}(async()=>{try{const sb=getClient();await sb.auth.signOut({scope:\"global\"});}catch{}try{localStorage.removeItem(\"framerstacks-auth\");Object.keys(localStorage).forEach(k=>{if(k.indexOf(\"sb-\")===0&&k.indexOf(\"-auth-token\")>-1){localStorage.removeItem(k);}});}catch{}const url=SIGN_OUT_REDIRECT;try{if(window.top&&window.top!==window.self){window.top.location.href=url;return;}}catch{}try{if(window.parent&&window.parent!==window.self){window.parent.location.href=url;return;}}catch{}window.location.href=url;})();},[]);if(state===\"loading\")return /*#__PURE__*/_jsx(Component,{...props});const target=state===\"in\"?VARIANTS.loggedIn:VARIANTS.loggedOut;return /*#__PURE__*/_jsx(Component,{...props,variant:target});};}// ════════════════════════════════════════════════════════════════════════════\n// TEXT OVERRIDES — fill a Framer TEXT element with the user's real info.\n// ----------------------------------------------------------------------------\n// Apply these to a TEXT layer (not a component with variants). The override\n// replaces the text content with the live value from Supabase.\n//   withFirstName -> user's first name\n//   withLastName  -> user's last name\n//   withEmail     -> user's email address\n//   withPlanName  -> their plan, nicely capitalised (\"Basic\" / \"Standard\")\n//\n// HOW TO USE\n//   1. Put a normal Text layer on the canvas. The text you type is just a\n//      placeholder (e.g. \"First name\") — it shows briefly while loading.\n//   2. Select it -> Code Overrides -> LicenseOverrides -> pick the override.\n// ════════════════════════════════════════════════════════════════════════════\n// Shared hook: loads first name, last name, email and plan for the signed-in user.\nfunction useUserInfo(){const[info,setInfo]=useState({loading:true,firstName:\"\",lastName:\"\",email:\"\",plan:\"\"});useEffect(()=>{let active=true;const sb=getClient();async function resolve(){try{const{data:{session}}=await sb.auth.getSession();const user=session?.user;if(!user){if(active)setInfo({loading:false,firstName:\"\",lastName:\"\",email:\"\",plan:\"\"});return;}const meta=user.user_metadata||{};const email=user.email||\"\";// The name may be stored under several possible keys depending on\n// how the account was created. Supabase's \"Display name\" usually\n// lands in display_name / name / full_name. We also support the\n// explicit first_name / last_name keys.\nconst displayName=meta.display_name||meta.name||meta.full_name||\"\";const nameParts=displayName.trim().split(/\\s+/);const firstName=meta.first_name||meta.firstName||meta.given_name||nameParts[0]||// first word of the display name\n\"\";const lastName=meta.last_name||meta.lastName||meta.family_name||(nameParts.length>1?nameParts.slice(1).join(\" \"):\"\")||\"\";// Set email + name IMMEDIATELY (they're already in the session).\n// Do NOT wait for the profiles query — that was blocking them.\nif(active)setInfo({loading:false,firstName,lastName,email,plan:\"\"});// Then fetch the plan separately and merge it in when it arrives.\ntry{const{data:profile}=await sb.from(\"profiles\").select(\"plan\").eq(\"id\",user.id).single();const plan=profile&&profile.plan?String(profile.plan).toLowerCase():\"\";if(active&&plan)setInfo({loading:false,firstName,lastName,email,plan});}catch{}}catch{if(active)setInfo({loading:false,firstName:\"\",lastName:\"\",email:\"\",plan:\"\"});}}resolve();const{data:{subscription}}=sb.auth.onAuthStateChange(()=>resolve());return()=>{active=false;subscription?.unsubscribe();};},[]);return info;}// Helper: replace a text layer's content with a string.\nfunction setText(Component,value){return props=>/*#__PURE__*/_jsx(Component,{...props,text:value});}// Helper: render the text layer with a value, OR remove it entirely (return\n// null) when the value is empty. null is the reliable hide in Framer; a\n// style.display=\"none\" is often ignored.\nfunction textOrHidden(Component,props,value){const clean=(value||\"\").trim();if(!clean)return null;return /*#__PURE__*/_jsx(Component,{...props,text:clean});}// ─── TEXT 1: withFirstName ───────────────────────────────────────────────────\nexport function withFirstName(Component){return props=>{const{loading,firstName}=useAuthInfo();if(loading)return /*#__PURE__*/_jsx(Component,{...props});return textOrHidden(Component,props,firstName);};}// ─── TEXT 2: withLastName ────────────────────────────────────────────────────\nexport function withLastName(Component){return props=>{const{loading,lastName}=useAuthInfo();if(loading)return /*#__PURE__*/_jsx(Component,{...props});return textOrHidden(Component,props,lastName);};}// ─── TEXT 3: withEmail ───────────────────────────────────────────────────────\nexport function withEmail(Component){return props=>{const{loading,email}=useAuthInfo();if(loading)return /*#__PURE__*/_jsx(Component,{...props});return textOrHidden(Component,props,email);};}// ─── TEXT 4: withPlanName ────────────────────────────────────────────────────\n// Shows the plan capitalised: \"Basic\" / \"Standard\". Hidden if no active plan.\nexport function withPlanName(Component){return props=>{const{loading,plan}=useAuthInfo();if(loading)return /*#__PURE__*/_jsx(Component,{...props});const pretty=plan?plan.charAt(0).toUpperCase()+plan.slice(1):\"\";return textOrHidden(Component,props,pretty);};}// ════════════════════════════════════════════════════════════════════════════\n// ACTION OVERRIDE — withSignOut\n// ----------------------------------------------------------------------------\n// Apply to your Sign-out BUTTON. On click it signs the user out of Supabase,\n// then navigates the WHOLE TAB to SIGN_OUT_REDIRECT (set in CONFIG up top).\n//\n// Why this version is reliable:\n//   - Attaches a real DOM click listener on the rendered element (capture\n//     phase) so clicks on child elements/labels are caught too — not just the\n//     React onClick, which Framer doesn't always fire.\n//   - Awaits signOut() before navigating, so the session is actually cleared.\n//   - Breaks out of Framer's iframe (window.top) so it navigates the whole tab.\n//\n// HOW TO USE\n//   1. Select your Sign-out button on the canvas.\n//   2. Code Overrides -> LicenseOverrides -> withSignOut.\n// ════════════════════════════════════════════════════════════════════════════\nexport function withSignOut(Component){return props=>{// Shared busy flag across renders without useRef on the element.\nconst[busy,setBusy]=useState(false);async function doSignOut(){if(busy)return;setBusy(true);try{const sb=getClient();await sb.auth.signOut({scope:\"global\"});}catch{}// Clear any stored session directly as a fallback.\ntry{localStorage.removeItem(\"framerstacks-auth\");Object.keys(localStorage).forEach(k=>{if(k.indexOf(\"sb-\")===0&&k.indexOf(\"-auth-token\")>-1){localStorage.removeItem(k);}});}catch{}// Navigate the top-level tab (break out of the Framer iframe).\nconst url=SIGN_OUT_REDIRECT;try{if(window.top&&window.top!==window.self){window.top.location.href=url;return;}}catch{}try{if(window.parent&&window.parent!==window.self){window.parent.location.href=url;return;}}catch{}window.location.href=url;}// Framer fires onTap for tap/click interactions on most elements;\n// we hook both onTap and onClick so whichever the button uses, we catch\n// it. No refs or DOM listeners → no hydration (#421) errors.\nreturn /*#__PURE__*/_jsx(Component,{...props,onTap:e=>{if(typeof props.onTap===\"function\"){try{props.onTap(e);}catch{}}doSignOut();},onClick:e=>{if(typeof props.onClick===\"function\"){try{props.onClick(e);}catch{}}doSignOut();}});};}// ════════════════════════════════════════════════════════════════════════════\n// withAvatar — show the user's profile picture on a FRAME elsewhere (e.g. nav)\n// ----------------------------------------------------------------------------\n// Apply to a Frame/Image layer. It sets that layer's background to the user's\n// avatar (a fresh signed URL). If the user has no avatar, the layer keeps its\n// existing background (your placeholder). Uses the shared auth store + client.\n//\n// HOW TO USE\n//   1. Make a Frame in your nav, sized/rounded how you want the avatar.\n//   2. Code Overrides -> (this file) -> withAvatar.\n// ════════════════════════════════════════════════════════════════════════════\nexport function withAvatar(Component){return props=>{const[url,setUrl]=useState(\"\");useEffect(()=>{let active=true;(async()=>{try{const sb=getClient();const{data:{session}}=await sb.auth.getSession();const user=session?.user;if(!user)return;const{data:profile}=await sb.from(\"profiles\").select(\"avatar_path\").eq(\"id\",user.id).single();if(profile&&profile.avatar_path){const{data:signed}=await sb.storage.from(\"avatars\").createSignedUrl(profile.avatar_path,60*60);if(active&&signed?.signedUrl)setUrl(signed.signedUrl);}}catch{}})();return()=>{active=false;};},[]);if(!url)return /*#__PURE__*/_jsx(Component,{...props});return /*#__PURE__*/_jsx(Component,{...props,style:{...props.style,overflow:\"hidden\",borderRadius:props?.style?.borderRadius!==undefined?props.style.borderRadius:\"50%\",backgroundImage:`url(\"${url}\")`,backgroundSize:\"cover\",backgroundPosition:\"center\",backgroundRepeat:\"no-repeat\"}});};}// ════════════════════════════════════════════════════════════════════════════\n// withAvatarNav — nav avatar that DISPLAYS the picture AND links to /account/\n// ----------------------------------------------------------------------------\n// Use this on the NAV avatar frame (NOT the AvatarUpload component). It shows\n// the user's avatar as a background and, on click, navigates to the account\n// page — it does NOT open a file picker. Upload stays only on /account/.\n//\n// HOW TO USE\n//   1. In your nav, make a Frame sized/rounded for the avatar.\n//   2. Code Overrides -> (this file) -> withAvatarNav.\n//   (No Framer link needed — the override handles navigation.)\n// ════════════════════════════════════════════════════════════════════════════\nexport function withAvatarNav(Component){return props=>{const[url,setUrl]=useState(\"\");useEffect(()=>{let active=true;(async()=>{try{const sb=getClient();const{data:{session}}=await sb.auth.getSession();const user=session?.user;if(!user)return;const{data:profile}=await sb.from(\"profiles\").select(\"avatar_path\").eq(\"id\",user.id).single();if(profile&&profile.avatar_path){const{data:signed}=await sb.storage.from(\"avatars\").createSignedUrl(profile.avatar_path,60*60);if(active&&signed?.signedUrl)setUrl(signed.signedUrl);}}catch{}})();return()=>{active=false;};},[]);function goToAccount(e){if(typeof props.onClick===\"function\"){try{props.onClick(e);}catch{}}const target=ACCOUNT_PAGE;try{if(window.top&&window.top!==window.self){window.top.location.href=target;return;}}catch{}try{if(window.parent&&window.parent!==window.self){window.parent.location.href=target;return;}}catch{}window.location.href=target;}const sizePx=NAV_AVATAR_SIZE;const styleWithBg=url?{...props.style,width:sizePx,height:sizePx,minWidth:sizePx,minHeight:sizePx,borderRadius:\"50%\",clipPath:\"circle(50% at 50% 50%)\",WebkitClipPath:\"circle(50% at 50% 50%)\",backgroundImage:`url(\"${url}\")`,backgroundSize:\"cover\",backgroundPosition:\"center\",cursor:\"pointer\",boxSizing:\"border-box\"}:{...props.style,cursor:\"pointer\"};// When an avatar is shown, hide the button's built-in icon (children)\n// so you don't see BOTH the icon and the photo. With no avatar, keep\n// the icon visible as the placeholder.\nconst childProps=url?{children:null}:{};return /*#__PURE__*/_jsx(Component,{...props,...childProps,style:styleWithBg,onClick:goToAccount,onTap:goToAccount});};}\nexport const __FramerMetadata__ = {\"exports\":{\"withSignOut\":{\"type\":\"reactHoc\",\"name\":\"withSignOut\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withPlanBasic\":{\"type\":\"reactHoc\",\"name\":\"withPlanBasic\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withEmail\":{\"type\":\"reactHoc\",\"name\":\"withEmail\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withLastName\":{\"type\":\"reactHoc\",\"name\":\"withLastName\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withPlanStandard\":{\"type\":\"reactHoc\",\"name\":\"withPlanStandard\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withPlanGate\":{\"type\":\"reactHoc\",\"name\":\"withPlanGate\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withLoggedOut\":{\"type\":\"reactHoc\",\"name\":\"withLoggedOut\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withLoggedIn\":{\"type\":\"reactHoc\",\"name\":\"withLoggedIn\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withNoActiveLicense\":{\"type\":\"reactHoc\",\"name\":\"withNoActiveLicense\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withAvatarNav\":{\"type\":\"reactHoc\",\"name\":\"withAvatarNav\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withFirstName\":{\"type\":\"reactHoc\",\"name\":\"withFirstName\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withVariant\":{\"type\":\"reactHoc\",\"name\":\"withVariant\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withLoggedInNav\":{\"type\":\"reactHoc\",\"name\":\"withLoggedInNav\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withPlanName\":{\"type\":\"reactHoc\",\"name\":\"withPlanName\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withAvatar\":{\"type\":\"reactHoc\",\"name\":\"withAvatar\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./UserInfoFields.map"],"mappings":"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"}