your-ai-workflow-firebase-os 1.14.21 → 1.14.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/{ContactPopup-DFF2AR_d.js → ContactPopup-BLDgoHVE.js} +3 -3
- package/dist/{ContactPopup-DrMOJl4b.cjs → ContactPopup-CiOMamPP.cjs} +2 -2
- package/dist/{PhoneInputField-DjBSFQd9.js → PhoneInputField-9_YRqiYx.js} +1 -1
- package/dist/renderer.cjs.js +1 -1
- package/dist/renderer.es.js +1 -1
- package/dist/your-ai-workflow-firebase-os.cjs.js +54 -47
- package/dist/your-ai-workflow-firebase-os.css +1 -1
- package/dist/your-ai-workflow-firebase-os.es.js +11933 -12924
- package/package.json +1 -1
|
@@ -1,31 +1,18 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-DYteiM-1.cjs`),t=require(`./ContactPopup-DrMOJl4b.cjs`),n=require(`./PhoneInputField-CkAv_5Lw.cjs`);let r=require(`react`);r=e.i(r,1);let i=require(`react/jsx-runtime`),a=require(`firebase/auth`),o=require(`firebase/firestore`),s=require(`firebase/storage`),c=require(`react-router-dom`),l=require(`react-dom`);var u=Object.assign({"./contactForm.config.ts":t.Ra,"./supportForm.config.ts":t.Ia}),d={};for(let e in u){let t=u[e];if(!t)continue;let n=null;for(let e in t)if(e.endsWith(`FormConfig`)||e.endsWith(`Config`)){n=t[e];break}if(!n&&t?.default&&(n=t.default),!n)continue;let r=e.replace(`./`,``).replace(`.config.ts`,``).replace(/Form$/,``).toLowerCase(),i={...n,systemName:n.systemName||r};d[r]=i,i.systemName&&(d[i.systemName]=i,d[i.systemName.toLowerCase()]=i)}if(typeof window<`u`){let e=window.__FBOS_FORMS__||{};window.__FBOS_FORMS__={...d,...e}}var f=Object.assign({}),p=Object.assign({}),m={};for(let e in f){let t=f[e];if(!t)continue;let n=null;for(let e in t)if(e.endsWith(`TabConfig`)||e.endsWith(`Config`)){n=t[e];break}if(!n&&t?.default&&(n=t.default),!n)continue;let r=e.replace(`./`,``).replace(`.config.ts`,``).replace(/Tab$/,``).toLowerCase(),i={config:{...n,pageId:n.pageId||r,tabName:n.tabName||n.title||r},isPublic:!1};m[r]=i,i.config.pageId&&(m[i.config.pageId]=i,m[i.config.pageId.toLowerCase()]=i)}for(let e in p){let t=p[e];if(!t)continue;let n=null;for(let e in t)if(e.endsWith(`PageConfig`)||e.endsWith(`Config`)){n=t[e];break}if(!n&&t?.default&&(n=t.default),!n)continue;let r=e.replace(`./`,``).replace(`.config.ts`,``).replace(/Page$/,``).toLowerCase(),i={config:{...n,pageId:n.pageId||r,pageName:n.pageName||n.title||r},isPublic:!0};m[r]=i,i.config.pageId&&(m[i.config.pageId]=i,m[i.config.pageId.toLowerCase()]=i)}if(typeof window<`u`){let e=window.__FBOS_PAGES__||{};window.__FBOS_PAGES__={...m,...e}}var h=()=>{document.querySelectorAll(`.fbos-content-slot style, .fbos-home-slot style`).forEach(e=>{e.disabled&&e.media===`not all`||(e.disabled=!0,e.media=`not all`,typeof console<`u`&&console.warn(`FirebaseOS: a <style> tag inside a content file is global CSS and was disabled — style with theme classes (bg-background, text-foreground, glass-panel, btn-primary) instead.`))})},g=e=>{for(let t=e;t;t=t.parentElement){if(t.classList.contains(`fbos-content-slot`)||t.classList.contains(`fbos-home-slot`))return!1;if(getComputedStyle(t).position===`fixed`)return!0}return!1},_=()=>{if(typeof window>`u`)return;let e=window.innerHeight*.6;document.querySelectorAll(`.fbos-content-slot *, .fbos-home-slot *`).forEach(t=>{if(!t.clientHeight||t.clientHeight<e||t.scrollHeight<=t.clientHeight+2)return;let n=getComputedStyle(t);n.overflowY!==`visible`&&(n.webkitLineClamp&&n.webkitLineClamp!==`none`||g(t)||(t.style.setProperty(`max-height`,`none`,`important`),t.style.setProperty(`height`,`auto`,`important`),t.scrollHeight>t.clientHeight+2&&t.style.setProperty(`overflow-y`,`visible`,`important`),typeof console<`u`&&console.warn(`FirebaseOS: a box in a content file was as tall as the screen and hid the rest of the page, which left the bottom unreachable on a phone — it was allowed to grow. Let the page be as long as it needs: no h-screen, max-h-screen or overflow-hidden around the whole page.`)))})},v=()=>{(0,r.useEffect)(()=>{if(typeof document>`u`||typeof MutationObserver>`u`)return;let e=()=>{h(),_()};e();let t=new MutationObserver(e);return t.observe(document.body,{childList:!0,subtree:!0}),window.addEventListener(`resize`,e),window.addEventListener(`orientationchange`,e),()=>{t.disconnect(),window.removeEventListener(`resize`,e),window.removeEventListener(`orientationchange`,e)}},[])};function y(){return(typeof window<`u`?window.__FBOS_PAGES__:null)||{}}function b(e=y()){let t=new Set,n=[];for(let[r,i]of Object.entries(e))!i||t.has(i)||(t.add(i),n.push([r,i]));return n}var x=`mem_notifications`;async function S(e){let{toUid:n,toRole:r,title:i,body:a,link:s}=e||{};if(!i||!n&&!r){console.warn(`notify(): needs a title and either toUid (one person) or toRole ('admin' | 'internal').`,e);return}if(r&&r!==`admin`&&r!==`internal`){console.warn(`notify(): toRole is 'admin' or 'internal' — the bell's notifications live in mem_, which only the team can read, so '${r}' would reach nobody. To reach one person, pass toUid with their uid.`,e);return}let c=t.Ea.currentUser;if(!c){console.warn(`notify(): nobody is signed in, so there is no one to send as.`);return}try{await(0,o.addDoc)((0,o.collection)(t.Da,x),{...n?{toUid:n}:{toRole:r},title:i,body:a||``,link:s||``,uid:c.uid,fromName:c.displayName||c.email||``,createdAt:(0,o.serverTimestamp)()})}catch(e){console.warn(`notify(): the notification was not saved. If the sender is not on your team, re-paste your Firestore rules from /setup — sending from outside the team needs the mem_notifications line added in 1.14.21. A sender who is signed out, unverified or deactivated is refused whatever the rules say.`,e)}}var C=`user_notices`;async function w(e,n){let r=String(e||``).trim();if(!r||!n?.title){console.warn(`leaveNotice(): needs the uid of the person to tell and a title.`,n);return}try{await(0,o.addDoc)((0,o.collection)(t.Da,C),{uid:r,kind:`notice`,title:n.title,body:n.body||``,link:n.link||``,fromName:t.Ea.currentUser?.displayName||t.Ea.currentUser?.email||``,createdAt:Date.now()})}catch(e){console.warn(`leaveNotice(): the notice was not saved — only an admin may leave one.`,e)}}async function T(e,t){for(let n of[...new Set(e.map(e=>String(e||``).trim()).filter(Boolean))])await w(n,t)}function E(e,n,r){if(n?.own===!0)return null;let i=n?.start?t.un(new Date(String(n.start)),r):``,a=t.Yt({scheduleName:n?.scheduleName,memberName:n?.memberName}),o=String(n?.cancelReason||``).trim(),s={id:`b_${e}`,groupKey:n?.entryId?`${n.entryId}__${String(n.start||``)}`:``,type:`booking`,link:`/my-bookings`};return n?.cancelled===!0?String(n.cancelledSide||``)===`booker`?null:{...s,title:`Booking cancelled`,subtitle:[a,i,o].filter(Boolean).join(` · `),time:typeof n.cancelledAt==`number`&&n.cancelledAt>0?n.cancelledAt:n.createdAt}:n?.pending!==!0&&typeof n?.acceptedAt==`number`&&n.acceptedAt>0?{...s,title:`Booking confirmed`,subtitle:[a,i].filter(Boolean).join(` · `),time:n.acceptedAt}:null}function D(e,t){let n=new Map;for(let t of e){let e=t.data()||{};if(e.own===!0)continue;let r=e.entryId?`${e.entryId}__${String(e.start||``)}`:t.id,i=n.get(r);i?i.push({id:t.id,data:e}):n.set(r,[{id:t.id,data:e}])}let r=[];for(let e of n.values()){let n=e.find(e=>e.data.cancelled===!0&&String(e.data.cancelledSide||``)!==`booker`&&String(e.data.cancelReason||``).trim())||e.find(e=>e.data.cancelled===!0);if(n){let e=E(n.id,n.data,t);e&&r.push(e);continue}if(e.every(e=>E(e.id,e.data,t)?.title===`Booking confirmed`)){let n=e.reduce((e,t)=>t.data.acceptedAt>e.data.acceptedAt?t:e),i=E(n.id,n.data,t);i&&r.push(i)}}return r}function O(){let[e,n]=(0,r.useState)(!1),[a,s]=(0,r.useState)([]),l=(0,r.useRef)(null),u=(0,r.useRef)(null),[d,f]=(0,r.useState)(null),p=(0,c.useNavigate)(),{user:m,userRole:h,roleConfirmed:g}=t.na(),_=h===`admin`,v=t.fa(h);(0,r.useEffect)(()=>{function e(e){l.current&&!l.current.contains(e.target)&&n(!1)}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let y=(0,r.useRef)({users:[],submissions:[],requests:[],direct:[],rolewide:[],bookings:[],booked:[],bookedByEmail:[],notices:[]}),b=(0,r.useRef)(!1);(0,r.useEffect)(()=>{b.current=!1},[m?.uid]);let S=(e,t)=>{y.current[e]=t;let n=y.current,r=new Set,i=[...n.users,...n.submissions,...n.requests,...n.direct,...n.rolewide,...n.bookings,...n.booked,...n.bookedByEmail,...n.notices].filter(e=>r.has(e.id)?!1:(r.add(e.id),!0));i.sort((e,t)=>{let n=e.time?.toDate?e.time.toDate().getTime():new Date(e.time).getTime();return((t.time?.toDate?t.time.toDate().getTime():new Date(t.time).getTime())||0)-(n||0)}),s(i.slice(0,8))},w=(e,t)=>{b.current||(b.current=!0,console.warn(`AdminNotifications: this account could not read one of the notification feeds, so that part of the bell is empty. Most of them are the team's alone, and every one of them asks for a verified address.`,t)),S(e,[])};(0,r.useEffect)(()=>{let e=[];if(g){if(_){let n=(0,o.query)((0,o.collection)(t.Da,`user_profiles`),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(5));e.push((0,o.onSnapshot)(n,e=>{S(`users`,e.docs.map(e=>{let t=e.data();return{id:`u_${e.id}`,type:`user`,title:`New user registered`,subtitle:t.email||`Unknown`,time:t.createdAt,link:`/users/${e.id}`}}))},e=>w(`users`,e)));let r=(0,o.query)((0,o.collection)(t.Da,`user_submissions`),(0,o.orderBy)(`submittedAt`,`desc`),(0,o.limit)(5));e.push((0,o.onSnapshot)(r,e=>{S(`submissions`,e.docs.filter(e=>e.data()?.formId!==`booking`&&!t.on(e.data()||{})).map(e=>{let t=e.data();return{id:`s_${e.id}`,type:`submission`,title:`New form submission`,subtitle:t.name||t.email||`Anonymous`,time:t.submittedAt,link:`/inbox?open=${encodeURIComponent(`anyone:${e.id}`)}`}}))},e=>w(`submissions`,e)));let i=(0,o.query)((0,o.collection)(t.Da,`user_requests`),(0,o.orderBy)(`submittedAt`,`desc`),(0,o.limit)(5));e.push((0,o.onSnapshot)(i,e=>{S(`requests`,e.docs.map(e=>{let t=e.data();return{id:`r_${e.id}`,type:`request`,title:`New support request`,subtitle:t.name||t.submitterName||t.contactEmail||t.email||`Anonymous`,time:t.submittedAt,link:`/inbox?open=${encodeURIComponent(`signedIn:${e.id}`)}`}}))},e=>w(`requests`,e)))}else S(`users`,[]),S(`submissions`,[]),S(`requests`,[]);if(m?.uid&&(_||v)){let n=e=>{let n=e.data()||{};if(n.own===!0)return null;let r=n.cancelled===!0,i=String(n.cancelledSide||``)!==`booker`&&String(n.cancelledByUid||``)===(m?.uid||``);if(r&&i)return null;let a=n.start?t.un(new Date(String(n.start)),t.an()):``,o=t.cn({name:n.name}),s=String(n.cancelReason||``).trim();return{id:`b_${e.id}`,groupKey:n.entryId?`${n.entryId}__${String(n.start||``)}`:``,type:`booking`,title:r?`Booking cancelled`:n.pending===!0?`Booking to accept`:`New booking`,subtitle:[o,a,r?s:``].filter(Boolean).join(` · `),time:r&&typeof n.cancelledAt==`number`&&n.cancelledAt>0?n.cancelledAt:n.createdAt,link:`/schedule?open=${encodeURIComponent(e.id)}`}},r=e=>{let t=new Set,n=[];for(let r of e)if(r){if(r.groupKey){if(t.has(r.groupKey))continue;t.add(r.groupKey)}n.push(r)}return n},i=_?(0,o.query)((0,o.collection)(t.Da,t.ht),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(5)):(0,o.query)((0,o.collection)(t.Da,t.ht),(0,o.where)(`memberId`,`==`,m.uid));e.push((0,o.onSnapshot)(i,e=>S(`bookings`,r(e.docs.map(n))),e=>w(`bookings`,e)))}else S(`bookings`,[]);if(m?.uid){let n=t.an(),r=e=>D(e.docs,n),i=(0,o.query)((0,o.collection)(t.Da,t.ht),(0,o.where)(`uid`,`==`,m.uid));e.push((0,o.onSnapshot)(i,e=>S(`booked`,r(e)),e=>w(`booked`,e)));let a=String(m.email||``).trim().toLowerCase();if(a){let n=(0,o.query)((0,o.collection)(t.Da,t.ht),(0,o.where)(`email`,`==`,a));e.push((0,o.onSnapshot)(n,e=>S(`bookedByEmail`,r(e)),e=>w(`bookedByEmail`,e)))}else S(`bookedByEmail`,[])}else S(`booked`,[]),S(`bookedByEmail`,[]);if(m?.uid){let n=(0,o.query)((0,o.collection)(t.Da,C),(0,o.where)(`uid`,`==`,m.uid)),r=e=>{let t=e.data()||{};return{id:`n_${e.id}`,type:`message`,title:String(t.title||`Notification`),subtitle:String(t.body||``),time:t.createdAt,link:typeof t.link==`string`&&t.link.startsWith(`/`)?t.link:void 0}};e.push((0,o.onSnapshot)(n,e=>{S(`notices`,e.docs.filter(e=>(e.data()||{}).kind===`notice`).map(r))},e=>w(`notices`,e)))}else S(`notices`,[]);if(m?.uid&&(_||v)){let n=e=>{let t=e.data();return{id:`m_${e.id}`,type:`message`,title:t.title||`Notification`,subtitle:t.body||t.fromName||``,time:t.createdAt,link:typeof t.link==`string`&&t.link.startsWith(`/`)?t.link:void 0}},r=(0,o.query)((0,o.collection)(t.Da,x),(0,o.where)(`toUid`,`==`,m.uid));e.push((0,o.onSnapshot)(r,e=>S(`direct`,e.docs.map(n)),e=>w(`direct`,e)));let i=_?[`admin`,`internal`]:[`internal`],a=(0,o.query)((0,o.collection)(t.Da,x),(0,o.where)(`toRole`,`in`,i));e.push((0,o.onSnapshot)(a,e=>S(`rolewide`,e.docs.map(n)),e=>w(`rolewide`,e)))}else S(`direct`,[]),S(`rolewide`,[]);return()=>e.forEach(e=>e())}},[_,v,m?.uid,m?.email,g]);let[T,E]=(0,r.useState)(()=>typeof window<`u`?parseInt(localStorage.getItem(`admin_notifications_last_read`)||`0`,10):0),O=()=>{let t=!e;if(n(t),t){let e=u.current?.getBoundingClientRect();f(typeof window<`u`&&window.innerWidth<640&&e?e.bottom+8:null);let t=Date.now();E(t),typeof window<`u`&&localStorage.setItem(`admin_notifications_last_read`,t.toString())}},k=a.some(e=>{if(!e.time)return!0;let t=e.time?.toDate?e.time.toDate().getTime():new Date(e.time).getTime();return t>T||isNaN(t)}),A=e=>{n(!1),e.link?p(e.link):e.type===`user`?p(`/users`):e.type===`booking`?p(v?`/schedule`:`/my-bookings`):(e.type===`submission`||e.type===`request`)&&p(`/inbox`)},j=e=>{if(!e)return``;let t=e.toDate?e.toDate():new Date(e),n=Date.now()-t.getTime();if(isNaN(n))return``;let r=Math.floor(n/6e4);if(r<1)return`now`;if(r<60)return`${r}m`;let i=Math.floor(r/60);if(i<24)return`${i}h`;let a=Math.floor(i/24);return a<7?`${a}d`:new Intl.DateTimeFormat(`en-US`,{month:`short`,day:`numeric`}).format(t)};return(0,i.jsxs)(`div`,{className:`relative z-50 flex-shrink-0`,ref:l,children:[(0,i.jsxs)(`button`,{ref:u,onClick:O,className:`w-9 h-9 rounded-xl border border-[var(--panel-border)] transition-all relative text-foreground/60 hover:bg-foreground/5 hover:text-foreground flex items-center justify-center shadow-sm cursor-pointer`,"aria-label":`Notifications`,children:[(0,i.jsx)(t.Ki,{className:`w-4 h-4`}),k&&(0,i.jsx)(`span`,{className:`absolute top-1.5 right-1.5 w-2 h-2 bg-[var(--notification-icon-color)] rounded-full animate-pulse`})]}),(0,i.jsx)(t.pr,{children:e&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:-5,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,scale:.98,y:-5},className:`${d===null?`absolute top-full mt-2 right-0`:`fixed right-4`} w-[min(320px,calc(100vw-2rem))] md:w-[400px] glass-popover border border-[var(--panel-border)] rounded-2xl z-50 flex flex-col origin-top-right overflow-hidden`,style:d===null?void 0:{top:d},children:[(0,i.jsxs)(`div`,{className:`px-4 border-b border-[var(--panel-border)]/50 pb-3 pt-4 flex items-center justify-between`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[14px] text-foreground tracking-wide`,children:`Notifications`}),(_||v)&&(0,i.jsx)(`span`,{className:`text-[10px] font-bold uppercase tracking-widest text-accent bg-accent/10 px-2 py-0.5 rounded-md`,children:_?`Admin`:`Team`})]}),(0,i.jsx)(`div`,{className:`max-h-[350px] overflow-y-auto w-full p-2 flex flex-col gap-1`,children:a.length===0?(0,i.jsx)(`div`,{className:`p-6 text-center text-foreground/40 text-[13px] font-medium`,children:`No recent activity.`}):a.map(e=>(0,i.jsxs)(`button`,{onClick:()=>A(e),className:`w-full flex items-start gap-3 p-3 rounded-xl hover:bg-foreground/5 transition-all text-left group border border-transparent hover:border-[var(--panel-border)]`,children:[(0,i.jsx)(`div`,{className:`mt-0.5 w-8 h-8 rounded-full flex items-center justify-center shrink-0 bg-foreground/5 text-notification-icon`,children:e.type===`user`?(0,i.jsx)(t.Sr,{className:`w-4 h-4`}):e.type===`booking`?(0,i.jsx)(t.Wi,{className:`w-4 h-4`}):e.type===`submission`?(0,i.jsx)(t.Zr,{className:`w-4 h-4`}):e.type===`message`?(0,i.jsx)(t.Ki,{className:`w-4 h-4`}):(0,i.jsx)(t.ji,{className:`w-4 h-4`})}),(0,i.jsxs)(`div`,{className:`flex flex-col flex-1 min-w-0`,children:[(0,i.jsxs)(`div`,{className:`flex items-baseline gap-2`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground group-hover:text-accent transition-colors truncate flex-1 min-w-0`,children:e.title}),(0,i.jsx)(`span`,{className:`text-[10px] font-mono tracking-wide text-foreground/40 shrink-0`,children:j(e.time)})]}),(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/60 truncate`,children:e.subtitle})]})]},e.id))})]})})]})}var k=[{id:`guide`,hidden:!1},{id:`contact`,hidden:!1},{id:`templates`,hidden:!1}],A={drive:`assets`,submissions:`inbox`,requests:`inbox`},j=new Set([`setup`]),M=e=>{let t=(e||[]).map(e=>typeof e==`string`?{id:e,hidden:!1}:{id:String(e.id),hidden:!!e.hidden}).map(e=>({...e,id:A[e.id]||e.id})).filter(e=>!j.has(e.id));return t.filter((e,n)=>t.findIndex(t=>t.id===e.id)===n)},N=[{id:`inbox`,hidden:!1},{id:`users`,hidden:!1},{id:`pages`,hidden:!1},{id:`schedule`,hidden:!1},{id:`mybookings`,hidden:!1},{id:`payments`,hidden:!1},{id:`email`,hidden:!1},{id:`forms`,hidden:!1},{id:`theme`,hidden:!1},{id:`assets`,hidden:!1},{id:`publish`,hidden:!1}],P={route:`/support`,template:`popup_form`,form:`support`,tabName:`Support`,iconName:``};function F(e,t,n,r){let i=0,a=!0;for(let r=0;r<e.length;r++)if(i+=e[r]+(r>0?n:0),i>t){a=!1;break}if(a)return e.length;let o=0,s=0;for(let i=0;i<e.length;i++){let a=o+e[i]+(i>0?n:0);if(a+r>t)break;o=a,s++}return Math.max(s,1)}var I=`Could not reach the server. Check your connection and try again.`,L={goTo(e){window.location.href=e}},R=`/api/payments/webhook`,z=e=>e?`${e.replace(/\/$/,``)}${R}`:``;async function B(){try{let e=t.Ea?.currentUser;return e?await e.getIdToken():null}catch{return null}}function V(e){return e?{Authorization:`Bearer ${e}`}:{}}async function H(e,t){try{let t=await e.json();if(t&&typeof t.error==`string`&&t.error)return t.error}catch{}return t}async function U(e){let t=await W(e);return typeof t==`string`?t:(L.goTo(t.url),null)}async function W(e){try{let t=await B(),n=await fetch(`/api/payments/checkout`,{method:`POST`,headers:{"Content-Type":`application/json`,...V(t)},body:JSON.stringify({...e,origin:window.location.origin})});if(!n.ok)return await H(n,`The payment could not be started. Please try again.`);let r=await n.json();return r?.url?{sessionId:String(r.sessionId||``),url:String(r.url)}:`The payment could not be started. Please try again.`}catch{return I}}async function G(){let e=await B();if(!e)return`Sign in to manage your plan.`;try{let t=await fetch(`/api/payments/portal`,{method:`POST`,headers:{"Content-Type":`application/json`,...V(e)},body:JSON.stringify({origin:window.location.origin})});if(!t.ok)return await H(t,`The billing portal could not be opened.`);let n=await t.json();return n?.url?(L.goTo(String(n.url)),null):`The billing portal could not be opened.`}catch{return I}}async function ee(e){let t={paid:!1,paymentStatus:null,amountTotal:null,currency:null,customerEmail:null,metadata:{},error:null};if(!e)return{...t,error:`No payment session to confirm.`};try{let n=await fetch(`/api/payments/session/${encodeURIComponent(e)}`);if(!n.ok)return{...t,error:await H(n,`That payment could not be found.`)};let r=await n.json();return{paid:r?.paid===!0,paymentStatus:r?.paymentStatus??null,amountTotal:r?.amountTotal??null,currency:r?.currency??null,customerEmail:r?.customerEmail??null,metadata:r?.metadata||{},error:null}}catch{return{...t,error:I}}}var K=null;function q(){return K||=fetch(`/api/payments/status`).then(e=>e.json()).then(e=>({configured:e?.configured===!0&&e?.enabled!==!1,mode:e?.mode??null})).catch(()=>(K=null,{configured:!1,mode:null})),K}function J(){K=null}function Y(){let[e,t]=(0,r.useState)({loading:!0,configured:!1,mode:null});return(0,r.useEffect)(()=>{let e=!1;return q().then(n=>{e||t({loading:!1,...n})}),()=>{e=!0}},[]),e}function te(){let[e,t]=(0,r.useState)({loading:!0,active:!1,subscriptions:[],payments:[],error:null});return(0,r.useEffect)(()=>{let e=!1,n=n=>{e||t({loading:!1,...n})};return(async()=>{let e=await B();if(!e)return n({active:!1,subscriptions:[],payments:[],error:null});try{let t=await fetch(`/api/payments/me`,{headers:V(e)});if(!t.ok)return n({active:!1,subscriptions:[],payments:[],error:await H(t,`Your payments could not be loaded.`)});let r=await t.json();return n({active:r?.active===!0,subscriptions:r?.subscriptions||[],payments:r?.payments||[],error:null})}catch{return n({active:!1,subscriptions:[],payments:[],error:I})}})(),()=>{e=!0}},[]),e}function ne(){let[e,t]=(0,r.useState)({loading:!0,charges:[],subscriptions:[],error:null});return(0,r.useEffect)(()=>{let e=!1,n=n=>{e||t({loading:!1,...n})};return(async()=>{let e=await B();if(!e)return n({charges:[],subscriptions:[],error:`Please sign in first.`});try{let t=await fetch(`/api/payments/sales`,{headers:V(e)});if(!t.ok)return n({charges:[],subscriptions:[],error:await H(t,`The sales could not be loaded.`)});let r=await t.json();return n({charges:r?.charges||[],subscriptions:r?.subscriptions||[],error:null})}catch{return n({charges:[],subscriptions:[],error:I})}})(),()=>{e=!0}},[]),e}var re={"/guide":t.Mi,"/templates":t.ai,"/contact":t.Zr},X=e=>e&&re[e]||t.ci;function Z({onNavigate:e}){let{subscriptions:n,payments:r}=te();return n.length===0&&r.length===0?null:(0,i.jsxs)(c.Link,{to:`/billing`,onClick:e,className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.wi,{className:`w-3 h-3 text-accent`})}),`Billing`]})}function Q(){let{subscriptions:e}=te(),t=e.find(e=>e.active&&e.productName)?.productName;return(0,i.jsx)(i.Fragment,{children:t||`Member`})}var ie={guide:{label:`Guide`,path:`/guide`},templates:{label:`Templates`,path:`/templates`},contact:{label:`Contact`,path:`/contact`}},ae=new Set([`setup`]);function oe({customMenu:e,standalone:n}){let{user:a,userRole:s,signOut:l,roleResolved:u}=t.na(),d=u!==!1,f=t.pa(s),p=t.ha(s),m=t.ia[p],[h,g]=(0,r.useState)(!1),[_,v]=(0,r.useState)(null),[y,x]=(0,r.useState)(!1),[S,C]=(0,r.useState)(!1),[w,T]=(0,r.useState)(!1),E=a?.displayName||a?.email?.split(`@`)[0]||`User`,D=E.charAt(0).toUpperCase()+E.slice(1),{theme:A,toggleTheme:j,activeConfig:N,canSwitchTheme:I}=t.ja(),L=async()=>{await l(),g(!1)},[R,z]=(0,r.useState)({...ie}),[B,V]=(0,r.useState)(k),[H,U]=(0,r.useState)(P.tabName);(0,r.useEffect)(()=>{if(!t.Da)return;let e=(0,o.onSnapshot)((0,o.collection)(t.Da,`sys_pages`),e=>{let t={...ie};for(let[e,n]of b()){if(!n.isPublic)continue;let r=n.config||{};if(r.enabled===!1)continue;let i=r.route?r.route.startsWith(`/`)?r.route:`/`+r.route:`/`+e;t[e]={label:r.pageName||r.pageTitle||r.title||e,path:i}}e.forEach(e=>{let n=e.data();if(n.enabled===!1)return;let r=n.pageName||n.title||ie[e.id]?.label||e.id,i=n.route||(e.id===`home`?`/`:`/`+e.id);t[e.id]={label:r,path:i}});for(let e of ae)delete t[e];z(t)},e=>{console.warn(`sys_pages snapshot error (safe to ignore during auth transition):`,e)}),n=(0,o.onSnapshot)((0,o.doc)(t.Da,`sys_configs`,`page_order`),e=>{V(e.exists()&&Array.isArray(e.data().order)?M(e.data().order):k)},e=>{console.warn(`page_order snapshot error (safe to ignore during auth transition):`,e)}),r=(0,o.onSnapshot)((0,o.doc)(t.Da,`sys_tabs`,`support`),e=>{e.exists()&&e.data().pageName&&U(e.data().pageName)},e=>{console.warn(`support snapshot error (safe to ignore during auth transition):`,e)});return()=>{e(),n(),r()}},[]);let W=(()=>{let e=new Set(B.filter(e=>e.hidden).map(e=>e.id)),t=new Set,n=[];return B.forEach(e=>{if(e.hidden||e.id===`home`)return;let r=R[e.id];r&&(n.push({label:r.label,path:r.path}),t.add(e.id))}),Object.entries(R).forEach(([r,i])=>{!t.has(r)&&!e.has(r)&&r!==`home`&&i.path!==`/`&&i.path!==`/support`&&n.push({label:i.label,path:i.path})}),n})(),G=e||W,ee=(0,r.useRef)(null),K=(0,r.useRef)(null),[q,J]=(0,r.useState)(()=>typeof window<`u`&&window.innerWidth<640);(0,r.useEffect)(()=>{if(typeof window>`u`)return;let e=()=>{let e=window.innerWidth<640;J(t=>(t!==e&&g(!1),e))};return e(),window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[]);let[Y,te]=(0,r.useState)(G.length);(0,r.useEffect)(()=>{if(n||q)return;let e=()=>{let e=ee.current,t=K.current;if(!e||!t)return;let n=e.clientWidth,r=t.querySelectorAll(`[data-measure-nav]`);if(r.length===0){te(G.length);return}te(F(Array.from(r,e=>e.offsetWidth),n,28,50))},t=requestAnimationFrame(e);if(typeof ResizeObserver>`u`)return()=>cancelAnimationFrame(t);let r=new ResizeObserver(()=>requestAnimationFrame(e));return ee.current&&r.observe(ee.current),()=>{cancelAnimationFrame(t),r.disconnect()}},[G.map(e=>e.label).join(`|`),n,q,G.length]);let ne=G.slice(0,Y),re=G.slice(Y);return(0,i.jsxs)(`nav`,{className:`flex items-center justify-between w-full max-w-7xl mx-auto z-40 p-4 md:p-10 relative`,children:[(0,i.jsx)(`div`,{className:`flex items-center min-w-0 z-50`,children:(0,i.jsxs)(c.Link,{to:`/`,className:`flex items-center gap-2 md:gap-2.5 lg:gap-3 group cursor-pointer z-50 min-w-0`,children:[(0,i.jsx)(`div`,{className:`w-8 h-8 md:w-9 md:h-9 rounded-lg glass-panel flex items-center justify-center glow-hover shadow-lg transition-transform duration-500 group-hover:rotate-180 group-active:scale-95 overflow-hidden shrink-0`,children:N?.logoUrl?(0,i.jsx)(`img`,{src:N.logoUrl,alt:`Logo`,className:`w-full h-full object-contain max-md:p-0.5`}):(0,i.jsx)(t.Ci,{className:`w-4 h-4 text-accent`})}),(0,i.jsx)(`span`,{className:`font-bold text-[17px] md:text-[19px] lg:text-[22px] tracking-tight text-gradient transition-all duration-300 drop-shadow-sm truncate`,children:N?.appName||``})]})}),(0,i.jsx)(t.pr,{children:y&&(0,i.jsx)(t.t,{formId:`contact`,onClose:()=>x(!1)})}),(0,i.jsx)(t.pr,{children:S&&(0,i.jsx)(t.t,{formId:`support`,onClose:()=>C(!1)})}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5 md:gap-4 z-50 relative ml-auto flex-1 min-w-0 justify-end`,children:[!n&&!a&&!q&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{ref:K,"aria-hidden":`true`,className:`flex items-center gap-7 whitespace-nowrap px-1`,style:{position:`fixed`,top:-9999,left:0,visibility:`hidden`,height:0,pointerEvents:`none`},children:G.map((e,n)=>(0,i.jsxs)(`span`,{"data-measure-nav":!0,className:`text-[13px] md:text-[14px] font-bold tracking-wide flex items-center gap-1.5 shrink-0`,children:[e.label,e.submenu&&(0,i.jsx)(t.Ri,{className:`w-3 h-3`})]},e.path||n))}),(0,i.jsxs)(`div`,{className:`flex items-center gap-7 mr-6 flex-1 min-w-0 justify-end relative`,ref:ee,children:[ne.map((e,n)=>(0,i.jsxs)(`div`,{className:`relative shrink-0`,onMouseEnter:()=>v(e.label),onMouseLeave:()=>v(null),children:[e.path?(0,i.jsxs)(c.Link,{to:e.path,className:`text-[13px] md:text-[14px] font-bold tracking-wide text-foreground/50 hover:text-accent transition-all cursor-pointer flex items-center gap-1.5`,children:[e.label,e.submenu&&(0,i.jsx)(t.Ri,{className:`w-3 h-3`})]}):(0,i.jsxs)(`button`,{onClick:e.action,className:`text-[13px] md:text-[14px] font-bold tracking-wide text-foreground/50 hover:text-accent transition-all flex items-center gap-1.5`,children:[e.label,e.submenu&&(0,i.jsx)(t.Ri,{className:`w-3 h-3`})]}),e.submenu&&_===e.label&&(0,i.jsx)(`div`,{className:`absolute top-[100%] left-0 pt-2 z-50`,children:(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:5},animate:{opacity:1,y:0},className:`min-w-[180px] max-h-[300px] overflow-y-auto styled-scrollbars bg-background/95 backdrop-blur-xl border border-[var(--panel-border)] rounded-2xl shadow-xl flex flex-col py-2`,children:e.submenu.map((e,t)=>e.path?(0,i.jsx)(c.Link,{to:e.path,className:`px-5 py-3 text-[13px] font-medium text-foreground/70 hover:text-foreground hover:bg-foreground/5 transition-colors`,children:e.label},t):(0,i.jsx)(`button`,{onClick:e.action,className:`px-5 py-3 text-left w-full text-[13px] font-medium text-foreground/70 hover:text-foreground hover:bg-foreground/5 transition-colors`,children:e.label},t))})})]},`${e.path||`no-path`}-${n}`)),re.length>0&&(0,i.jsxs)(`div`,{className:`relative flex items-center shrink-0`,onMouseEnter:()=>g(`overflow`),children:[(0,i.jsx)(`button`,{onClick:()=>g(h===`overflow`?!1:`overflow`),className:`p-1 rounded-lg transition-colors flex items-center ${h===`overflow`?`bg-foreground/5 text-accent`:`text-foreground/50 hover:bg-foreground/5 hover:text-accent`}`,children:(0,i.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`w-5 h-5`,children:[(0,i.jsx)(`circle`,{cx:`12`,cy:`12`,r:`1`}),(0,i.jsx)(`circle`,{cx:`12`,cy:`5`,r:`1`}),(0,i.jsx)(`circle`,{cx:`12`,cy:`19`,r:`1`})]})}),(0,i.jsx)(t.pr,{children:h===`overflow`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>g(!1)}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:5,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:5,scale:.98},className:`absolute top-[100%] pt-1 right-0 min-w-[200px] max-h-[350px] overflow-y-auto styled-scrollbars glass-popover border border-[var(--panel-border)] rounded-2xl flex flex-col py-2 z-50 origin-top-right`,children:re.map((e,t)=>e.path?(0,i.jsx)(c.Link,{to:e.path,onClick:()=>g(!1),className:`px-5 py-3 text-[13px] font-bold tracking-wide text-foreground/70 hover:text-foreground hover:bg-foreground/5 transition-colors`,children:e.label},t):(0,i.jsx)(`button`,{onClick:()=>{e.action&&e.action(),g(!1)},className:`px-5 py-3 text-left w-full text-[13px] font-bold tracking-wide text-foreground/70 hover:text-foreground hover:bg-foreground/5 transition-colors`,children:e.label},t))})]})})]})]})]}),!n&&!a&&(0,i.jsxs)(i.Fragment,{children:[I&&(0,i.jsx)(`button`,{onClick:j,className:`w-9 h-9 rounded-xl border border-[var(--panel-border)] hover:bg-foreground/5 transition-all text-foreground/60 hover:text-foreground flex items-center justify-center shadow-sm shrink-0 cursor-pointer`,"aria-label":`Toggle Theme`,children:A===`dark`?(0,i.jsx)(t.Mr,{className:`w-4 h-4`}):(0,i.jsx)(t.Yr,{className:`w-4 h-4`})}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5 shrink-0`,children:[!q&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(c.Link,{to:`/login`,className:`flex text-[14px] font-bold tracking-wide text-foreground/80 hover:text-accent transition-colors px-3 py-1.5 shrink-0`,children:`Sign In`}),(0,i.jsx)(c.Link,{to:`/register`,className:`flex text-[13px] md:text-[14px] font-bold tracking-wide px-4 py-1.5 md:px-5 md:py-2 rounded-xl btn-primary transition-all duration-300 hover:shadow-lg hover:-translate-y-0.5 active:scale-95 items-center justify-center ml-2 shrink-0`,children:`Get Started`})]}),q&&(0,i.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,i.jsx)(`button`,{onClick:()=>g(h===`guest`?!1:`guest`),"aria-label":`Open menu`,"aria-expanded":h===`guest`,className:`w-9 h-9 rounded-xl glass-panel glow-hover border transition-all flex items-center justify-center ${h===`guest`?`border-accent bg-foreground/5`:`border-[var(--panel-border)] hover:bg-foreground/5`}`,children:(0,i.jsx)(t.Xr,{className:`w-5 h-5 text-accent/80`})}),(0,i.jsx)(t.pr,{children:h===`guest`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>g(!1)}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:-10,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,scale:.95},className:`absolute top-full right-0 mt-3 w-[220px] p-2 glass-popover border border-[var(--panel-border)] rounded-2xl z-50 flex flex-col gap-1 origin-top-right`,children:[G.map((e,t)=>{let n=X(e.path);return e.path?(0,i.jsxs)(c.Link,{to:e.path,onClick:()=>g(!1),className:`flex items-center gap-3 px-3 py-2.5 rounded-xl hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all min-w-0`,children:[(0,i.jsx)(n,{className:`w-4 h-4 text-accent/70 shrink-0`}),` `,(0,i.jsx)(`span`,{className:`text-[14px] font-semibold truncate`,children:e.label})]},`${e.path}-${t}`):(0,i.jsxs)(`button`,{onClick:()=>{e.action&&e.action(),g(!1)},className:`flex items-center gap-3 px-3 py-2.5 rounded-xl hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all w-full text-left min-w-0`,children:[(0,i.jsx)(n,{className:`w-4 h-4 text-accent/70 shrink-0`}),` `,(0,i.jsx)(`span`,{className:`text-[14px] font-semibold truncate`,children:e.label})]},`${e.label}-${t}`)}),(0,i.jsx)(`div`,{className:`pt-2 mt-1 border-t border-[var(--panel-border)]/50 flex flex-col gap-1`,children:(0,i.jsxs)(c.Link,{to:`/login`,onClick:()=>g(!1),className:`flex items-center gap-3 px-3 py-2.5 rounded-xl hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all w-full`,children:[(0,i.jsx)(t.$r,{className:`w-4 h-4 text-accent/70`}),` `,(0,i.jsx)(`span`,{className:`text-[14px] font-semibold`,children:`Sign In`})]})})]})]})})]})]})]}),!n&&a&&(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5`,children:[d&&!!a&&(0,i.jsx)(O,{}),I&&(0,i.jsx)(`button`,{onClick:j,className:`w-9 h-9 rounded-xl border border-[var(--panel-border)] hover:bg-foreground/5 transition-all text-foreground/60 hover:text-foreground flex items-center justify-center shadow-sm shrink-0 cursor-pointer`,"aria-label":`Toggle Theme`,children:A===`dark`?(0,i.jsx)(t.Mr,{className:`w-4 h-4`}):(0,i.jsx)(t.Yr,{className:`w-4 h-4`})}),(0,i.jsxs)(`div`,{className:`relative z-50 flex-shrink-0`,children:[(0,i.jsxs)(`button`,{onClick:()=>g(h===`user`?!1:`user`),className:`flex items-center gap-2 group p-0.5 sm:p-1 sm:pr-2.5 rounded-full hover:bg-foreground/5 transition-all duration-300 cursor-pointer sm:border ${h===`user`?`sm:border-accent/50 sm:bg-foreground/5`:`sm:border-[var(--panel-border)] sm:hover:border-accent/30`}`,children:[(0,i.jsx)(`div`,{className:`w-8 h-8 md:w-9 md:h-9 rounded-full bg-accent/10 flex items-center justify-center overflow-hidden border sm:border-0 transition-colors shrink-0 text-accent ${h===`user`?`border-accent/50`:`border-[var(--panel-border)] group-hover:border-accent/30`}`,children:a.photoURL&&!w?(0,i.jsx)(`img`,{src:a.photoURL,alt:`Profile`,className:`w-full h-full object-cover`,onError:()=>T(!0)}):(0,i.jsx)(t.Sr,{className:`w-4 h-4 md:w-5 md:h-5 text-accent`})}),(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex flex-col text-left mr-1 justify-center min-w-[70px] max-w-[160px]`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-extrabold leading-tight text-foreground truncate w-full`,children:D}),d?(0,i.jsx)(`span`,{className:`text-[10px] font-mono tracking-wider leading-tight text-accent truncate w-full mt-0.5 uppercase font-bold`,children:p===`free`?(0,i.jsx)(Q,{}):m}):(0,i.jsx)(`span`,{className:`h-[10px] w-12 rounded bg-foreground/10 animate-pulse mt-1`,"aria-hidden":`true`})]})]}),(0,i.jsx)(t.pr,{children:h===`user`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>g(!1)}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:-5,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,scale:.98,y:-5},className:`absolute top-full mt-2 right-0 w-[280px] md:w-[320px] glass-popover border border-[var(--panel-border)] rounded-2xl p-2 z-50 flex flex-col origin-top-right`,children:[(0,i.jsxs)(`div`,{className:`p-3 border-b border-[var(--panel-border)]/50 mb-1 flex flex-col gap-1.5`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[15px] text-foreground truncate`,children:D}),(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/50 truncate font-mono`,children:a.email})]}),(0,i.jsxs)(`div`,{className:`py-1`,children:[(0,i.jsxs)(c.Link,{to:`/dashboard`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.si,{className:`w-3 h-3 text-accent`})}),`Dashboard`]}),f&&(0,i.jsxs)(c.Link,{to:`/assets`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.pi,{className:`w-3 h-3 text-accent`})}),`Assets`]}),s===`admin`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(c.Link,{to:`/users`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.xr,{className:`w-3 h-3 text-accent`})}),`Users`]}),(0,i.jsxs)(c.Link,{to:`/inbox`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.di,{className:`w-3 h-3 text-accent`})}),`Inbox`]}),(0,i.jsxs)(c.Link,{to:`/pages`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.ci,{className:`w-3 h-3 text-accent`})}),`Pages`]})]}),s!==`admin`&&(0,i.jsxs)(c.Link,{to:`/support`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3 text-left`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.ji,{className:`w-3 h-3 text-accent`})}),H]}),(0,i.jsx)(Z,{onNavigate:()=>g(!1)}),(0,i.jsxs)(c.Link,{to:`/profile`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.Sr,{className:`w-3 h-3 text-accent`})}),`Profile Settings`]})]}),(0,i.jsx)(`div`,{className:`pt-1 mt-1 border-t border-[var(--panel-border)]/50`,children:(0,i.jsxs)(`button`,{onClick:L,className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-bold tracking-wide hover:bg-red-500/10 hover:text-red-500 text-foreground/70 transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-red-500/5 flex items-center justify-center shrink-0 text-red-500`,children:(0,i.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`w-3 h-3`,children:[(0,i.jsx)(`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`}),(0,i.jsx)(`polyline`,{points:`16 17 21 12 16 7`}),(0,i.jsx)(`line`,{x1:`21`,y1:`12`,x2:`9`,y2:`12`})]})}),`Sign Out`]})})]})]})})]})]}),n&&(0,i.jsx)(i.Fragment,{children:I&&(0,i.jsx)(`button`,{onClick:j,className:`w-9 h-9 rounded-xl border border-[var(--panel-border)] hover:bg-foreground/5 transition-all text-foreground/60 hover:text-foreground flex items-center justify-center shadow-sm shrink-0 cursor-pointer`,"aria-label":`Toggle Theme`,children:A===`dark`?(0,i.jsx)(t.Mr,{className:`w-4 h-4`}):(0,i.jsx)(t.Yr,{className:`w-4 h-4`})})})]})]})}function se(){let[e,n]=(0,r.useState)(null);return(0,i.jsxs)(`main`,{className:`flex-1 flex flex-col items-center justify-center w-full max-w-5xl mx-auto mt-4 md:mt-12 mb-16 md:mb-24 z-10 relative`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:30},animate:{opacity:1,y:0},transition:{duration:.8},className:`text-center mb-8 md:mb-12`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},transition:{delay:.2},className:`inline-flex items-center gap-2 md:gap-3 px-5 md:px-6 py-2 md:py-2.5 mb-8 md:mb-10 text-[13px] md:text-[15px] font-semibold tracking-wide uppercase rounded-full glass-panel text-foreground glow-hover cursor-pointer`,children:[(0,i.jsx)(t.gr,{className:`w-4 h-4 text-accent`}),` The Open-Source Firebase Starter`]}),(0,i.jsx)(t.fr.h1,{className:`text-4xl sm:text-5xl md:text-6xl lg:text-[4.5rem] font-extrabold tracking-tight mb-6 md:mb-8 text-gradient animate-float leading-[1.1] md:leading-[1.15] px-2`,children:`Your AI Firebase`}),(0,i.jsx)(`p`,{className:`text-[14px] sm:text-[15px] md:text-lg lg:text-xl text-foreground/60 max-w-3xl mx-auto font-medium leading-[1.6] md:leading-[1.7] mb-10 md:mb-14 px-6 md:px-4`,children:`A production-ready Firebase backend template with Auth, Firestore prefix rules, and a clean dashboard — ready for vibe-coded apps.`}),(0,i.jsxs)(t.fr.div,{className:`flex flex-col sm:flex-row items-center justify-center gap-4 sm:gap-6 w-full max-w-2xl mx-auto px-6`,initial:{opacity:0},animate:{opacity:1},transition:{delay:.5},children:[(0,i.jsx)(c.Link,{to:`/register`,style:{borderRadius:`var(--btn-radius, 0.75rem)`},className:`w-full sm:w-auto px-6 md:px-8 py-3 md:py-3.5 font-semibold tracking-wide btn-primary text-[15px] shadow-xl transition-all duration-300 hover:-translate-y-1 active:scale-95 flex items-center justify-center`,children:`Start Building Free`}),(0,i.jsx)(c.Link,{to:`/login`,style:{borderRadius:`var(--btn-radius, 0.75rem)`},className:`w-full sm:w-auto px-6 md:px-8 py-3 md:py-3.5 font-semibold tracking-wide btn-secondary text-[15px] transition-all duration-300 flex items-center justify-center hover:-translate-y-1`,children:`Sign In`})]})]}),(0,i.jsx)(t.pr,{children:e&&(0,i.jsx)(t.t,{onClose:()=>n(null),formId:e})})]})}async function ce(){if(!t.Ea)throw Error(`Firebase is not initialized. Check your configuration.`);let e=new a.GoogleAuthProvider;try{return await(0,a.signInWithPopup)(t.Ea,e),`done`}catch(n){if(n?.code===`auth/popup-blocked`||n?.code===`auth/popup-closed-by-user`||n?.code===`auth/cancelled-popup-request`){let{signInWithRedirect:n}=await import(`firebase/auth`);return await n(t.Ea,e),`redirecting`}throw n}}function le(e,t){let n=e?.code||``;return n===`auth/unauthorized-domain`||(e?.message||``).includes(`requested action is invalid`)?`Google Sign-In failed: your app domain is not authorized. Go to Firebase Console → Authentication → Settings → Authorized domains and add your domain (e.g. localhost or your-app.com).`:n===`auth/network-request-failed`?`Network error — please check your internet connection and Firebase configuration.`:e?.message||t}var ue=[{id:`length`,label:`At least 8 characters`,ok:e=>e.length>=8},{id:`case`,label:`An uppercase and a lowercase letter`,ok:e=>/[a-z]/.test(e)&&/[A-Z]/.test(e)},{id:`number`,label:`A number`,ok:e=>/[0-9]/.test(e)}],de=new Set(`password1.password12.password123.password1234.passw0rd1.p@ssword1.p@ssw0rd1.test1234.test12345.testing123.test123456.qwerty123.qwerty1234.abcd1234.abc12345.welcome1.welcome123.admin123.admin1234.letmein123.iloveyou1.monkey123.football1.changeme1.secret123.summer2024.summer2025`.split(`.`)),fe=e=>e.toLowerCase().replace(/[\s._-]/g,``),pe=e=>de.has(fe(e||``)),me=e=>ue.map(t=>({rule:t,met:t.ok(e||``)}));function he(e){let t=e||``;if(!t)return`Choose a password.`;let n=ue.find(e=>!e.ok(t));return n?`Your password needs ${n.label.toLowerCase()}.`:pe(t)?`That password is one of the first anyone would guess. Please pick another.`:``}function ge(e,t){return t?e===t?``:`Both passwords must be the same.`:`Type your password a second time.`}function _e({value:e,className:n=``}){return(0,i.jsx)(`ul`,{className:`flex flex-col gap-1 ml-1 ${n}`,"aria-label":`Password requirements`,children:me(e).map(({rule:e,met:n})=>(0,i.jsxs)(`li`,{className:`flex items-center gap-2 text-[12.5px] font-medium transition-colors ${n?`text-emerald-500`:`text-foreground/45`}`,children:[n?(0,i.jsx)(t.zi,{className:`w-3.5 h-3.5 shrink-0`}):(0,i.jsx)(`span`,{className:`w-3.5 flex justify-center shrink-0`,children:(0,i.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-foreground/25`})}),e.label]},e.id))})}function ve(){let[e,n]=(0,r.useState)(!1),[a,o]=(0,r.useState)(null),[s,l]=(0,r.useState)(``),[u,d]=(0,r.useState)(``),[f,p]=(0,r.useState)(``),[m,h]=(0,r.useState)(``),g=(0,c.useNavigate)(),{registerUser:_}=t.na();return(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mt-6 mb-8 md:mt-0 md:mb-0 md:pt-8 md:pb-32`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.5},className:`w-full max-w-[500px] p-5 sm:p-8 lg:p-10 rounded-3xl md:rounded-3xl glass-panel relative glow-hover shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-30 blur-[20px] rounded-3xl md:rounded-3xl -z-10`}),(0,i.jsxs)(`div`,{className:`mb-5 sm:mb-6 text-center`,children:[(0,i.jsx)(`h3`,{className:`text-[21px] sm:text-3xl font-extrabold mb-1.5 sm:mb-2 text-foreground tracking-tight`,children:`Create an account`}),(0,i.jsx)(`p`,{className:`text-[13.5px] md:text-[15px] font-medium text-foreground/60 tracking-wide`,children:`Join Your AI Firebase and start building today.`})]}),a&&(0,i.jsx)(`div`,{className:`p-3 mb-6 text-[14px] font-medium text-red-400 bg-red-500/10 rounded-xl border border-red-500/20`,children:a}),(0,i.jsxs)(`form`,{className:`space-y-3.5 sm:space-y-4`,onSubmit:async e=>{e.preventDefault(),n(!0),o(null);let t=new FormData(e.currentTarget),r=t.get(`email`),a=t.get(`firstName`),l=t.get(`lastName`),d=he(s),f=d?``:ge(s,u);if(p(d),h(f),d||f){o(d||f),n(!1);return}try{await _(r,s,a,l),g(`/verify`)}catch(e){e?.code===`auth/email-already-in-use`?o((0,i.jsxs)(`span`,{children:[`An account with this email already exists.`,` `,(0,i.jsx)(c.Link,{to:`/login?email=${encodeURIComponent(r)}`,className:`font-bold underline hover:text-accent transition-colors`,children:`Sign in?`})]})):e?.code===`auth/weak-password`?o(he(s)||`Please choose a stronger password.`):o(e?.message||`An error occurred during registration.`)}finally{n(!1)}},children:[(0,i.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-3.5 sm:gap-4`,children:[(0,i.jsx)(t.lr,{name:`firstName`,label:`First Name`,type:`text`,placeholder:`John`,className:`max-sm:h-11`,required:!0}),(0,i.jsx)(t.lr,{name:`lastName`,label:`Last Name`,type:`text`,placeholder:`Doe`,className:`max-sm:h-11`,required:!0})]}),(0,i.jsx)(t.lr,{name:`email`,label:`Email`,type:`email`,placeholder:`name@example.com`,className:`max-sm:h-11`,required:!0}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[(0,i.jsx)(t.lr,{name:`password`,label:`Password`,type:`password`,placeholder:`••••••••`,className:`max-sm:h-11`,autoComplete:`new-password`,value:s,onChange:e=>{l(e.target.value),f&&p(``),m&&e.target.value===u&&h(``)},onBlur:()=>p(s?he(s):``),error:f,required:!0}),s&&(0,i.jsx)(_e,{value:s})]}),s&&(0,i.jsx)(t.lr,{name:`confirmPassword`,label:`Confirm password`,type:`password`,placeholder:`••••••••`,className:`max-sm:h-11`,autoComplete:`new-password`,value:u,onChange:e=>{d(e.target.value),m&&h(``)},onBlur:()=>h(u?ge(s,u):``),error:m,required:!0}),(0,i.jsx)(`div`,{className:`pt-2`,children:(0,i.jsxs)(t.cr,{type:`submit`,className:`w-full py-2.5 sm:py-3 text-[15px] font-bold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,isLoading:e,children:[`Create Account `,(0,i.jsx)(t.Xi,{className:`ml-2 w-4 h-4 group-hover:translate-x-1 transition-transform shrink-0`})]})})]}),(0,i.jsxs)(`div`,{className:`mt-5 pt-4 sm:mt-6 sm:pt-5 border-t border-[var(--panel-border)] space-y-4 text-center`,children:[(0,i.jsxs)(t.cr,{variant:`secondary`,onClick:async()=>{n(!0),o(null);try{await ce()}catch(e){o(le(e,`Google sign-up failed.`))}finally{n(!1)}},className:`w-full py-2.5 sm:py-3 text-[15px] font-bold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,disabled:e,children:[(0,i.jsxs)(`svg`,{className:`w-5 h-5 mr-3`,viewBox:`0 0 24 24`,children:[(0,i.jsx)(`path`,{fill:`currentColor`,d:`M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z`})]}),`Sign up with Google`]}),(0,i.jsxs)(`p`,{className:`text-[13.5px] sm:text-[14px] text-foreground/70 font-medium pt-1 sm:pt-2 tracking-wide`,children:[`Already have an account? `,(0,i.jsx)(c.Link,{to:`/login`,className:`text-accent hover:underline font-bold ml-1`,children:`Sign in`})]})]})]})})}function ye(){let[e,n]=(0,r.useState)(!1),[o,s]=(0,r.useState)(null),[l]=(0,c.useSearchParams)(),u=(0,c.useNavigate)(),[d]=(0,r.useState)(l.get(`email`)||``);return(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mt-6 mb-8 md:mt-0 md:mb-0 md:pt-8 md:pb-32`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.5},className:`w-full max-w-[480px] p-5 sm:p-8 lg:p-10 rounded-3xl md:rounded-3xl glass-panel relative glow-hover shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-30 blur-[20px] rounded-3xl md:rounded-3xl -z-10`}),(0,i.jsxs)(`div`,{className:`mb-5 sm:mb-6 text-center`,children:[(0,i.jsx)(`h3`,{className:`text-[21px] sm:text-3xl font-extrabold mb-1.5 sm:mb-2 text-foreground tracking-tight`,children:`Welcome back`}),(0,i.jsx)(`p`,{className:`text-[13.5px] md:text-[15px] font-medium text-foreground/60 tracking-wide`,children:`Sign in to Your AI Firebase.`})]}),o&&(0,i.jsx)(`div`,{className:`p-3 mb-6 text-[14px] font-medium text-red-400 bg-red-500/10 rounded-xl border border-red-500/20`,children:o}),(0,i.jsxs)(`form`,{className:`space-y-3.5 sm:space-y-4`,onSubmit:async e=>{e.preventDefault(),n(!0),s(null);let r=new FormData(e.currentTarget),o=r.get(`email`),d=r.get(`password`);try{if(!t.Ea)throw Error(`Firebase is not initialized. Check your configuration.`);await(0,a.signInWithEmailAndPassword)(t.Ea,o,d),u(l.get(`from`)||`/dashboard`,{replace:!0})}catch(e){e?.code===`auth/invalid-credential`||e?.code===`auth/user-not-found`||e?.code===`auth/wrong-password`?s((0,i.jsxs)(`span`,{children:[`Email or Password are incorrect.`,` `,(0,i.jsx)(c.Link,{to:`/reset-password`,className:`font-bold underline hover:text-red-400 transition-colors`,children:`Reset password?`})]})):e?.code===`auth/network-request-failed`?s(`Network error — please check your internet connection and Firebase configuration.`):s(e?.message||`Invalid credentials.`),n(!1)}},children:[(0,i.jsx)(t.lr,{name:`email`,label:`Email`,type:`email`,defaultValue:d,placeholder:`name@example.com`,className:`max-sm:h-11`,required:!0}),(0,i.jsxs)(`div`,{className:`space-y-2`,children:[(0,i.jsxs)(`div`,{className:`flex justify-between items-center pr-1`,children:[(0,i.jsx)(`label`,{className:`text-[14px] md:text-[15px] tracking-wide font-medium text-foreground/80 select-none pb-1`,children:`Password`}),(0,i.jsx)(c.Link,{to:`/reset-password`,className:`text-[13px] md:text-[14px] text-accent hover:underline font-bold tracking-wide`,children:`Forgot Password?`})]}),(0,i.jsx)(t.lr,{name:`password`,type:`password`,placeholder:`••••••••`,className:`max-sm:h-11`,required:!0})]}),(0,i.jsx)(`div`,{className:`pt-2`,children:(0,i.jsxs)(t.cr,{type:`submit`,className:`w-full py-2.5 sm:py-3 text-[15px] sm:text-base font-bold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,isLoading:e,children:[`Sign In `,(0,i.jsx)(t.Xi,{className:`ml-2 w-4 h-4 group-hover:translate-x-1 transition-transform shrink-0`})]})})]}),(0,i.jsxs)(`div`,{className:`mt-5 pt-4 sm:mt-6 sm:pt-5 border-t border-[var(--panel-border)] space-y-4 text-center`,children:[(0,i.jsxs)(t.cr,{variant:`secondary`,onClick:async()=>{n(!0),s(null);try{if(await ce()===`redirecting`)return;u(l.get(`from`)||`/dashboard`,{replace:!0})}catch(e){s(le(e,`Google sign-in failed.`))}finally{n(!1)}},className:`w-full py-2.5 sm:py-3 text-[15px] sm:text-base font-bold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,disabled:e,children:[(0,i.jsxs)(`svg`,{className:`w-5 h-5 mr-3`,viewBox:`0 0 24 24`,children:[(0,i.jsx)(`path`,{fill:`currentColor`,d:`M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z`})]}),`Sign in with Google`]}),(0,i.jsxs)(`p`,{className:`text-[13.5px] sm:text-[14px] text-foreground/70 font-medium pt-1 sm:pt-2 tracking-wide`,children:[`New here? `,(0,i.jsx)(c.Link,{to:`/register`,className:`text-accent hover:underline font-bold ml-1`,children:`Create account`})]})]})]})})}function be(){let{user:e,refreshUser:n}=t.na(),o=(0,c.useNavigate)(),[s,l]=(0,r.useState)(!1),[u,d]=(0,r.useState)(!1),[f,p]=(0,r.useState)(``);return(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mb-16`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.5},className:`w-full max-w-[480px] p-6 md:p-8 lg:p-10 rounded-3xl glass-panel relative glow-hover text-center shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-30 blur-[20px] rounded-3xl -z-10`}),(0,i.jsx)(`div`,{className:`w-14 h-14 md:w-16 md:h-16 rounded-2xl glass-panel border border-[var(--panel-border)] flex items-center justify-center mx-auto mb-5 md:mb-6 animate-float shadow-xl`,children:(0,i.jsx)(t.Zr,{className:`w-7 h-7 md:w-8 md:h-8 text-accent opacity-90`})}),(0,i.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold mb-3 text-foreground tracking-tight`,children:`Verify your email`}),(0,i.jsxs)(`p`,{className:`text-[14px] md:text-[15px] text-foreground/60 mb-6 md:mb-8 leading-[1.6] tracking-wide`,children:[`We've sent a verification link to `,(0,i.jsx)(`span`,{className:`font-semibold text-foreground`,children:e?.email}),`. Please check your inbox (and spam folder) to verify your account and access your dashboard.`]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 max-w-[360px] mx-auto`,children:[f&&(0,i.jsx)(`div`,{role:`status`,className:`w-full px-4 py-2.5 md:py-3 text-[13px] md:text-[14px] font-semibold leading-snug rounded-xl border ${f.includes(`Failed`)||f.includes(`not verified`)||f.includes(`wrong`)?`text-red-400 bg-red-500/10 border-red-500/20`:`text-emerald-400 bg-emerald-500/10 border-emerald-500/20`}`,children:f}),(0,i.jsx)(t.cr,{variant:`primary`,onClick:async()=>{l(!0),p(``);try{if(t.Ea.currentUser){if(await t.Ea.currentUser.reload(),!t.Ea.currentUser.emailVerified){p(`Email is not verified yet. Please check your inbox.`),l(!1);return}await t.Ea.currentUser.getIdToken(!0),await n(),o(`/dashboard`)}}catch{p(`Something went wrong. Please try again.`),l(!1)}},isLoading:s,className:`w-full py-2.5 md:py-3 text-[14px] font-bold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,children:`I've verified my email`}),(0,i.jsx)(t.cr,{variant:`ghost`,onClick:async()=>{if(e){d(!0),p(``);try{await(0,a.sendEmailVerification)(e),p(`Verification email sent! Please check your inbox.`)}catch(e){e?.code===`auth/too-many-requests`?p(`Failed to resend: Please wait a minute before trying again.`):p(e?.message||`Failed to resend. Please try again later.`)}finally{d(!1)}}},isLoading:u,className:`w-full py-2.5 md:py-3 text-[13px] md:text-[14px] font-semibold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,children:`Resend verification link`})]})]})})}var xe=.72;function Se(e){let t=(0,r.useRef)(null);return(0,r.useLayoutEffect)(()=>{let e=t.current,n=e?.parentElement;if(!e||!n)return;let r=()=>{e.style.removeProperty(`font-size`),e.removeAttribute(`data-fold`);let t=n.clientWidth,r=e.scrollWidth;if(!t||r<=t)return;let i=parseFloat(window.getComputedStyle(e).fontSize)||24,a=t/r;e.style.setProperty(`font-size`,`${(i*Math.max(a,xe)).toFixed(2)}px`,`important`),a<.72&&e.setAttribute(`data-fold`,``)};if(r(),document.fonts?.ready.then(r).catch(()=>{}),typeof ResizeObserver>`u`)return;let i=new ResizeObserver(r);return i.observe(n),()=>i.disconnect()},e),t}var Ce=({className:e,children:n,...r})=>(0,i.jsx)(`h1`,{ref:Se([n]),className:t.ur(`page-title w-fit inline-block tracking-tight mb-3 mt-1 text-gradient`,e),...r,children:n});Ce.displayName=`PageTitle`;var we=/^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i,Te=e=>{let t=String(e??``).trim();return we.test(t)?t:``};function Ee(e,t){let n=String(e??``).trim();if(!n||/^data:/i.test(n))return``;try{let e=new URL(n,t||void 0);return/^https?:$/.test(e.protocol)?e.href:``}catch{return``}}function De(e,t){let n=e?.colors?.light||{},r=Array.isArray(n.buttonGradient)?n.buttonGradient.map(Te).filter(Boolean).slice(0,2):[];return{appName:String(e?.appName||``).replace(/\s+/g,` `).trim().slice(0,60),logoUrl:Ee(e?.logoUrl,t),appUrl:Ee(t,``),accent:Te(n.accent),foreground:Te(n.foreground),buttonText:Te(n.buttonText),buttonGradient:r,panelBg:Te(n.panelBg),panelBorder:Te(n.panelBorder)}}function Oe(e){return{appName:String(e?.appName||``),logoUrl:String(e?.logoUrl||``),appUrl:String(e?.appUrl||``),accent:String(e?.accent||``),foreground:String(e?.foreground||``),buttonText:String(e?.buttonText||``),buttonGradient:Array.isArray(e?.buttonGradient)?e.buttonGradient.map(String):[],panelBg:String(e?.panelBg||``),panelBorder:String(e?.panelBorder||``)}}var ke=``,Ae=e=>/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i.test(e);function je(){let e=null;try{e=t.ja().activeConfig}catch{e=null}let n=!!t.na()?.isAdmin,i=typeof window<`u`?window.location.origin:``,a=e&&n?JSON.stringify(De(e,i)):``;(0,r.useEffect)(()=>{if(!a||!t.Da||a===ke)return;let e=!1;return(async()=>{try{let n=(0,o.doc)(t.Da,`sys_configs`,`emailBrand`),r=await(0,o.getDoc)(n);if(e)return;let s=r.exists()?Oe(r.data()):null,c=JSON.parse(a);Ae(i)&&s?.appUrl&&(c.appUrl=s.appUrl),(!s||JSON.stringify(s)!==JSON.stringify(c))&&await(0,o.setDoc)(n,c),ke=a}catch{}})(),()=>{e=!0}},[a])}var Me=t.Sa(`admin`),Ne={inbox:{path:`/inbox`,label:`Inbox`,icon:t.di,roles:Me},users:{path:`/users`,label:`Users`,icon:t.xr,roles:Me},pages:{path:`/pages`,label:`Pages`,icon:t.ci,roles:Me},schedule:{path:`/schedule`,label:`Schedule`,icon:t.Wi,roles:t.Sa(`internal`)},mybookings:{path:`/my-bookings`,label:`My bookings`,icon:t.Gi,roles:t.Sa(`user`)},payments:{path:`/payments`,label:`Payments`,icon:t.wi,roles:Me},email:{path:`/email`,label:`Email`,icon:t.Zr,roles:Me},forms:{path:`/forms`,label:`Forms`,icon:t.Br,roles:Me},theme:{path:`/theme`,label:`Theme`,icon:t.Jr,roles:Me},assets:{path:`/assets`,label:`Assets`,icon:t.pi,roles:Me},publish:{path:`/publish`,label:`Publish App`,icon:t.zr,roles:Me}};function Pe(e){try{let t=localStorage.getItem(e);return t?JSON.parse(t):null}catch{return null}}function Fe({customTabs:e=[]}){let{pathname:n}=(0,c.useLocation)(),{user:a,userRole:s,roleResolved:l}=t.na();je();let u=t.v(``,a?.email||``).bookings.length>0,[d,f]=(0,r.useState)(!1),p=(0,r.useRef)(null),[m,h]=(0,r.useState)(()=>Pe(`fbos_nav_tabs`)??{}),[g,_]=(0,r.useState)(()=>{let e=Pe(`fbos_nav_order`);return Array.isArray(e)?M(e):N}),[v,y]=(0,r.useState)(()=>Pe(`fbos_nav_tabs`)!==null),[x,S]=(0,r.useState)(()=>Pe(`fbos_nav_order`)!==null);(0,r.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(t.Da,`sys_tabs`),e=>{let t={};e.forEach(e=>{t[e.id]=e.data()}),h(t),y(!0),localStorage.setItem(`fbos_nav_tabs`,JSON.stringify(t))},e=>{console.warn(`sys_tabs snapshot error:`,e),y(!0)}),n=(0,o.onSnapshot)((0,o.doc)(t.Da,`sys_configs`,`tab_order`),e=>{let t=e.exists()&&Array.isArray(e.data().order)?M(e.data().order):N;_(t),S(!0),localStorage.setItem(`fbos_nav_order`,JSON.stringify(t))},e=>{console.warn(`tab_order snapshot error:`,e),S(!0)}),r=setTimeout(()=>{y(!0),S(!0)},3e3);return()=>{e(),n(),clearTimeout(r)}},[]);let C=l!==!1&&v&&x;(0,r.useEffect)(()=>{function e(e){p.current&&!p.current.contains(e.target)&&f(!1)}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let w=[...(()=>{let e={};Object.entries(Ne).forEach(([t,n])=>{t===`mybookings`&&!u||(e[t]={id:t,...n,exact:!0})});let n={...m};for(let[e,t]of b())t.isPublic||(n[e]={...t.config,...m[e]});Object.entries(n).forEach(([n,r])=>{let i=e[n],a=i?.icon??t.ci;if(r?.iconName){let e=r.iconName.trim(),n=e.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);t.mr[n]?a=t.mr[n]:t.mr[e]&&(a=t.mr[e])}let o=i?.roles??Me;r?.pageType&&(o=t.wa(r)),e[n]={id:n,path:r?.route?r.route.startsWith(`/`)?r.route:`/`+r.route:i?.path??`/`+n,label:r?.tabName||r?.pageTitle||r?.pageName||i?.label||n,icon:a,roles:o,exact:!0}});let r=[],i=new Set;g.forEach(t=>{t.hidden||i.has(t.id)||e[t.id]&&(r.push(e[t.id]),i.add(t.id))});let a=[],o=[];return Object.keys(e).forEach(t=>{if(i.has(t))return;let r=g.find(e=>e.id===t);r?.hidden||(t in n&&!r?a.push(e[t]):o.push(e[t]))}),a.length>0&&r.unshift(...a),o.length>0&&r.push(...o),r})(),...e.map(e=>({...e,id:e.path}))].filter(e=>{let n=t.Ta(s,!!a);return t.Ca(e.roles,n)}),T=(0,r.useRef)(null),E=(0,r.useRef)(null),[D,O]=(0,r.useState)(null);(0,r.useEffect)(()=>{let e=()=>{let e=T.current,t=E.current;if(!e||!t)return;let n=e.clientWidth;if(n===0)return;let r=parseFloat(getComputedStyle(e).columnGap)||40,i=t.querySelectorAll(`[data-measure-tab]`);if(i.length===0){O(w.length);return}O(F(Array.from(i,e=>e.offsetWidth),n,r,52))},t=requestAnimationFrame(e);if(typeof ResizeObserver>`u`)return()=>cancelAnimationFrame(t);let n=new ResizeObserver(()=>requestAnimationFrame(e));return T.current&&n.observe(T.current),()=>{cancelAnimationFrame(t),n.disconnect()}},[w.map(e=>e.id+e.label).join(`|`),w.length,C]);let k=D===null?w:w.slice(0,D),A=D===null?[]:w.slice(D),j=e=>e.exact?n===e.path:n.startsWith(e.path),P=A.some(e=>j(e));return C?w.length===0?null:(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{ref:E,"aria-hidden":`true`,className:`flex items-center gap-5 md:gap-10 whitespace-nowrap px-1`,style:{position:`fixed`,top:-9999,left:0,visibility:`hidden`,pointerEvents:`none`},children:w.map(e=>{let t=e.icon;return(0,i.jsxs)(`span`,{"data-measure-tab":!0,className:`flex items-center gap-2 text-[13px] md:text-[14.5px] font-semibold shrink-0 pb-2.5 md:pb-3`,children:[(0,i.jsx)(t,{className:`w-4 h-4 md:w-[18px] md:h-[18px]`}),e.label]},e.path||e.id)})}),(0,i.jsxs)(`div`,{ref:T,className:`w-full flex items-center gap-5 md:gap-10 mb-5 border-b border-[var(--panel-border)] px-1 whitespace-nowrap relative`,children:[k.map(e=>{let t=j(e),n=e.icon;return(0,i.jsxs)(c.Link,{to:e.path||`/`,className:`flex items-center gap-2 text-[13px] md:text-[14.5px] font-semibold transition-all duration-300 pb-2.5 md:pb-3 -mb-[1px] border-b-2 shrink-0 ${t?`text-accent border-accent`:`text-foreground/50 hover:text-foreground/80 border-transparent`}`,children:[(0,i.jsx)(n,{className:`w-4 h-4 md:w-[18px] md:h-[18px]`}),e.label]},e.path||e.id)}),A.length>0&&(0,i.jsxs)(`div`,{className:`relative shrink-0 ml-auto`,ref:p,children:[(0,i.jsx)(`button`,{onClick:()=>f(!d),className:`flex items-center justify-center transition-all duration-300 pb-2.5 md:pb-3 -mb-[1px] border-b-2 cursor-pointer ${P?`text-accent border-accent`:`text-foreground/50 hover:text-foreground/80 border-transparent`}`,title:`More items`,children:(0,i.jsx)(t.xi,{className:`w-[18px] h-[18px] md:w-5 md:h-5`})}),(0,i.jsx)(t.pr,{children:d&&(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},exit:{opacity:0,y:10},className:`absolute top-[100%] right-0 mt-2 min-w-[200px] glass-popover border border-[var(--panel-border)] rounded-2xl z-50 flex flex-col py-2 overflow-hidden`,children:A.map(e=>{let t=j(e),n=e.icon;return(0,i.jsxs)(c.Link,{to:e.path||`/`,onClick:()=>f(!1),className:`flex items-center gap-3 px-5 py-3 text-[14px] font-medium transition-colors ${t?`text-accent bg-accent/5`:`text-foreground/70 hover:text-foreground hover:bg-foreground/5`}`,children:[(0,i.jsx)(n,{className:`w-4 h-4`}),e.label]},e.path||e.id)})})})]})]})]}):(0,i.jsx)(`div`,{className:`w-full flex items-center gap-5 md:gap-10 mb-5 border-b border-[var(--panel-border)] px-1 whitespace-nowrap relative`,children:[56,72,64].map((e,t)=>(0,i.jsxs)(`span`,{className:`flex items-center gap-2 pb-2.5 md:pb-3 h-[30px] md:h-[33px] shrink-0`,"aria-hidden":`true`,children:[(0,i.jsx)(`span`,{className:`w-4 h-4 md:w-[18px] md:h-[18px] rounded-md bg-foreground/5 animate-pulse`}),(0,i.jsx)(`span`,{className:`h-3.5 rounded bg-foreground/5 animate-pulse`,style:{width:e}})]},t))})}function Ie(){let{user:e,refreshUser:n,isInternal:c}=t.na(),[l,u]=(0,r.useState)(e?.displayName||``),[d,f]=(0,r.useState)(e?.email||``),[p,m]=(0,r.useState)(e?.photoURL||``),[h,g]=(0,r.useState)(!1),[_,v]=(0,r.useState)(null),[y,b]=(0,r.useState)(``),[x,S]=(0,r.useState)(``),[C,w]=(0,r.useState)(``),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(!1),[k,A]=(0,r.useState)(!0);r.default.useEffect(()=>{u(e?.displayName||``),f(e?.email||``),m(e?.photoURL||``)},[e?.uid,e?.displayName,e?.email,e?.photoURL]);let j=async n=>{if(e)try{if(!c)return;let r=[`mem_files`,`admin_files`];(await(0,o.getDocs)((0,o.collection)(t.Da,`sys_tabs`))).forEach(e=>{let n=e.data(),i=(n.tabName||e.id).toLowerCase().replace(/[^a-z0-9]+/g,`_`),a=t.ga(n.pageType);a===`internal`&&r.push(`mem_${i}_records`),a===`admin`&&r.push(`admin_${i}_records`)});for(let i of r)try{let r=await(0,o.getDocs)((0,o.query)((0,o.collection)(t.Da,i),(0,o.where)(`uid`,`==`,e.uid)));if(r.empty)continue;let a=(0,o.writeBatch)(t.Da);r.docs.forEach(e=>a.update(e.ref,{creatorAvatar:n})),await a.commit()}catch{}}catch(e){console.error(`Error propagating avatar to records:`,e)}},M=async r=>{if(!e)return;let i=await t.or(r,{maxSide:512});if(i.size>2*1024*1024){v({text:`File too large. Please select an image under 2MB.`,type:`error`});return}O(!0),E(!1),A(!0);try{let r=(0,s.ref)(t.ka,`user_avatars/${e.uid}/file.png`);await(0,s.uploadBytes)(r,i,{customMetadata:{ownerId:e.uid}});let c=await(0,s.getDownloadURL)(r);m(c);let l=(0,o.doc)(t.Da,`user_profiles`,e.uid);await Promise.all([(0,a.updateProfile)(e,{photoURL:c}),(0,o.updateDoc)(l,{avatar:c}),j(c)]),await n(),v({text:`Avatar successfully updated!`,type:`success`})}catch(e){console.error(e),v({text:`Failed to upload photo.`,type:`error`})}finally{O(!1)}},N=e=>{let t=e.target.files?.[0];t&&M(t)},{over:P,dropProps:F}=t.er({accept:`image/*`,disabled:D,onFiles:([e])=>M(e),onReject:()=>v({text:`That is not a picture. Drop a JPG or a PNG.`,type:`error`})}),I=async()=>{if(e){O(!0),E(!1),A(!1);try{let r=(0,s.ref)(t.ka,`user_avatars/${e.uid}/file.png`);m(``),O(!1);let i=(0,o.doc)(t.Da,`user_profiles`,e.uid);await Promise.all([(0,s.deleteObject)(r).catch(e=>console.error(e)),(0,a.updateProfile)(e,{photoURL:``}),(0,o.updateDoc)(i,{avatar:``}),j(``)]),await n(),v({text:`Avatar removed.`,type:`success`})}catch(e){console.error(e),v({text:`Failed to delete photo.`,type:`error`}),O(!1)}}};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-5 sm:mb-8`,children:[(0,i.jsx)(Ce,{children:`Profile Settings`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/profile`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-6 animate-in fade-in duration-500 pb-20`,children:[(0,i.jsx)(`div`,{className:`flex justify-start`,children:(0,i.jsx)(Fe,{})}),(0,i.jsx)(t.pr,{children:_&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.98,y:-10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.98,y:-10},className:`p-4 mb-6 rounded-2xl border flex flex-col sm:flex-row sm:items-center gap-3 ${_.type===`error`?`bg-red-500/10 border-red-500/20 text-red-400`:`bg-accent/10 border-accent/20 text-accent`}`,children:[_.type===`success`?(0,i.jsx)(t.Ni,{className:`w-5 h-5 shrink-0`}):(0,i.jsx)(t.Pi,{className:`w-5 h-5 shrink-0`}),(0,i.jsx)(`span`,{className:`text-[14px] font-semibold tracking-wide leading-relaxed`,children:_.text})]})}),(0,i.jsx)(`form`,{onSubmit:async r=>{if(r.preventDefault(),e){g(!0),v(null);try{l!==e.displayName&&await(0,a.updateProfile)(e,{displayName:l});let r=!1;if(d!==e.email){let n=await(0,a.fetchSignInMethodsForEmail)(t.Ea,d);if(n&&n.length>0)throw Error(`An account with this email already exists.`);await(0,a.verifyBeforeUpdateEmail)(e,d),r=!0}if(y){let t=he(y);if(t)throw Error(t);let n=ge(y,x);if(n)throw w(n),Error(n);await(0,a.updatePassword)(e,y),b(``),S(``),w(``)}await n(),v(r?{text:`Profile updated. A verification link has been sent to your new email address.`,type:`success`}:{text:`Profile successfully updated.`,type:`success`})}catch(e){console.error(e),e.code===`auth/requires-recent-login`?v({text:`For security, please sign out and sign back in before changing your email or password.`,type:`error`}):v({text:e.message||`Failed to update profile.`,type:`error`})}finally{g(!1)}}},className:`w-full flex flex-col`,children:(0,i.jsxs)(`div`,{className:`glass-panel w-full p-5 sm:p-8 md:p-12 rounded-3xl border border-[var(--panel-border)] shadow-2xl space-y-8 md:min-h-[500px]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-4 sm:gap-5 pb-6 border-b border-[var(--panel-border)]/50`,children:[(0,i.jsxs)(`div`,{...F,className:`relative shrink-0 group/avatar rounded-full transition-shadow ${P?`ring-2 ring-accent ring-offset-2 ring-offset-background`:``}`,children:[(0,i.jsxs)(`div`,{className:`w-16 h-16 sm:w-20 sm:h-20 rounded-full glass-panel border-2 border-[var(--panel-border)] shadow-lg bg-accent/10 flex items-center justify-center relative overflow-hidden`,children:[(D||p&&k&&!T)&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center bg-accent/5 backdrop-blur-sm z-10`,children:(0,i.jsx)(t.ti,{className:`w-6 h-6 text-accent animate-spin`})}),p&&!T?(0,i.jsx)(`img`,{src:p,alt:`Avatar`,className:`w-full h-full object-cover transition-opacity duration-300 ${k?`opacity-0`:`opacity-100`}`,onLoad:()=>A(!1),onError:()=>{E(!0),A(!1)}}):(0,i.jsx)(t.Sr,{className:`w-7 h-7 sm:w-8 sm:h-8 text-accent`})]}),!D&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`label`,{title:p?`Change photo`:`Upload photo`,className:`absolute inset-0 rounded-full bg-background/60 backdrop-blur-[2px] opacity-0 group-hover/avatar:opacity-100 focus-within:opacity-100 flex items-center justify-center cursor-pointer transition-opacity z-20`,children:[(0,i.jsx)(t.Bi,{className:`w-4 h-4 text-foreground`}),(0,i.jsx)(`input`,{type:`file`,accept:`image/*`,"aria-label":`Upload photo`,onChange:N,className:`hidden`})]}),p&&(0,i.jsx)(`button`,{type:`button`,onClick:I,title:`Remove photo`,"aria-label":`Remove photo`,className:`hidden group-hover/avatar:flex absolute -top-1 -right-1 w-6 h-6 rounded-full bg-background border border-[var(--panel-border)] text-foreground/50 hover:text-red-500 hover:border-red-500/40 items-center justify-center shadow-sm cursor-pointer z-30`,children:(0,i.jsx)(t.Or,{className:`w-3 h-3`})})]})]}),(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h3`,{className:`font-extrabold text-lg sm:text-xl text-foreground mb-1 truncate`,children:l||`User`}),(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/40 mt-1 font-medium break-words`,children:e?.email})]})]}),(0,i.jsxs)(`div`,{className:`space-y-6`,children:[(0,i.jsx)(`h3`,{className:`text-[16px] font-extrabold text-foreground flex items-center gap-2`,children:`Account Details`}),(0,i.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-5 md:gap-6`,children:[(0,i.jsx)(t.lr,{name:`name`,value:l,onChange:e=>u(e.target.value),label:`Display Name`,placeholder:`John Doe`}),(0,i.jsxs)(`div`,{className:`flex flex-col`,children:[(0,i.jsx)(t.lr,{name:`email`,type:`email`,value:d,onChange:e=>f(e.target.value),label:`Email Address`,placeholder:`name@example.com`,required:!0}),(0,i.jsx)(`p`,{className:`text-[11px] text-foreground/40 mt-1.5 px-2 font-medium`,children:`Changing email sends a verification link to the new address.`})]})]})]}),(0,i.jsxs)(`div`,{className:`pt-6 border-t border-[var(--panel-border)]/50`,children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-bold text-foreground mb-4 flex items-center gap-2`,children:`Change Password`}),(0,i.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-5 md:gap-6`,children:[(0,i.jsx)(t.lr,{name:`password`,type:`password`,label:`New Password`,autoComplete:`new-password`,value:y,onChange:e=>{b(e.target.value),C&&e.target.value===x&&w(``)},placeholder:`At least 8 characters`}),(0,i.jsx)(t.lr,{name:`confirmPassword`,type:`password`,label:`Confirm New Password`,autoComplete:`new-password`,value:x,onChange:e=>{S(e.target.value),C&&w(``)},onBlur:()=>w(x?ge(y,x):``),error:C,placeholder:`Type it a second time`})]}),y&&(0,i.jsx)(_e,{value:y,className:`mt-3`})]}),(0,i.jsx)(`div`,{className:`pt-6 md:pt-8 border-t border-[var(--panel-border)]/50 flex justify-start w-full`,children:(0,i.jsx)(t.cr,{type:`submit`,isLoading:h,className:`w-full sm:w-auto sm:px-12 py-3 md:py-2.5 text-[14px] md:text-[15px] font-bold tracking-wide rounded-xl hover:-translate-y-0.5`,children:`Save Changes`})})]})})]})]})}function Le(){let[e,n]=(0,r.useState)(!1),[o,s]=(0,r.useState)(null),[l,u]=(0,r.useState)(0),[d,f]=(0,r.useState)(0);return(0,r.useEffect)(()=>{let e;return l>0&&(e=setInterval(()=>u(e=>e-1),1e3)),()=>clearInterval(e)},[l]),(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mb-16 mt-6 md:mt-0 md:mb-0 md:pt-8 md:pb-32`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.5},className:`w-full max-w-[480px] p-6 md:p-8 lg:p-10 rounded-3xl glass-panel relative glow-hover shadow-[0_8px_32px_rgba(0,0,0,0.08)] text-center`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-40 blur-[15px] rounded-3xl -z-10`}),(0,i.jsx)(`div`,{className:`w-14 h-14 md:w-16 md:h-16 rounded-2xl glass-panel border border-[var(--panel-border)] flex items-center justify-center mx-auto mb-5 md:mb-6 animate-float shadow-xl`,children:(0,i.jsx)(t.li,{className:`w-7 h-7 md:w-8 md:h-8 text-accent opacity-90`})}),(0,i.jsxs)(`div`,{className:`mb-6 text-center`,children:[(0,i.jsx)(`h3`,{className:`text-2xl md:text-3xl font-extrabold mb-2 md:mb-3 text-foreground tracking-tight`,children:`Reset Password`}),(0,i.jsx)(`p`,{className:`text-[14px] md:text-[15px] font-medium text-foreground/60 tracking-wide`,children:`Enter your email to receive a recovery link.`})]}),o&&(0,i.jsx)(`div`,{className:`p-3 md:p-4 mb-5 md:mb-6 text-[13px] md:text-[14px] font-medium text-emerald-400 bg-emerald-500/10 rounded-xl border border-emerald-500/20 max-w-[360px] mx-auto`,children:o}),(0,i.jsxs)(`form`,{className:`space-y-4 text-left max-w-[360px] mx-auto`,onSubmit:async e=>{e.preventDefault(),n(!0),s(null);let r=new FormData(e.currentTarget).get(`email`);try{await(0,a.sendPasswordResetEmail)(t.Ea,r)}catch(e){console.error(e)}finally{s(`If an account exists, a reset link has been sent. Check your inbox and spam folder.`);let e=d+1;f(e),u(e===1?60:120),n(!1)}},children:[(0,i.jsx)(t.lr,{name:`email`,label:`Work Email`,type:`email`,placeholder:`name@company.com`,required:!0}),(0,i.jsx)(`div`,{className:`pt-2`,children:(0,i.jsx)(t.cr,{type:`submit`,className:`w-full py-2.5 md:py-3 text-[14px] font-bold tracking-wide rounded-xl transition-all ${l>0?`opacity-60 shadow-none cursor-not-allowed pointer-events-none hover:translate-y-0`:`hover:-translate-y-0.5`}`,isLoading:e,disabled:l>0,children:l>0?`Resend link in ${(e=>`${Math.floor(e/60)}:${(e%60).toString().padStart(2,`0`)}`)(l)}`:d>0?`Resend reset password link`:`Send Reset Link`})})]}),(0,i.jsx)(`div`,{className:`mt-6 pt-5 border-t border-[var(--panel-border)] space-y-4 text-center`,children:(0,i.jsxs)(c.Link,{to:`/login`,className:`inline-flex items-center text-[13px] md:text-[14px] text-foreground/70 font-medium hover:text-accent transition-colors tracking-wide`,children:[(0,i.jsx)(t.Zi,{className:`w-4 h-4 mr-2`}),`Back to Sign In`]})})]})})}var Re=`(max-width: 767px)`,ze=()=>typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(Re).matches;function Be(){let[e,t]=(0,r.useState)(ze);return(0,r.useEffect)(()=>{if(typeof window>`u`||typeof window.matchMedia!=`function`)return;let e=window.matchMedia(Re),n=()=>t(e.matches);return n(),e.addEventListener?.(`change`,n),()=>e.removeEventListener?.(`change`,n)},[]),e}function Ve({isOpen:e,title:n,message:r,confirmText:a=`Delete`,cancelText:o=`Cancel`,onConfirm:s,onCancel:c,isProcessing:l=!1,disableConfirm:u=!1}){return(0,i.jsx)(t.pr,{children:e&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>!l&&c(),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/80 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`w-full max-w-[400px] p-6 rounded-3xl glass-popover border border-[var(--panel-border)] shadow-2xl relative z-10 text-center`,children:(0,i.jsxs)(`div`,{className:`w-full flex flex-col items-center`,children:[(0,i.jsx)(`h3`,{className:`text-xl font-extrabold mb-2 text-foreground tracking-tight`,children:n}),(0,i.jsx)(`p`,{className:`w-full text-[14px] font-medium text-foreground/60 leading-relaxed mb-6 break-words`,children:r}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3 w-full`,children:[(0,i.jsx)(t.cr,{variant:`secondary`,onClick:c,disabled:l,className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl`,children:o}),(0,i.jsx)(t.cr,{onClick:s,disabled:l||u,className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl bg-red-500 hover:bg-red-600 border-none text-white shadow-xl hover:shadow-red-500/20 glow-hover`,children:l?(0,i.jsx)(t.ti,{className:`w-5 h-5 animate-spin mx-auto`}):a})]})]})})]})})}var He=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).replace(/([A-Z])([A-Z][a-z])/g,`$1-$2`).toLowerCase(),Ue=(()=>{let e=t.hr,n=e?Object.keys(e):[];return n.length===0&&(n=Object.keys(t.mr).filter(e=>/^[A-Z]/.test(e)&&!/Icon$/.test(e)&&!/^Lucide/.test(e)&&e!==`IconNode`)),Array.from(new Set(n.map(He))).sort()})(),We=`layers.house.layout-dashboard.list.table.kanban.calendar.clock.file-text.files.folder.hard-drive.upload.download.paperclip.book-open.notebook-pen.users.user.user-plus.contact.building.briefcase.handshake.mail.message-square.message-circle.send.inbox.bell.megaphone.phone.shopping-cart.package.truck.receipt.credit-card.banknote.wallet.tag.percent.chart-bar.chart-line.chart-pie.trending-up.target.gauge.activity.settings.sliders-horizontal.wrench.shield.lock.key.eye.search.star.heart.bookmark.flag.pin.map-pin.globe.circle-check.circle-alert.info.circle-question-mark.life-buoy.sparkles.zap.rocket.camera.image.video.music.mic.palette.pen-tool.scissors.stethoscope.graduation-cap.utensils.plane.car.dumbbell.leaf.sun.moon`.split(`.`),Ge={money:[`banknote`,`wallet`,`credit-card`,`coins`,`dollar-sign`,`receipt`],cash:[`banknote`,`coins`,`wallet`],payment:[`credit-card`,`banknote`,`receipt`],invoice:[`receipt`,`file-text`],price:[`tag`,`dollar-sign`,`receipt`],people:[`users`,`user`,`contact`],customer:[`users`,`contact`,`user-round`],client:[`users`,`contact`,`briefcase`],team:[`users`,`users-round`],staff:[`users`,`id-card`],chat:[`message-circle`,`message-square`,`messages-square`],message:[`message-circle`,`mail`,`send`],email:[`mail`,`send`,`inbox`],task:[`list-checks`,`square-check`,`clipboard-check`],todo:[`list-checks`,`square-check`],project:[`kanban`,`folder-kanban`,`briefcase`],board:[`kanban`,`layout-dashboard`],photo:[`image`,`camera`,`images`],picture:[`image`,`images`],document:[`file-text`,`files`,`file`],doc:[`file-text`,`file`],shop:[`shopping-cart`,`store`,`shopping-bag`],store:[`store`,`shopping-bag`,`shopping-cart`],order:[`shopping-cart`,`package`,`receipt`],delivery:[`truck`,`package`],home:[`house`,`house-heart`],booking:[`calendar-check`,`calendar`,`clock`],appointment:[`calendar-clock`,`calendar`,`clock`],schedule:[`calendar-days`,`calendar`,`clock`],event:[`calendar`,`party-popper`,`ticket`],report:[`chart-bar`,`chart-line`,`file-chart-column`],stats:[`chart-bar`,`chart-line`,`chart-pie`],analytics:[`chart-line`,`chart-bar`,`activity`],help:[`circle-question-mark`,`life-buoy`,`info`],support:[`life-buoy`,`headset`,`circle-question-mark`],idea:[`lightbulb`,`sparkles`],health:[`heart-pulse`,`stethoscope`,`activity`],food:[`utensils`,`chef-hat`,`pizza`],travel:[`plane`,`map`,`luggage`],location:[`map-pin`,`map`,`globe`],address:[`map-pin`,`house`],security:[`shield`,`lock`,`key`],password:[`key`,`lock`],settings:[`settings`,`sliders-horizontal`,`wrench`],file:[`file`,`file-text`,`files`,`folder`],upload:[`upload`,`cloud-upload`],video:[`video`,`film`,`clapperboard`],school:[`graduation-cap`,`book-open`,`school`],course:[`graduation-cap`,`book-open`],gym:[`dumbbell`,`activity`],garden:[`leaf`,`flower`,`sprout`],car:[`car`,`car-front`],pet:[`paw-print`,`dog`,`cat`],note:[`notebook-pen`,`sticky-note`,`pencil`],write:[`pencil`,`pen-tool`,`notebook-pen`],time:[`clock`,`timer`,`hourglass`],star:[`star`,`sparkles`],favourite:[`star`,`heart`,`bookmark`],favorite:[`star`,`heart`,`bookmark`],album:[`images`,`image`,`camera`],gallery:[`images`,`image`,`camera`],profile:[`circle-user`,`user-round`,`id-card`],account:[`circle-user`,`user-round`,`id-card`],member:[`users`,`user-round`,`id-card`],membership:[`id-card`,`users`,`award`],subscription:[`credit-card`,`repeat`,`wallet`],plan:[`clipboard-list`,`layout-list`,`credit-card`],ticket:[`ticket`,`tickets`,`inbox`],request:[`inbox`,`send`,`file-text`],progress:[`trending-up`,`gauge`,`activity`],result:[`chart-bar`,`clipboard-check`,`trophy`],score:[`trophy`,`target`,`star`],library:[`library`,`book-open`,`folder`],lesson:[`graduation-cap`,`book-open`],session:[`calendar-clock`,`clock`,`video`],service:[`wrench`,`handshake`,`briefcase`],statement:[`file-text`,`receipt`,`banknote`],saved:[`bookmark`,`heart`,`star`],list:[`list`,`list-checks`,`layout-list`],detail:[`file-text`,`info`],referral:[`user-plus`,`share`,`gift`],reward:[`gift`,`trophy`,`award`],badge:[`award`,`badge`,`medal`],certificate:[`award`,`file-badge`,`scroll`],download:[`download`,`cloud-download`],history:[`history`,`clock`,`rotate-ccw`],feedback:[`message-square`,`star`,`thumbs-up`],review:[`star`,`message-square`],wishlist:[`heart`,`bookmark`,`star`],cart:[`shopping-cart`,`shopping-bag`],credit:[`coins`,`wallet`,`credit-card`],dashboard:[`layout-dashboard`,`gauge`],welcome:[`hand`,`house`,`sparkles`],onboarding:[`rocket`,`list-checks`,`user-plus`],benefit:[`gift`,`sparkles`,`award`],perk:[`gift`,`sparkles`],resource:[`folder`,`book-open`,`files`],guide:[`book-open`,`compass`,`map`],faq:[`circle-question-mark`,`message-circle`],contract:[`file-pen`,`file-text`,`scroll`],agreement:[`handshake`,`file-pen`],quote:[`file-text`,`receipt`,`tag`],enquiry:[`message-square`,`mail`],inquiry:[`message-square`,`mail`],application:[`file-text`,`clipboard-list`,`send`],form:[`clipboard-list`,`file-text`],submission:[`inbox`,`send`,`file-text`],record:[`folder`,`file-text`,`database`],log:[`history`,`list`,`file-text`]},Ke=new Set([`my`,`our`,`your`,`their`,`the`,`a`,`an`,`all`,`new`,`page`,`pages`,`of`,`and`,`for`,`to`,`in`,`on`,`at`,`is`,`it`,`this`,`that`]),qe=(e,t)=>{if(Math.abs(e.length-t.length)>2)return 3;let n=Array.from({length:t.length+1},(e,t)=>t);for(let r=1;r<=e.length;r++){let i=n[0];n[0]=r;for(let a=1;a<=t.length;a++){let o=n[a];n[a]=Math.min(n[a]+1,n[a-1]+1,i+(e[r-1]===t[a-1]?0:1)),i=o}}return n[t.length]},Je=(e,t)=>{let n=0;for(let r of t)r===e[n]&&n++;return n===e.length};function Ye(e,t=96,n=Ue){let r=e.trim().toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``);if(!r)return[];let i=r.split(`-`).filter(Boolean),a=new Set(n),o=new Map,s=(e,t)=>{a.has(e)&&o.set(e,Math.max(o.get(e)||0,t))};for(let e of n){let t=e.split(`-`);if(e===r){s(e,100);continue}if(e.startsWith(r)){s(e,90);continue}if(t.some(e=>e===r)){s(e,85);continue}if(t.some(e=>e.startsWith(r))){s(e,75);continue}if(e.includes(r)){s(e,65);continue}if(i.length>1&&i.every(e=>t.some(t=>t.startsWith(e)))){s(e,60);continue}}let c=e=>{(Ge[e]||[]).forEach((e,t)=>s(e,74-t)),e.endsWith(`s`)&&(Ge[e.slice(0,-1)]||[]).forEach((e,t)=>s(e,74-t))};for(let e of i)c(e);if(o.size===0&&i.length>1)for(let e of[...i].reverse()){if(Ke.has(e)||e.length<3)continue;let r=Ye(e,t,n);if(r.length)return r}if(o.size===0&&r.length>=3)for(let e of n)e.split(`-`).some(e=>qe(r,e)<=(r.length>5?2:1))?s(e,40):r.length>=4&&Je(r,e.replace(/-/g,``))&&s(e,20);let l=e=>{let t=We.indexOf(e);return t===-1?We.length:t};return Array.from(o.entries()).sort((e,t)=>t[1]-e[1]||l(e[0])-l(t[0])||e[0].length-t[0].length||e[0].localeCompare(t[0])).slice(0,t).map(([e])=>e)}var Xe=/(<[A-Z][A-Za-z0-9]*(?:\s[^<>]*)?\/?>|src\/[A-Za-z0-9_./-]*[A-Za-z0-9_-]|'[A-Za-z0-9_@./-]+')/g,Ze=/(https?:\/\/[^\s]+)/g,Qe=e=>e.split(Ze).flatMap((e,t)=>t%2==1?[{text:e,kind:`value`}]:e.split(Xe).map((e,t)=>({text:e,kind:t%2==1?`code`:void 0}))).filter(e=>e.text),$e=/exactly: |Here is (?:what|how) [^:]*: |It should ask for: |Where the form belongs on the page: |a button that says /,et=e=>{let t=$e.exec(e);if(!t)return Qe(e);let n=t.index+t[0].length,r=e.slice(0,n),i=e.slice(n),a=i.indexOf(` — `);return[...Qe(r),{text:a===-1?i:i.slice(0,a),kind:`value`},...Qe(a===-1?``:i.slice(a))]},tt=`text-accent font-semibold bg-accent/[0.08] rounded-[4px] px-1 -mx-[1px] [overflow-wrap:anywhere]`,nt=`font-mono text-[0.92em] text-foreground/75 bg-foreground/[0.055] border border-[var(--panel-border)]/60 rounded-[4px] px-1 py-[1px] [overflow-wrap:anywhere]`;function rt({text:e}){return(0,i.jsx)(i.Fragment,{children:et(e).map((e,t)=>e.kind?(0,i.jsx)(`span`,{className:e.kind===`value`?tt:nt,children:e.text},t):(0,i.jsx)(r.default.Fragment,{children:e.text},t))})}function it({title:e=`Ask your assistant`,description:n,prompt:a,compact:o=!1,locked:s=!1,onCopied:c}){let[l,u]=(0,r.useState)(!1),d=a.includes(`
|
|
2
|
-
`);return s?null:(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 min-w-0 max-w-full rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)] ${o?`px-4 py-3.5`:`px-5 py-4`}`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-extrabold tracking-tight text-gradient`,children:e}),(0,i.jsxs)(`button`,{type:`button`,onClick:()=>{navigator.clipboard?.writeText(a),u(!0),setTimeout(()=>u(!1),2e3),c&&setTimeout(c,550)},"aria-label":l?`Copied`:`Copy`,className:`inline-flex items-center justify-center gap-1.5 h-8 w-8 px-0 sm:w-auto sm:px-3 rounded-[var(--btn-radius,0.75rem)] text-[12px] font-semibold shrink-0 border ${l?`copy-btn-done border-emerald-500/30 bg-emerald-500/10 text-emerald-500 cursor-pointer`:`copy-btn cursor-pointer`}`,children:[l?(0,i.jsx)(t.
|
|
3
|
-
`).filter(e=>e.trim()).map((e,t)=>(0,i.jsx)(`p`,{className:`min-w-0`,children:(0,i.jsx)(rt,{text:e})},t))}):(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`“`,(0,i.jsx)(rt,{text:a}),`”`]})})]})}var at=`w-11 h-11 shrink-0 rounded-[var(--input-radius,0.75rem)] overflow-hidden border border-[var(--panel-border)]`,ot=e=>{try{return(decodeURIComponent(new URL(e).pathname).split(`/`).pop()||``).replace(/^\d{10,}_/,``)||`Your picture`}catch{return`Your picture`}};function st({label:e,hint:n,value:a,onChange:o,accept:s=`image/*`,action:c,clearable:l=!0,tips:u,onBusyChange:d}){let{user:f}=t.na(),[p,m]=(0,r.useState)(!1),[h,g]=(0,r.useState)(``),[_,v]=(0,r.useState)(!1),[y,b]=(0,r.useState)(!1),x=async e=>{if(!p){m(!0),d?.(!0),g(``);try{o(await t.ar(e,f))}catch(e){g(t.ir(e))}m(!1),d?.(!1),b(!1)}},S=e=>{let t=e.target.files?.[0];e.target.value=``,t&&x(t)},{over:C,dropProps:w}=t.er({accept:s,disabled:p,onFiles:([e])=>x(e),onReject:()=>g(s.startsWith(`image`)?`That is not a picture — drop a JPG or a PNG.`:`That kind of file does not go here.`)}),T=(0,i.jsx)(`input`,{type:`file`,accept:s,"aria-label":a?`Replace ${e}`:`Upload ${e}`,disabled:p,onChange:S,className:`sr-only`});return(0,i.jsxs)(t.Z,{label:e,hint:n,error:h,action:c,children:[(0,i.jsx)(`div`,{...w,className:`min-w-0`,children:a&&!p?(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`div`,{className:`${t.tt} min-w-0 ${C?`border-accent bg-accent/[0.04]`:``}`,children:(0,i.jsx)(`span`,{className:`flex-1 min-w-0 truncate text-[14px] select-none ${C?`text-accent`:`text-foreground/60`}`,children:C?`Drop it to replace this one`:ot(a)})}),(0,i.jsxs)(`div`,{className:`${at} relative group/pic`,children:[(0,i.jsx)(`button`,{type:`button`,onClick:()=>b(e=>!e),"aria-label":`Change ${e}`,"aria-expanded":y,className:`block w-full h-full cursor-pointer`,children:(0,i.jsx)(`img`,{src:a,alt:e,className:`w-full h-full object-cover`})}),(0,i.jsxs)(`div`,{className:`absolute inset-0 flex items-center justify-center gap-1 bg-background/85 transition-opacity duration-200 ${y?`opacity-100`:`opacity-0 pointer-events-none group-hover/pic:opacity-100 group-hover/pic:pointer-events-auto focus-within:opacity-100 focus-within:pointer-events-auto`}`,children:[(0,i.jsxs)(`label`,{title:`Replace ${e}`,className:`w-6 h-6 rounded-md flex items-center justify-center text-foreground/60 hover:text-accent hover:bg-foreground/10 transition-colors cursor-pointer`,children:[(0,i.jsx)(t.Di,{className:`w-3.5 h-3.5`}),T]}),l&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>{g(``),b(!1),o(``)},"aria-label":`Remove ${e}`,title:`Remove ${e}`,className:`w-6 h-6 rounded-md flex items-center justify-center text-foreground/60 hover:text-red-500 hover:bg-red-500/10 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-3.5 h-3.5`})})]})]})]}):(0,i.jsxs)(`label`,{title:`Upload ${e}`,className:`group/up flex items-center gap-2 ${p?`pointer-events-none`:`cursor-pointer`}`,children:[(0,i.jsx)(`span`,{className:`${t.tt} select-none text-[14px] truncate ${C?`border-accent bg-accent/[0.04] text-accent`:p?`text-foreground/50`:`text-foreground/35`} group-hover/up:border-accent/40 group-focus-within/up:border-accent`,children:C?`Drop it here`:p?`Uploading your picture…`:`Upload a picture, or drop one here`}),(0,i.jsx)(`span`,{"aria-hidden":!0,className:`${at} flex items-center justify-center bg-[var(--panel-bg)] ${C?`text-accent border-accent`:`text-foreground/40`} group-hover/up:text-accent group-hover/up:border-accent/40 transition-colors`,children:p?(0,i.jsx)(t.ti,{className:`w-4 h-4 animate-spin text-accent`}):(0,i.jsx)(t.Di,{className:`w-4 h-4`})}),T]})}),!!u?.length&&(0,i.jsxs)(`div`,{className:`mt-2 px-1`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:()=>v(e=>!e),"aria-expanded":_,className:`inline-flex items-center gap-1 text-[11.5px] font-semibold text-foreground/40 hover:text-foreground/70 transition-colors cursor-pointer`,children:[(0,i.jsx)(t.Ii,{className:`w-3 h-3 shrink-0 transition-transform duration-200 ${_?`rotate-90`:``}`}),`Which picture should I upload?`]}),_&&(0,i.jsx)(`ul`,{className:`flex flex-col gap-1 mt-1.5 ml-4`,children:u.map(e=>(0,i.jsxs)(`li`,{className:`text-[11.5px] text-foreground/40 font-medium leading-snug flex gap-1.5`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`text-accent/60`,children:`•`}),e]},e))})]})]})}var ct=[`A wide picture sits best across a page — about 1600 by 900.`,`JPG or PNG. Any size — a big photo is shrunk for you as it uploads, so the page still opens quickly.`,`Your own photo beats a stock one. People can tell.`,`No writing baked into the picture — your assistant sets the words, so they stay readable on a phone.`],lt=[`A wide picture, not a square one — it sits in a short bar about 40px tall.`,`PNG with a see-through background looks right on both the light and the dark theme.`],ut=[`A square picture — 64 by 64 is plenty.`,`One shape or one letter. A whole logo turns to mush at this size.`],dt=`sys_roles`,ft=(e,t)=>({id:e,name:String(t?.name||e),...typeof t?.createdAt==`number`?{createdAt:t.createdAt}:{}}),pt=(e,t)=>e.name.localeCompare(t.name),mt=[],ht=e=>{mt=e},gt=()=>mt,_t=(e,t=gt())=>t.find(t=>t.id===e)?.name||e;function vt(e,n=gt()){let r=String(e||``).trim();if(!r)return`Type a name for the role first — Client, say, or Supplier.`;let i=t.ba(r);return i.length<2||!/^[a-z]/.test(i)?`Use a name with at least two letters in it.`:t.oa.has(i)||!t.ma(i)?`${r} is a word the app already uses. Pick another.`:n.some(e=>e.id===i)?`You already have a role called ${n.find(e=>e.id===i).name}.`:``}async function yt(e){let n=String(e||``).trim().slice(0,48),r={id:t.ba(n),name:n,createdAt:Date.now()};return await(0,o.setDoc)((0,o.doc)(t.Da,dt,r.id),{name:r.name,createdAt:r.createdAt}),r}async function bt(e,n){let r=String(n||``).trim().slice(0,48);!t.ma(e)||!r||await(0,o.setDoc)((0,o.doc)(t.Da,dt,e),{name:r},{merge:!0})}function xt(e,t,n=gt()){let r=String(t||``).trim();if(!r)return`A role needs a name.`;let i=n.find(t=>t.id!==e&&t.name.trim().toLowerCase()===r.toLowerCase());return i?`You already have a role called ${i.name}.`:``}async function St(e){let n={people:[],pages:[]};return t.ma(e)?((await(0,o.getDocs)((0,o.query)((0,o.collection)(t.Da,`user_profiles`),(0,o.where)(`role`,`==`,e)))).forEach(e=>n.people.push(e.id)),(await(0,o.getDocs)((0,o.collection)(t.Da,`sys_tabs`))).forEach(r=>{t.ca(r.data()?.roles).includes(e)&&n.pages.push(r.id)}),n):n}async function Ct(e){if(!t.ma(e))return;let n=await(0,o.getDocs)((0,o.query)((0,o.collection)(t.Da,`user_profiles`),(0,o.where)(`role`,`==`,e)));for(let e of n.docs)await(0,o.updateDoc)((0,o.doc)(t.Da,`user_profiles`,e.id),{role:t.ya(`free`)});let r=await(0,o.getDocs)((0,o.collection)(t.Da,`sys_tabs`));for(let n of r.docs){let r=t.ca(n.data()?.roles);if(!r.includes(e))continue;let i=r.filter(t=>t!==e);await(0,o.setDoc)((0,o.doc)(t.Da,`sys_tabs`,n.id),{roles:i.length?i:[`user`]},{merge:!0})}await(0,o.deleteDoc)((0,o.doc)(t.Da,dt,e))}function wt(){let[e,n]=(0,r.useState)(()=>gt());return(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.collection)(t.Da,dt),e=>{let t=[];e.forEach(e=>t.push(ft(e.id,e.data()))),t.sort(pt),ht(t),n(t)},()=>{}),[]),e}function Tt({roles:e}){let[n,a]=(0,r.useState)(``),[o,s]=(0,r.useState)(``),[c,l]=(0,r.useState)(``),[u,d]=(0,r.useState)(``),[f,p]=(0,r.useState)(null);if(!e.length)return null;let m=async t=>{let n=xt(t.id,o,e);if(n){l(n);return}d(t.id);try{await bt(t.id,o),a(``),l(``)}catch(e){l(e?.message||`The new name could not be saved. Try again.`)}d(``)},h=async e=>{d(e.id);try{p({role:e,standing:await St(e.id)})}catch{p({role:e,standing:{people:[],pages:[]}})}d(``)};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`div`,{className:`border-t border-[var(--panel-border)] p-4 sm:p-6 flex flex-col gap-4`,children:[(0,i.jsx)(t.ot,{icon:t.kr,title:`Your own roles`,description:`The words you mark people with. Renaming one changes it everywhere; nobody is unmarked.`}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.map(e=>(0,i.jsx)(`div`,{className:`rounded-2xl glass-panel border border-[var(--panel-border)] px-3.5 py-2.5 flex items-center gap-2.5`,children:n===e.id?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`input`,{autoFocus:!0,value:o,disabled:u===e.id,"aria-label":`Rename ${e.name}`,onChange:e=>{s(e.target.value),c&&l(``)},onKeyDown:t=>{t.key===`Enter`&&(t.preventDefault(),m(e)),t.key===`Escape`&&(t.preventDefault(),a(``),l(``))},className:`${t.et} flex-1 min-w-0`}),(0,i.jsx)(t.Q,{icon:t.zi,compact:!0,busy:u===e.id,title:`Save ${o||e.name}`,onClick:()=>m(e),children:`Save`}),(0,i.jsx)(t.Q,{icon:t._r,compact:!0,title:`Keep the name`,onClick:()=>{a(``),l(``)},children:`Cancel`})]}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`span`,{className:`flex-1 min-w-0 text-[13.5px] font-bold text-foreground truncate`,children:e.name}),(0,i.jsx)(t.Q,{icon:t.Gr,compact:!0,title:`Rename ${e.name}`,onClick:()=>{a(e.id),s(e.name),l(``)},children:`Rename`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,busy:u===e.id,title:`Remove ${e.name}`,onClick:()=>h(e),children:`Remove`})]})},e.id)),!!c&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:c}),(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Make a new role on the Pages screen, on the row of the page you want to keep for it.`})]})]}),(0,i.jsx)(Ve,{isOpen:!!f,title:f?`Remove ${f.role.name}?`:``,message:f?Et(f.standing):``,confirmText:`Yes, remove it`,cancelText:`Keep it`,isProcessing:u===`removing`,onCancel:()=>p(null),onConfirm:async()=>{if(f){d(`removing`);try{await Ct(f.role.id),p(null)}catch(e){l(e?.message||`The role could not be removed. Try again.`),p(null)}d(``)}}})]})}function Et(e){let t=e.people.length,n=e.pages.length,r=[];return t&&r.push(`${t} ${t===1?`person goes`:`people go`} back to being ${t===1?`a member`:`members`}`),n&&r.push(`${n} ${n===1?`page goes`:`pages go`} back to everybody signed in`),`${r.length?`${r.join(`, and `)}. `:`Nobody is marked with it and no page is kept for it. `}Whatever those pages have saved stays exactly where it is — you and your admins can still read it — but nobody else will, and the word itself is gone from every list.`}function Dt(){let{user:e,userRole:n}=t.na(),a=wt(),[l,u]=(0,r.useState)(!0),d=(0,c.useNavigate)(),{id:f}=(0,c.useParams)(),p=Be(),[m,h]=(0,r.useState)([]),[g,_]=(0,r.useState)(null),[v,y]=(0,r.useState)(!1),[b,x]=(0,r.useState)(``),[S,C]=(0,r.useState)(!1),w=f?m.find(e=>e.id===f)||null:m.length>0?m[0]:null,T=e=>{d(e?`/users/${e.id}`:`/users`)};(0,r.useEffect)(()=>{u(!0);let e=(0,o.onSnapshot)((0,o.collection)(t.Da,`user_profiles`),e=>{let t=[];e.forEach(e=>{t.push({id:e.id,...e.data()})}),h(t),u(!1),!f&&t.length>0&&!ze()&&d(`/users/${t[0].id}`,{replace:!0})},e=>{console.error(`Error fetching users:`,e),u(!1)});return()=>e()},[f,d]);let E=m.find(t=>t.id===e?.uid),D=e=>e.id===E?.id?!1:e.role!==`admin`||!E?.createdAt?!0:e.createdAt?new Date(E.createdAt).getTime()<=new Date(e.createdAt).getTime():!1,O=[...t.ra.map(e=>({value:t.ya(e),label:t.ia[e]})),...a.map(e=>({value:e.id,label:e.name}))],k=e=>t.da(e.role)||t.ya(t.ha(e.role)),A=e=>{let n=t.da(e.role);return n?_t(n,a):t.ia[t.ha(e.role)]},j=async(e,r,i)=>{if(!(n!==`admin`||!D(e))&&k(e)!==r)try{await(0,o.updateDoc)((0,o.doc)(t.Da,`user_profiles`,e.id),{role:r}),_({text:`Access level set to ${i}`,type:`success`}),setTimeout(()=>_(null),3e3)}catch(e){_({text:e.message,type:`error`}),setTimeout(()=>_(null),3e3)}},M=async(e,r)=>{if(!(n!==`admin`||!D(e)))try{await(0,o.updateDoc)((0,o.doc)(t.Da,`user_profiles`,e.id),{inactive:r}),_({text:`User ${r?`deactivated`:`activated`} successfully`,type:`success`}),setTimeout(()=>_(null),3e3)}catch(e){_({text:e.message,type:`error`}),setTimeout(()=>_(null),3e3)}},N=async()=>{if(y(!1),!(!w||!D(w)||b===w.displayName))try{await(0,o.updateDoc)((0,o.doc)(t.Da,`user_profiles`,w.id),{displayName:b}),_({text:`Name updated successfully`,type:`success`}),setTimeout(()=>_(null),3e3)}catch(e){_({text:e.message,type:`error`}),setTimeout(()=>_(null),3e3)}},P=async e=>{if(!w||!D(w))return;let n=await t.or(e,{maxSide:512});if(n.size>2*1024*1024){_({text:`File too large. Please select an image under 2MB.`,type:`error`});return}C(!0);try{let e=(0,s.ref)(t.ka,`user_avatars/${w.id}/file.png`);await(0,s.uploadBytes)(e,n);let r=await(0,s.getDownloadURL)(e);h(e=>e.map(e=>e.id===w.id?{...e,avatar:r}:e)),await(0,o.updateDoc)((0,o.doc)(t.Da,`user_profiles`,w.id),{avatar:r}),_({text:`Avatar successfully updated.`,type:`success`}),setTimeout(()=>_(null),3e3)}catch{_({text:`Failed to upload photo.`,type:`error`})}C(!1)},F=e=>{let t=e.target.files?.[0];t&&P(t)},{over:I,dropProps:L}=t.er({accept:`image/*`,disabled:S||!w||!D(w),onFiles:([e])=>P(e),onReject:()=>_({text:`That is not a picture. Drop a JPG or a PNG.`,type:`error`})}),[R,z]=(0,r.useState)(!1);if((0,r.useEffect)(()=>{let e;return l&&m.length===0?e=setTimeout(()=>z(!0),150):z(!1),()=>clearTimeout(e)},[l,m.length]),l&&m.length===0)return R?(0,i.jsx)(`div`,{className:`fixed inset-0 z-[100] flex items-center justify-center bg-background/60 backdrop-blur-xl transition-all duration-300`,children:(0,i.jsx)(t.ti,{className:`w-8 h-8 animate-spin text-accent`})}):null;let B=p&&!!f,V=!B,H=!p||!!f;return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto z-10 flex flex-col min-h-screen p-4 pt-2 md:p-8 md:pt-4`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-8`,children:[(0,i.jsx)(Ce,{children:`Users`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/users`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col animate-in fade-in duration-500 gap-6 ${B?`flex-1 pb-6`:`pb-20`}`,children:[(0,i.jsx)(t.pr,{children:g&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},exit:{opacity:0,y:-10},className:`p-4 text-[14px] font-medium border rounded-xl ${g.type===`error`?`text-red-500 bg-red-500/10 border-red-500/20 shadow-[0_0_15px_rgba(239,68,68,0.1)]`:`text-emerald-400 bg-emerald-500/10 border-emerald-500/20 shadow-[0_0_15px_rgba(52,211,153,0.1)]`} flex items-center gap-2`,children:[g.type===`success`&&(0,i.jsx)(t.Ni,{className:`w-4 h-4 shrink-0`}),g.text]})}),(0,i.jsx)(`div`,{className:`flex justify-start`,children:(0,i.jsx)(Fe,{})}),(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] bg-[var(--panel-bg)] overflow-hidden rounded-3xl shadow-2xl ${B?`flex-1 flex flex-col`:``}`,children:[m.length===0?(0,i.jsx)(`div`,{className:`p-8 text-center text-foreground/50 text-[14px]`,children:`No members found.`}):(0,i.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 md:min-h-[500px] ${B?`flex-1`:``}`,children:[V&&(0,i.jsxs)(`div`,{className:`flex md:col-span-1 border-r md:border-r-[var(--panel-border)] border-b md:border-b-0 border-[var(--panel-border)] flex-col hide-scrollbar bg-foreground/[0.03] rounded-t-3xl md:rounded-tr-none md:rounded-l-3xl`,children:[(0,i.jsx)(`div`,{className:`p-4 border-b border-[var(--panel-border)] font-bold text-[13px] text-foreground/70 uppercase tracking-wider`,children:`System Users`}),(0,i.jsx)(`div`,{className:`flex-1 overflow-y-auto p-4 space-y-2 md:max-h-[520px]`,children:m.map(e=>(0,i.jsxs)(`div`,{onClick:()=>T(e),className:`p-3.5 rounded-2xl border transition-all flex items-center gap-3 cursor-pointer ${w?.id===e.id?`bg-foreground/[0.06] border-accent/40 shadow-sm`:`glass-panel border-[var(--panel-border)] hover:border-accent/40`} ${e.inactive?`opacity-50 grayscale`:``}`,children:[(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-full overflow-hidden bg-accent/10 shrink-0 flex items-center justify-center border border-accent/20 shadow-sm`,children:e.avatar||e.photoURL?(0,i.jsx)(`img`,{src:e.avatar||e.photoURL,alt:``,className:`w-full h-full object-cover`}):(0,i.jsx)(t.Sr,{className:`w-4 h-4 text-accent`})}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[14px] text-foreground truncate`,children:e.displayName||`No Name`}),(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/50 truncate font-medium mt-0.5`,children:e.email})]}),p&&(0,i.jsx)(t.Ii,{className:`w-4 h-4 text-foreground/25 shrink-0`})]},e.id))})]}),H&&(0,i.jsx)(`div`,{className:`flex md:col-span-2 flex-col relative ${B?`px-4 pt-4 pb-10`:`p-5 sm:p-6 md:p-10`}`,children:w?(0,i.jsxs)(`div`,{className:`animate-in fade-in duration-300 w-full max-w-lg`,children:[(0,i.jsxs)(`div`,{className:`flex flex-row items-center gap-3 sm:gap-6 md:gap-8 mb-8 sm:mb-10`,children:[B&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>T(null),"aria-label":`Back to all users`,className:`shrink-0 -ml-1.5 w-7 h-7 flex items-center justify-center rounded-lg text-foreground/40 hover:text-foreground active:bg-foreground/5 transition-colors cursor-pointer`,children:(0,i.jsx)(t.Zi,{className:`w-5 h-5`})}),(0,i.jsxs)(`div`,{...L,className:`relative shrink-0 group/avatar rounded-full transition-shadow ${I?`ring-2 ring-accent ring-offset-2 ring-offset-background`:``}`,children:[(0,i.jsx)(`div`,{className:`w-14 h-14 sm:w-24 sm:h-24 rounded-full glass-panel border-2 sm:border-4 border-[var(--panel-border)] shadow-lg sm:shadow-xl bg-accent/10 flex items-center justify-center overflow-hidden`,children:S?(0,i.jsx)(t.ti,{className:`w-5 h-5 sm:w-8 sm:h-8 text-accent animate-spin`}):w.avatar||w.photoURL?(0,i.jsx)(`img`,{src:w.avatar||w.photoURL,alt:`Avatar`,className:`w-full h-full object-cover`}):(0,i.jsx)(t.Sr,{className:`w-6 h-6 sm:w-10 sm:h-10 text-accent`})}),!S&&D(w)&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`label`,{title:`Change photo`,className:`max-sm:hidden sm:flex absolute -bottom-0.5 -right-0.5 w-9 h-9 rounded-full btn-primary text-white items-center justify-center cursor-pointer shadow-lg border-2 border-[var(--bg-color)] hover:scale-105 active:scale-95 transition-transform z-10`,children:[(0,i.jsx)(t.Bi,{className:`w-4 h-4`}),(0,i.jsx)(`input`,{type:`file`,accept:`image/*`,"aria-label":`Change photo`,onChange:F,className:`hidden`})]}),(0,i.jsxs)(`label`,{title:`Change photo`,className:`flex sm:hidden absolute inset-0 rounded-full bg-background/60 backdrop-blur-[2px] opacity-0 group-hover/avatar:opacity-100 focus-within:opacity-100 items-center justify-center cursor-pointer transition-opacity z-10`,children:[(0,i.jsx)(t.Bi,{className:`w-4 h-4 text-foreground`}),(0,i.jsx)(`input`,{type:`file`,accept:`image/*`,"aria-label":`Change photo`,onChange:F,className:`hidden`})]})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col flex-1 w-full min-w-0 relative`,children:[v?(0,i.jsx)(`input`,{autoFocus:!0,value:b,onChange:e=>x(e.target.value),onBlur:N,onKeyDown:e=>e.key===`Enter`&&N(),className:`text-xl sm:text-2xl md:text-3xl font-extrabold mb-1 bg-transparent border-b-2 border-accent outline-none text-foreground w-full py-1`}):(0,i.jsx)(`h3`,{onDoubleClick:()=>{D(w)&&(x(w.displayName||``),y(!0))},className:`text-xl sm:text-2xl md:text-3xl font-extrabold mb-1 select-none break-words ${D(w)?`cursor-pointer hover:text-accent transition-colors`:``}`,title:D(w)?`Double-click to edit`:``,children:w.displayName||`No Name`}),(0,i.jsx)(`p`,{className:`text-[13px] sm:text-[14px] font-mono text-foreground/50 break-all`,children:w.email}),(0,i.jsx)(`span`,{className:`mt-2 self-start inline-flex items-center h-6 px-2.5 rounded-full text-[11.5px] font-bold bg-accent/10 text-accent border border-accent/20`,children:A(w)}),!D(w)&&w.id!==E?.id&&(0,i.jsxs)(`p`,{className:`mt-2 flex items-center gap-1.5 text-[12px] font-medium text-foreground/45`,children:[(0,i.jsx)(t.ei,{className:`w-3 h-3 shrink-0`}),`Admin since before you, so only they can change this account.`]})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(`div`,{className:`p-4 rounded-2xl glass-panel border border-[var(--panel-border)] flex flex-col gap-3`,children:(0,i.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[14px] text-foreground`,children:`Access level`}),(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/50`,children:`What this person can open`})]}),(0,i.jsx)(`div`,{role:`radiogroup`,"aria-label":`Access level`,className:`flex items-center gap-1.5 flex-wrap ${D(w)?``:`opacity-50`}`,children:O.map(e=>{let t=k(w)===e.value;return(0,i.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":t,disabled:!D(w),onClick:()=>j(w,e.value,e.label),className:`h-8 px-3.5 rounded-full text-[12.5px] font-semibold border transition-all ${t?`bg-accent/10 border-accent/40 text-accent`:`border-[var(--panel-border)] text-foreground/55 hover:text-foreground hover:border-accent/30`} ${D(w)?`cursor-pointer`:`cursor-not-allowed`}`,children:e.label},e.value)})})]})}),(0,i.jsxs)(`div`,{className:`p-4 rounded-2xl glass-panel border flex items-center justify-between gap-3 ${w.inactive?`border-amber-500/30 bg-amber-500/5`:`border-red-500/20 bg-red-500/5`}`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[14px] ${w.inactive?`text-amber-500`:`text-red-500`}`,children:w.inactive?`Reactivate User`:`Deactivate User`}),(0,i.jsx)(`span`,{className:`text-[12px] ${w.inactive?`text-amber-500/70`:`text-red-500/70`}`,children:`Block access to this app`})]}),(0,i.jsx)(`button`,{type:`button`,disabled:!D(w),onClick:()=>M(w,!w.inactive),className:`relative inline-flex h-7 w-12 shrink-0 items-center rounded-full transition-colors focus:outline-none shadow-inner ${w.inactive?`bg-amber-500`:`bg-red-500/20`} ${D(w)?`cursor-pointer`:`opacity-50 cursor-not-allowed`}`,children:(0,i.jsx)(`span`,{className:`inline-block h-5 w-5 transform rounded-full bg-white transition-transform shadow-md ${w.inactive?`translate-x-6`:`translate-x-1`}`})})]})]})]}):(0,i.jsxs)(`div`,{className:`absolute inset-0 flex flex-col items-center justify-center opacity-30 pointer-events-none`,children:[(0,i.jsx)(t.xr,{className:`w-12 h-12 mb-4`}),(0,i.jsx)(`p`,{className:`font-bold tracking-widest uppercase text-[12px]`,children:`Select a User`})]})})]}),!B&&(0,i.jsx)(Tt,{roles:a})]})]})]})}var Ot={anyone:{collectionName:`user_submissions`,chip:`Anyone`,filterLabel:`From anyone`},signedIn:{collectionName:`user_requests`,chip:`Signed-in user`,filterLabel:`From signed-in users`}},kt=[`id`,`source`,`uid`,`submittedAt`,`avatarUrl`,`isArchived`,`name`,`full_name`,`email`,`contactEmail`,`topic`],At=e=>{let t=e.submittedAt;if(!t)return 0;if(typeof t.toMillis==`function`)return t.toMillis();if(typeof t.toDate==`function`)return t.toDate().getTime();let n=new Date(t).getTime();return Number.isNaN(n)?0:n},jt=e=>{if(!e)return`Just now`;let t=e.toDate?e.toDate():new Date(e);return new Intl.DateTimeFormat(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`numeric`}).format(t)},Mt=e=>{if(!e)return`now`;let t=e.toDate?e.toDate():new Date(e),n=new Date;return t.toDateString()===n.toDateString()?new Intl.DateTimeFormat(`en-US`,{hour:`numeric`,minute:`numeric`}).format(t):new Intl.DateTimeFormat(`en-US`,t.getFullYear()===n.getFullYear()?{month:`short`,day:`numeric`}:{month:`short`,year:`numeric`}).format(t)},Nt=e=>{let t=new Date(e);return new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()},Pt=e=>{let t=At(e);if(!t)return`Older`;let n=Math.round((Nt(Date.now())-Nt(t))/864e5);return n<=0?`Today`:n===1?`Yesterday`:n<7?`This week`:n<30?`This month`:`Older`},Ft=e=>e.reduce((e,t)=>{let n=Pt(t),r=e[e.length-1];return r&&r.label===n?r.items.push(t):e.push({label:n,items:[t]}),e},[]);function It({label:e}){return(0,i.jsxs)(`div`,{className:`md:hidden flex items-center gap-3 pt-1 first:pt-0 select-none`,children:[(0,i.jsx)(`span`,{className:`text-[10.5px] font-bold uppercase tracking-[0.18em] text-foreground/35 shrink-0`,children:e}),(0,i.jsx)(`span`,{className:`h-px flex-1 bg-[var(--panel-border)]/60`})]})}var Lt=e=>e.submitterName||e.name||e.full_name||`Anonymous`,Rt=e=>e.contactEmail||e.email||`No email provided`;function zt(e){let[n,i]=(0,r.useState)([]),[a,s]=(0,r.useState)(!0);return(0,r.useEffect)(()=>{let n=!1,r=Ot[e].collectionName,a=(0,o.onSnapshot)((0,o.query)((0,o.collection)(t.Da,r),(0,o.orderBy)(`submittedAt`,`desc`)),async r=>{let a=[];for(let n of r.docs){let r={...n.data()};if(r.formId===`booking`||t.on(r))continue;let i=``;if(r.uid&&r.uid!==`guest`)try{let e=await(0,o.getDoc)((0,o.doc)(t.Da,`user_profiles`,r.uid));if(e.exists()){let t=e.data();(t.avatar||t.photoURL)&&(i=t.avatar||t.photoURL),r.name||=t.name||t.displayName,r.email||=t.email,r.contactEmail||=t.email}}catch(e){console.error(`Failed to fetch profile`,e)}a.push({...r,id:n.id,source:e,avatarUrl:i})}n||(i(a),s(!1))},e=>{console.error(`Error loading ${r}:`,e),n||s(!1)});return()=>{n=!0,a()}},[e]),{items:n,loading:a}}function Bt({source:e}){return(0,i.jsx)(`span`,{className:`text-[10px] font-bold uppercase tracking-widest text-accent bg-accent/10 px-2 py-0.5 rounded-md border border-accent/20 shrink-0`,children:Ot[e].chip})}function Vt({item:e,isExpanded:n,onToggle:r,onArchive:a,onDelete:o,busy:s,dimmed:l}){let u=Lt(e),d=e.avatarUrl||e.submitterAvatar,f=!!e.uid&&e.uid!==`guest`,p=Object.entries(e).filter(([e])=>!kt.includes(e)&&!e.toLowerCase().startsWith(`submitter`)&&e.toLowerCase()!==`formid`),m=e.topic?[[`topic`,e.topic],...p]:p;return(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`glass-panel border border-[var(--panel-border)] rounded-2xl flex flex-col overflow-hidden hover:border-accent/40 transition-all duration-300 ${l?`opacity-60 hover:opacity-100`:``}`,children:[(0,i.jsxs)(`div`,{className:`w-full flex items-center gap-3 p-3.5 md:px-5`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:r,"aria-expanded":n,className:`flex items-center gap-3 flex-1 min-w-0 text-left cursor-pointer`,children:[(0,i.jsx)(`div`,{className:`relative shrink-0`,children:d?(0,i.jsx)(`img`,{src:d,alt:``,className:`w-9 h-9 rounded-full object-cover border border-[var(--panel-border)] shadow-sm`}):(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-full bg-accent/10 text-accent flex items-center justify-center font-bold border border-accent/20 shadow-sm uppercase`,children:(u||`A`)[0]})}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[14px] text-foreground truncate`,children:u}),(0,i.jsxs)(`span`,{className:`text-[12px] text-foreground/50 truncate flex items-center gap-1.5 font-medium mt-0.5`,children:[(0,i.jsx)(t.Zr,{className:`w-3.5 h-3.5 shrink-0`}),` `,Rt(e)]})]})]}),(0,i.jsx)(`button`,{type:`button`,onClick:r,tabIndex:-1,"aria-hidden":`true`,className:`md:hidden w-8 h-8 -mr-1 flex items-center justify-center rounded-lg text-foreground/30 hover:text-accent hover:bg-foreground/5 transition-colors shrink-0 cursor-pointer`,children:(0,i.jsx)(t.Ri,{className:`w-4 h-4 transition-transform duration-300 ${n?`rotate-180`:``}`})}),(0,i.jsxs)(`div`,{className:`max-md:hidden md:flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/35 tabular-nums whitespace-nowrap mr-1`,children:Mt(e.submittedAt)}),(0,i.jsx)(t.Q,{icon:e.isArchived?t.Yi:t.$i,onClick:a,busy:s,children:e.isArchived?`Restore`:`Archive`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,onClick:o,children:`Delete`}),(0,i.jsx)(`button`,{type:`button`,onClick:r,"aria-label":n?`Hide details from ${u}`:`Show details from ${u}`,className:`p-1.5 text-foreground/40 transition-transform duration-300 cursor-pointer ${n?`rotate-180`:``}`,children:(0,i.jsx)(t.Ri,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(t.pr,{children:n&&(0,i.jsx)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden`,children:(0,i.jsxs)(`div`,{className:`px-3.5 md:px-5 py-4 border-t border-[var(--panel-border)]/40`,children:[(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 mb-3`,children:[(0,i.jsx)(Bt,{source:e.source}),e.formId&&(0,i.jsx)(`span`,{className:`text-[10px] font-bold uppercase tracking-widest text-foreground/40 bg-foreground/5 px-2 py-0.5 rounded-md border border-[var(--panel-border)] shrink-0`,children:String(e.formId).replace(/_/g,` `)}),(0,i.jsx)(`span`,{className:`text-[11px] font-medium text-foreground/40 shrink-0`,children:jt(e.submittedAt)})]}),m.length>0?(0,i.jsx)(`div`,{className:`rounded-xl border border-[var(--panel-border)]/60 bg-foreground/[0.02] divide-y divide-[var(--panel-border)]/40 overflow-hidden`,children:m.map(([e,n])=>(0,i.jsxs)(`div`,{className:`px-3.5 md:px-4 py-3`,children:[(0,i.jsx)(`span`,{className:`block text-[11px] font-bold uppercase tracking-widest text-foreground/40 mb-1`,children:e.replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase())}),t.rr(n)?(0,i.jsx)(`div`,{className:`flex flex-col gap-1.5`,children:t.nr(n).map(e=>(0,i.jsxs)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,className:`inline-flex items-center gap-2 text-[14px] font-semibold text-accent hover:underline break-all [overflow-wrap:anywhere]`,children:[(0,i.jsx)(t.qr,{className:`w-4 h-4 shrink-0`}),t.tr(e)]},e))}):(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/85 leading-relaxed whitespace-pre-wrap break-words [overflow-wrap:anywhere]`,children:typeof n==`boolean`?n?`Yes`:`No`:String(n??``)||`No data provided`})]},e))}):(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/40 font-medium`,children:`This form only asked for a name and email.`}),f&&(0,i.jsx)(c.Link,{to:`/users/${e.uid}`,className:`inline-flex mt-3 text-[12.5px] font-bold text-accent hover:underline`,children:`Open this person’s profile`}),(0,i.jsxs)(`div`,{className:`md:hidden flex items-center justify-end gap-2 mt-4`,children:[(0,i.jsx)(t.Q,{icon:e.isArchived?t.Yi:t.$i,onClick:a,busy:s,children:e.isArchived?`Restore`:`Archive`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,onClick:o,children:`Delete`})]})]})})})]})}function Ht(){let e=zt(`anyone`),n=zt(`signedIn`),[a,s]=(0,r.useState)(`all`),[l,u]=(0,r.useState)(null),[d,f]=(0,r.useState)(!1),[p,m]=(0,r.useState)(null),[h,g]=(0,r.useState)(null),[_,v]=(0,r.useState)(!1),y=e.loading||n.loading,b=(0,r.useMemo)(()=>[...e.items,...n.items].sort((e,t)=>At(t)-At(e)),[e.items,n.items]),x=a===`all`?b:b.filter(e=>e.source===a),S=x.filter(e=>!e.isArchived),C=x.filter(e=>e.isArchived),w=e=>`${e.source}:${e.id}`,[T,E]=(0,c.useSearchParams)(),D=T.get(`open`);(0,r.useEffect)(()=>{if(!D||y)return;let e=b.find(e=>w(e)===D);e&&(e.isArchived&&f(!0),u(D),E({},{replace:!0}))},[D,y,b]);let O=e=>u(t=>t===w(e)?null:w(e)),k=async e=>{m(w(e));try{await(0,o.updateDoc)((0,o.doc)(t.Da,Ot[e.source].collectionName,e.id),{isArchived:!e.isArchived}),!e.isArchived&&l===w(e)&&u(null)}catch(e){console.error(`Failed to archive`,e)}m(null)},A=async()=>{if(h){v(!0);try{await(0,o.deleteDoc)((0,o.doc)(t.Da,Ot[h.source].collectionName,h.id)),l===w(h)&&u(null),g(null)}catch(e){console.error(`Failed to delete`,e)}v(!1)}},j=[{key:`all`,label:`Everything`,short:`All`},{key:`anyone`,label:Ot.anyone.filterLabel,short:`Anyone`},{key:`signedIn`,label:Ot.signedIn.filterLabel,short:`Signed in`}];return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-8`,children:[(0,i.jsx)(Ce,{children:`Inbox`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/inbox`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 flex-1 min-h-[500px]`,children:[(0,i.jsx)(`div`,{className:`flex justify-start`,children:(0,i.jsx)(Fe,{})}),(0,i.jsxs)(`div`,{className:`w-full flex-1 flex flex-col glass-panel rounded-2xl md:rounded-3xl p-3 sm:p-6 md:p-10 relative overflow-hidden border border-[var(--panel-border)] shadow-2xl bg-[var(--panel-bg)]`,children:[(0,i.jsx)(`div`,{className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-64 h-64 bg-accent/5 blur-[100px] rounded-full pointer-events-none`}),(0,i.jsx)(`div`,{className:`relative z-10 flex-1 flex flex-col`,children:y?(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center min-h-[500px]`,children:(0,i.jsx)(`div`,{className:`w-8 h-8 md:w-10 md:h-10 border-4 border-accent/20 border-t-accent rounded-full animate-spin`})}):b.length===0?(0,i.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center text-center p-8 gap-6`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-3xl bg-accent/10 border border-accent/20 flex items-center justify-center text-accent shadow-inner`,children:(0,i.jsx)(t.di,{className:`w-6 h-6`})}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`h2`,{className:`text-2xl font-extrabold text-foreground mb-2`,children:`Nothing here yet`}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/50 font-medium max-w-md`,children:`Everything people send you through a form on your site lands here.`})]})]}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 pb-8`,children:[(0,i.jsx)(`div`,{className:`flex flex-wrap items-center gap-2 mb-2`,children:j.map(e=>(0,i.jsxs)(`button`,{type:`button`,onClick:()=>s(e.key),"aria-pressed":a===e.key,"aria-label":e.label,className:`h-8 md:h-9 px-3 md:px-4 rounded-full text-[12px] md:text-[12.5px] font-bold border transition-all cursor-pointer ${a===e.key?`bg-accent/10 border-accent/40 text-accent`:`border-[var(--panel-border)]/70 bg-background/60 text-foreground/60 hover:text-foreground hover:border-accent/30`}`,children:[(0,i.jsx)(`span`,{className:`sm:hidden`,children:e.short}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:e.label})]},e.key))}),S.length===0&&(0,i.jsx)(`div`,{className:`bg-foreground/[0.02] border border-dashed border-[var(--panel-border)] rounded-2xl flex flex-col items-center justify-center p-8 text-center mb-4`,children:(0,i.jsx)(`p`,{className:`text-[14px] font-bold text-foreground/50`,children:C.length>0?`Everything here is archived.`:`Nothing matches this filter.`})}),(0,i.jsx)(t.pr,{children:Ft(S).map(e=>(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(It,{label:e.label}),e.items.map(e=>(0,i.jsx)(Vt,{item:e,isExpanded:l===w(e),onToggle:()=>O(e),onArchive:()=>k(e),onDelete:()=>g(e),busy:p===w(e)},w(e)))]},e.label))}),C.length>0&&(0,i.jsxs)(`div`,{className:`mt-6 pt-4 border-t border-[var(--panel-border)]/30`,children:[(0,i.jsx)(`div`,{className:`flex justify-center`,children:(0,i.jsxs)(`button`,{type:`button`,onClick:()=>f(e=>!e),className:`flex items-center gap-2 text-[11px] font-bold text-foreground/40 hover:text-foreground/70 transition-colors py-2 uppercase tracking-widest cursor-pointer`,children:[d?`Hide`:`View`,` `,C.length,` archived`,(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 transition-transform duration-300 ${d?`rotate-180`:``}`})]})}),(0,i.jsx)(t.pr,{children:d&&(0,i.jsx)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden mt-4`,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:Ft(C).map(e=>(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(It,{label:e.label}),e.items.map(e=>(0,i.jsx)(Vt,{item:e,isExpanded:l===w(e),onToggle:()=>O(e),onArchive:()=>k(e),onDelete:()=>g(e),busy:p===w(e),dimmed:!0},w(e)))]},e.label))})})})]})]})})]})]}),(0,i.jsx)(Ve,{isOpen:!!h,title:`Delete this message?`,message:`This removes it for good. There is no undo — archive it instead if you only want it out of the way.`,onConfirm:A,onCancel:()=>g(null),isProcessing:_,confirmText:`Yes, delete`})]})}var Ut=`inline-flex items-center justify-center w-9 h-9 rounded-full border border-[var(--panel-border)] text-foreground/50 hover:text-accent hover:bg-foreground/5 transition-colors shrink-0 cursor-pointer`,Wt=({to:e})=>e?(0,i.jsx)(c.Link,{to:e,"aria-label":`Go back`,title:`Go back`,className:Ut,children:(0,i.jsx)(t.Zi,{className:`w-4 h-4`})}):(0,i.jsx)(`button`,{type:`button`,onClick:()=>window.history.back(),"aria-label":`Go back`,title:`Go back`,className:Ut,children:(0,i.jsx)(t.Zi,{className:`w-4 h-4`})}),Gt=e=>{if(!e)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**+r).toFixed(2))+` `+n[r]};function Kt({title:e=`Drive`,subtitle:n=`/drive`,backUrl:a=`/templates`,filesCollection:u=`pub_files`,config:d,customContent:f,footer:p}){let{user:m,userRole:h}=t.na(),g=!!d,_=h===`admin`,v=u,y=u.startsWith(`user_`),[b,x]=(0,r.useState)([]),[S,C]=(0,r.useState)(!0),[w,T]=(0,r.useState)(null),[E,D]=(0,r.useState)(!0),[O,k]=(0,r.useState)(null),[A,j]=(0,r.useState)(!1),[M,N]=(0,r.useState)(null),[P,F]=(0,r.useState)(null),[I,L]=(0,r.useState)({}),[R,z]=(0,r.useState)(!1),[B,V]=(0,r.useState)(null),[H,U]=(0,r.useState)(``),[W,G]=(0,r.useState)(!1),[ee,K]=(0,r.useState)(``),[q,J]=(0,r.useState)(!1),Y=(0,r.useRef)(null);(0,r.useEffect)(()=>{D(!0)},[w?._id]),(0,r.useEffect)(()=>{if(!(y&&!m))return C(!0),(0,o.onSnapshot)(y?(0,o.query)((0,o.collection)(t.Da,u),(0,o.where)(`uid`,`==`,m.uid)):(0,o.query)((0,o.collection)(t.Da,u),(0,o.orderBy)(`createdAt`,`desc`)),e=>{let t=e.docs.map(e=>({_id:e.id,...e.data()}));t.sort((e,t)=>(t.createdAt?.toMillis?.()||0)-(e.createdAt?.toMillis?.()||0)),x(t),C(!1)},e=>{console.warn(`Error listening to ${u}:`,e),C(!1)})},[u,y,m?.uid]);let te=e=>!!m&&(e.uid===m.uid||_),ne=e=>{V(e),U(e.name),K(``),z(!0)},re=()=>{V(null),K(``),z(!0)},X=async e=>{if(e.preventDefault(),!(!B||!H.trim()||!m)){G(!0),K(``);try{let e=await t.or(B),n=`${v}/${`${Date.now()}_${e.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,r=(0,s.ref)(t.ka,n);await(0,s.uploadBytes)(r,e,{customMetadata:{ownerId:m.uid}});let i=await(0,s.getDownloadURL)(r);await(0,o.addDoc)((0,o.collection)(t.Da,u),{fileName:H.trim(),fileType:e.type||`unknown`,fileSize:e.size,downloadURL:i,storagePath:n,uid:m.uid,uploaderEmail:m.email||``,createdAt:(0,o.serverTimestamp)()}),z(!1),V(null),U(``)}catch(e){K(e?.code===`storage/unauthorized`?`You do not have permission to upload here.`:e?.message||`Upload failed. Please try again.`)}G(!1)}},Z=async()=>{if(O){j(!0);try{await Promise.all([(0,s.deleteObject)((0,s.ref)(t.ka,O.storagePath||O.downloadURL)).catch(e=>console.warn(`Storage object missing:`,e)),(0,o.deleteDoc)((0,o.doc)(t.Da,u,O._id))]),k(null)}catch(e){console.error(`Delete failed:`,e)}j(!1)}},Q=async()=>{if(!M||!M.name.trim()){N(null);return}try{await(0,o.updateDoc)((0,o.doc)(t.Da,u,M.id),{fileName:M.name.trim()})}catch(e){console.error(`Rename failed:`,e)}N(null)},ie=(e,t)=>{navigator.clipboard.writeText(e),F(t),setTimeout(()=>F(null),2e3)},ae=(e,n=`row`)=>{let r=n===`card`?`w-16 h-16`:`w-10 h-10`,a=n===`card`?`w-8 h-8`:`w-5 h-5`;return e.includes(`video`)||e.includes(`audio`)?(0,i.jsx)(`div`,{className:`${r} flex items-center justify-center bg-accent/10 text-accent rounded-lg`,children:(0,i.jsx)(t.br,{className:a})}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,i.jsx)(`div`,{className:`${r} flex items-center justify-center bg-blue-500/10 text-blue-500 rounded-lg`,children:(0,i.jsx)(t.gi,{className:a})}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,i.jsx)(`div`,{className:`${r} flex items-center justify-center bg-yellow-500/10 text-yellow-500 rounded-lg`,children:(0,i.jsx)(t.ea,{className:a})}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,i.jsx)(`div`,{className:`${r} flex items-center justify-center bg-emerald-500/10 text-emerald-500 rounded-lg`,children:(0,i.jsx)(t.Ei,{className:a})}):(0,i.jsx)(`div`,{className:`${r} flex items-center justify-center bg-foreground/5 text-foreground/40 rounded-lg`,children:(0,i.jsx)(t.hi,{className:a})})};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 flex flex-col min-h-screen relative`,onDragOver:e=>{e.preventDefault(),J(!0)},onDragLeave:e=>{e.preventDefault(),J(!1)},onDrop:e=>{e.preventDefault(),J(!1),e.dataTransfer.files?.[0]&&ne(e.dataTransfer.files[0])},children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[!g&&(0,i.jsx)(Wt,{to:a}),(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(Ce,{children:e}),(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),n]})]})]}),g&&(0,i.jsx)(`div`,{className:`mb-6`,children:(0,i.jsx)(Fe,{})}),(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl md:rounded-3xl overflow-hidden flex-1 shadow-2xl min-h-[420px] md:min-h-[520px] mb-16 bg-background flex flex-col`,children:[(0,i.jsxs)(`div`,{className:`p-4 md:p-8 flex items-center justify-between gap-3 md:gap-6 border-b border-[var(--panel-border)]/50 bg-background/50`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-lg md:text-2xl font-extrabold text-foreground tracking-tight`,children:`Files`}),(0,i.jsx)(`p`,{className:`max-sm:hidden text-[12px] md:text-[13px] mt-1 md:mt-2 text-foreground/60 font-medium`,children:y?`Only you can see the files you upload here.`:`Everyone who can open this page can see these files.`})]}),!f&&(m?(0,i.jsxs)(t.cr,{onClick:re,title:`Add file`,className:`flex items-center justify-center gap-2 w-9 h-9 p-0 sm:w-auto sm:h-auto sm:px-5 sm:py-2.5 rounded-xl text-[13px] font-bold shadow-md shrink-0`,children:[(0,i.jsx)(t.Ur,{className:`w-4 h-4`}),` `,(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:`Add file`})]}):(0,i.jsxs)(c.Link,{to:`/login`,title:`Sign in to add a file`,className:`btn-primary flex items-center justify-center gap-2 w-9 h-9 p-0 sm:w-auto sm:h-auto sm:px-5 sm:py-2.5 rounded-xl text-[13px] font-bold shadow-md shrink-0`,children:[(0,i.jsx)(t.Ur,{className:`w-4 h-4`}),` `,(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:`Add file`})]}))]}),f?(0,i.jsx)(`div`,{className:`fbos-content-slot p-4 md:p-8 flex-1`,children:(0,i.jsx)(f,{files:b,loading:S,user:m,uploadFile:ne,deleteFile:k,openUploadModal:re,config:d})}):(0,i.jsxs)(`div`,{className:`p-4 sm:p-6 md:p-8 flex-1 relative`,children:[S&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,i.jsx)(t.ti,{className:`w-8 h-8 text-accent animate-spin`})}),b.length>0?(0,i.jsx)(`div`,{className:`grid grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3 sm:gap-4`,children:b.map(e=>(0,i.jsxs)(`div`,{className:`flex flex-col bg-background border border-[var(--panel-border)] rounded-2xl hover:border-accent/40 transition-all group overflow-hidden shadow-sm h-[190px] relative`,children:[(0,i.jsxs)(`div`,{className:`absolute top-2 right-2 flex flex-col gap-1 opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity z-10 bg-background/90 backdrop-blur-md rounded-lg p-1 border border-[var(--panel-border)] shadow-xl`,children:[(0,i.jsx)(`a`,{href:e.downloadURL,download:!0,target:`_blank`,rel:`noreferrer`,className:`p-1.5 hover:bg-foreground/5 rounded-md text-foreground/60 hover:text-blue-500 transition-colors`,title:`Download`,children:(0,i.jsx)(t.Si,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),ie(e.downloadURL,e._id)},className:`p-1.5 hover:bg-foreground/5 rounded-md text-foreground/60 hover:text-emerald-500 transition-colors`,title:`Copy link`,children:P===e._id?(0,i.jsx)(t.zi,{className:`w-4 h-4 text-emerald-500`}):(0,i.jsx)(t.ri,{className:`w-4 h-4`})}),te(e)&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),N({id:e._id,name:e.fileName})},className:`p-1.5 hover:bg-foreground/5 rounded-md text-foreground/60 hover:text-accent transition-colors`,title:`Rename`,children:(0,i.jsx)(t.Kr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),k(e)},className:`p-1.5 hover:bg-red-500/10 rounded-md text-foreground/60 hover:text-red-500 transition-colors`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`h-[120px] w-full border-b border-[var(--panel-border)]/50 bg-foreground/[0.02] flex items-center justify-center overflow-hidden relative cursor-pointer`,onClick:()=>T(e),children:e.fileType.startsWith(`image/`)?(0,i.jsxs)(i.Fragment,{children:[I[e._id]!==!1&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center bg-accent/5 z-0`,children:(0,i.jsx)(t.ti,{className:`w-5 h-5 text-accent animate-spin`})}),(0,i.jsx)(`img`,{src:e.downloadURL,alt:``,loading:`lazy`,className:`absolute inset-0 w-full h-full object-contain p-2 transition-opacity duration-300 ${I[e._id]===!1?`opacity-100`:`opacity-0`}`,onLoad:()=>L(t=>({...t,[e._id]:!1})),onError:()=>L(t=>({...t,[e._id]:!1}))})]}):ae(e.fileType,`card`)}),(0,i.jsxs)(`div`,{className:`p-3 flex flex-col justify-center flex-1 min-w-0`,onClick:()=>!M&&T(e),children:[M?.id===e._id?(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,value:M.name,onChange:e=>N({...M,name:e.target.value}),onBlur:Q,onKeyDown:e=>{e.key===`Enter`&&Q(),e.key===`Escape`&&N(null)},onClick:e=>e.stopPropagation(),className:`no-glow text-[12.5px] font-bold text-foreground bg-transparent border-b border-accent/30 outline-none pb-0.5 w-full`}):(0,i.jsx)(`span`,{className:`text-[12.5px] font-bold text-foreground truncate select-none group-hover:text-accent transition-colors`,title:e.fileName,children:e.fileName}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/40 font-bold uppercase tracking-wider mt-1 select-none`,children:Gt(e.fileSize)})]})]},e._id))}):!S&&(0,i.jsxs)(`div`,{onClick:()=>m&&z(!0),className:`min-h-[320px] flex flex-col items-center justify-center text-center cursor-pointer group`,children:[(0,i.jsx)(t.Di,{className:`w-12 h-12 text-foreground/15 mb-4`}),(0,i.jsx)(`p`,{className:`text-[20px] font-bold text-foreground/50 group-hover:text-foreground/70 transition-colors`,children:`No files yet`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium mt-1 text-foreground/40`,children:m?`Click here or drag a file in to upload`:`Sign in to upload a file`})]})]})]}),p,(0,i.jsx)(t.pr,{children:R&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>!W&&z(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/80 backdrop-blur-xl cursor-pointer`}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`w-full max-w-[480px] border-[var(--panel-border)] border rounded-3xl relative z-10 glass-panel shadow-2xl flex flex-col bg-background`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between p-4 md:p-6 border-b border-[var(--panel-border)]/50`,children:[(0,i.jsx)(`span`,{className:`text-[16px] font-extrabold text-foreground tracking-tight`,children:`Upload a file`}),(0,i.jsx)(`button`,{onClick:()=>!W&&z(!1),className:`text-foreground/40 hover:text-foreground transition-colors`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})})]}),B?(0,i.jsxs)(`form`,{onSubmit:X,className:`p-4 md:p-6 flex flex-col gap-5 md:gap-6`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-4 bg-foreground/[0.03] p-4 rounded-2xl border border-[var(--panel-border)]`,children:[ae(B.type),(0,i.jsxs)(`div`,{className:`flex flex-col flex-1 min-w-0 pr-4`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:B.name}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/50 font-bold uppercase tracking-wider mt-1`,children:Gt(B.size)})]}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>!W&&V(null),className:`w-8 h-8 flex items-center justify-center text-foreground/40 hover:text-red-500 rounded-xl hover:bg-red-500/10 transition-colors shrink-0`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsx)(`label`,{className:`text-[11px] font-bold text-foreground/50 uppercase tracking-widest pl-1`,children:`File name`}),(0,i.jsx)(`input`,{type:`text`,required:!0,value:H,onChange:e=>U(e.target.value),disabled:W,className:`no-glow w-full bg-foreground/[0.02] border border-[var(--panel-border)] rounded-xl px-4 py-3.5 text-[14px] font-bold text-foreground outline-none focus:border-accent transition-colors`})]}),ee&&(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-red-400 bg-red-500/10 border border-red-500/20 rounded-xl p-3`,children:ee}),(0,i.jsx)(t.cr,{type:`submit`,isLoading:W,className:`w-full py-4 rounded-xl text-[14px] font-bold shadow-lg`,children:W?`Uploading…`:`Upload`})]}):(0,i.jsx)(`div`,{className:`p-4 md:p-6`,children:(0,i.jsxs)(`label`,{onDragOver:e=>e.preventDefault(),onDrop:e=>{e.preventDefault(),e.dataTransfer.files?.[0]&&ne(e.dataTransfer.files[0])},className:`group flex flex-col items-center justify-center gap-1.5 px-6 py-12 rounded-2xl border-2 border-dashed border-[var(--panel-border)] bg-foreground/[0.015] hover:border-accent/50 hover:bg-accent/[0.03] cursor-pointer text-center transition-all`,children:[(0,i.jsx)(`span`,{className:`w-14 h-14 rounded-full bg-accent/10 text-accent flex items-center justify-center mb-2 group-hover:scale-105 transition-transform`,children:(0,i.jsx)(t.Di,{className:`w-6 h-6`})}),(0,i.jsxs)(`p`,{className:`text-[15px] font-bold text-foreground`,children:[(0,i.jsx)(`span`,{className:`text-accent`,children:`Click to upload`}),` or drag a file in`]}),(0,i.jsx)(`p`,{className:`text-[12.5px] text-foreground/45 font-medium`,children:`Pictures, documents, anything`}),(0,i.jsx)(`input`,{type:`file`,ref:Y,"aria-label":`Upload a file`,onChange:e=>e.target.files?.[0]&&ne(e.target.files[0]),className:`hidden`})]})})]})]})}),typeof window<`u`&&(0,l.createPortal)((0,i.jsx)(t.pr,{children:w&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>T(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(`button`,{onClick:()=>T(null),className:`absolute top-3 right-3 md:top-6 md:right-6 z-[160] w-10 h-10 md:w-12 md:h-12 bg-foreground/10 hover:bg-foreground/20 text-foreground rounded-full flex items-center justify-center backdrop-blur-md transition-all`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.95},className:`relative z-10 w-full max-w-6xl max-h-[85vh] flex flex-col shadow-2xl rounded-3xl overflow-hidden glass-panel border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between p-3.5 md:p-6 bg-background/80 backdrop-blur-md border-b border-[var(--panel-border)] shrink-0`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-3 md:pr-4`,children:[(0,i.jsx)(`span`,{className:`text-[15px] md:text-xl font-extrabold text-foreground truncate`,children:w.fileName}),(0,i.jsxs)(`span`,{className:`text-[10.5px] md:text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-0.5 md:mt-1 truncate`,children:[w.fileType,` • `,Gt(w.fileSize)]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 md:gap-2 shrink-0`,children:[(0,i.jsx)(`button`,{onClick:()=>ie(w.downloadURL,w._id),className:`p-2 md:p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 hover:text-emerald-500 transition-colors rounded-xl`,title:`Copy link`,children:P===w._id?(0,i.jsx)(t.zi,{className:`w-4 h-4 text-emerald-500`}):(0,i.jsx)(t.ri,{className:`w-4 h-4`})}),te(w)&&(0,i.jsx)(`button`,{onClick:()=>{let e=w;T(null),k(e)},className:`p-2 md:p-2.5 bg-red-500/10 hover:bg-red-500/20 text-red-500 transition-colors rounded-xl`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})}),(0,i.jsx)(`a`,{href:w.downloadURL,download:!0,target:`_blank`,rel:`noreferrer`,className:`p-2 md:p-2.5 btn-primary transition-colors rounded-xl shadow-lg ml-0.5 md:ml-1`,title:`Download`,children:(0,i.jsx)(t.Si,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-0 h-[70vh]`,children:(0,i.jsxs)(`div`,{className:`absolute inset-4 md:inset-8 flex items-center justify-center`,children:[E&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center z-50 pointer-events-none`,children:(0,i.jsx)(t.ti,{className:`w-6 h-6 text-accent animate-spin`})}),w.fileType.startsWith(`image/`)?(0,i.jsx)(`img`,{onLoad:()=>D(!1),src:w.downloadURL,alt:w.fileName,className:`block max-w-full max-h-full w-auto h-auto object-contain rounded-lg transition-opacity duration-500 ${E?`opacity-0`:`opacity-100`}`}):w.fileType.startsWith(`video/`)?(0,i.jsx)(`video`,{onLoadedData:()=>D(!1),src:w.downloadURL,controls:!0,className:`max-w-full max-h-full rounded-lg transition-opacity duration-500 ${E?`opacity-0`:`opacity-100`}`}):w.fileType===`application/pdf`?(0,i.jsx)(`iframe`,{onLoad:()=>D(!1),src:w.downloadURL,className:`w-full h-full border-none bg-white rounded-lg transition-opacity duration-500 ${E?`opacity-0`:`opacity-100`}`,title:`PDF preview`}):(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center text-foreground/40 text-center`,onClick:()=>D(!1),children:[(0,i.jsx)(t.hi,{className:`w-24 h-24 mb-6 opacity-40`}),(0,i.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview unavailable`}),(0,i.jsx)(`span`,{className:`text-[14px] mt-2 text-foreground/60 font-medium max-w-xs`,children:`This format cannot be previewed. Download it instead.`})]})]})})]})]})}),document.body),(0,i.jsx)(Ve,{isOpen:!!O,title:`Delete file`,message:(0,i.jsxs)(i.Fragment,{children:[`Delete `,(0,i.jsx)(`strong`,{className:`text-foreground block my-1 break-words max-w-full text-center`,children:O?.fileName}),` This cannot be undone.`]}),onConfirm:Z,onCancel:()=>k(null),isProcessing:A,confirmText:`Yes, delete`}),(0,i.jsx)(t.pr,{children:q&&(0,i.jsx)(t.fr.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`fixed inset-0 z-[1000] bg-background/60 backdrop-blur-md pointer-events-none flex items-center justify-center p-6`,children:(0,i.jsxs)(`div`,{className:`w-full max-w-lg aspect-video bg-background/80 border-2 border-dashed border-accent rounded-[40px] shadow-2xl flex flex-col items-center justify-center gap-6`,children:[(0,i.jsx)(`div`,{className:`w-20 h-20 rounded-full bg-accent/10 flex items-center justify-center text-accent`,children:(0,i.jsx)(t.Di,{className:`w-10 h-10 animate-bounce`})}),(0,i.jsx)(`span`,{className:`text-[24px] font-extrabold text-foreground tracking-tight`,children:`Drop to upload`})]})})})]})}var qt=[`mem_files`,`user_files`,`admin_files`],Jt=e=>!e.sourceTab;function Yt(){let[e,n]=(0,r.useState)(null),[a,c]=(0,r.useState)(!1),[l,u]=(0,r.useState)(!1),[d,f]=(0,r.useState)(``),[p,m]=(0,r.useState)(0);(0,r.useEffect)(()=>{let e=!1;return Promise.all(qt.map(async e=>{try{return(await(0,o.getDocs)((0,o.collection)(t.Da,e))).docs.map(t=>({collectionName:e,id:t.id,...t.data()}))}catch{return[]}})).then(t=>{e||n(t.flat())}),()=>{e=!0}},[]);let h=async()=>{if(!e)return;u(!0),f(``);let r=0;for(let n of e)try{let e=n.storagePath||n.downloadURL;e&&Jt(n)&&await(0,s.deleteObject)((0,s.ref)(t.ka,e)).catch(()=>{}),await(0,o.deleteDoc)((0,o.doc)(t.Da,n.collectionName,n.id)),m(e=>e+1)}catch(e){r+=1,console.error(`Could not delete ${n.collectionName}/${n.id}:`,e)}r>0?(f(`${r} file${r===1?``:`s`} could not be deleted. Reload and try again.`),n((await Promise.all(qt.map(async e=>{try{return(await(0,o.getDocs)((0,o.collection)(t.Da,e))).docs.map(t=>({collectionName:e,id:t.id,...t.data()}))}catch{return[]}}))).flat())):n([]),u(!1),c(!1)};if(!e||e.length===0)return null;let g=e.filter(Jt).length,_=qt.map(t=>({name:t,n:e.filter(e=>e.collectionName===t).length})).filter(e=>e.n>0);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`mt-6 glass-panel border border-amber-500/25 bg-amber-500/[0.03] rounded-2xl md:rounded-3xl p-4 md:p-8`,children:[(0,i.jsxs)(`h3`,{className:`text-[17px] font-extrabold text-foreground tracking-tight mb-2`,children:[e.length,` leftover record`,e.length===1?``:`s`,` from the old Drive`]}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/60 leading-relaxed mb-3 max-w-2xl`,children:`Drive used to have Internal, User and Admin folders. They are gone — this page is the only built-in folder now, and each page you have built keeps its own files. Nothing reads these records any more.`}),(0,i.jsxs)(`p`,{className:`text-[14px] text-foreground/60 leading-relaxed mb-3 max-w-2xl`,children:[g>0?`${g} ${g===1?`was`:`were`} uploaded through the old Drive screen, so ${g===1?`its file is`:`their files are`} deleted too. `:``,e.length-g>0?`${e.length-g} belong to files a page still shows, so only the leftover record goes — the ${e.length-g===1?`file stays`:`files stay`} where ${e.length-g===1?`it is`:`they are`}.`:``]}),(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/50 font-medium mb-5`,children:_.map(e=>`${e.n} in ${e.name}`).join(` · `)}),d&&(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-red-400 bg-red-500/10 border border-red-500/20 rounded-xl p-3 mb-4`,children:d}),(0,i.jsxs)(`button`,{onClick:()=>c(!0),disabled:l,className:`inline-flex items-center gap-2 px-5 py-2.5 rounded-xl text-[13px] font-bold bg-red-500/10 hover:bg-red-500/20 text-red-500 border border-red-500/20 transition-colors disabled:opacity-50`,children:[l?(0,i.jsx)(t.ti,{className:`w-4 h-4 animate-spin`}):(0,i.jsx)(t.Or,{className:`w-4 h-4`}),l?`Deleting ${p} of ${e.length}…`:`Clean up all ${e.length} permanently`]})]}),(0,i.jsx)(Ve,{isOpen:a,title:`Delete the old Drive files`,message:(0,i.jsxs)(i.Fragment,{children:[`This permanently deletes `,(0,i.jsxs)(`strong`,{className:`text-foreground`,children:[e.length,` leftover record`,e.length===1?``:`s`]}),` `,`from `,_.map(e=>e.name).join(`, `),g>0&&(0,i.jsxs)(i.Fragment,{children:[`, along with the `,(0,i.jsxs)(`strong`,{className:`text-foreground`,children:[g,` file`,g===1?``:`s`]}),` uploaded through the old Drive screen`]}),`. It cannot be undone, and it covers every user's uploads, not only your own. Files that a page still shows are left alone.`]}),onConfirm:h,onCancel:()=>c(!1),isProcessing:l,confirmText:`Yes, delete them`})]})}function Xt(){let{isAdmin:e}=t.na();return(0,i.jsx)(Kt,{title:`Assets`,subtitle:`/assets`,filesCollection:`pub_files`,config:{isAdmin:!0,pageId:`assets`},footer:e?(0,i.jsx)(Yt,{}):null})}function Zt(){let e=[{id:`board`,title:`Board View`,description:`Cards in columns you drag from one stage to the next.`,icon:t.ui,path:`/board`},{id:`table`,title:`Data Table`,description:`Rows and columns for longer lists, with search and sorting.`,icon:t.jr,path:`/table`},{id:`calendar`,title:`Calendar View`,description:`A month at a time for anything that belongs on a date.`,icon:t.Vi,path:`/calendar`},{id:`drive`,title:`Drive View`,description:`A file library with upload, preview, rename and delete.`,icon:t.pi,path:`/drive`}];return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-10 text-center`,children:[(0,i.jsx)(Ce,{children:`What your assistant can build`}),(0,i.jsxs)(`p`,{className:`text-foreground/60 text-[14px] md:text-[15px] font-medium max-w-2xl mx-auto`,children:[`Every layout below already works — open one to see it.`,` `,(0,i.jsx)(c.Link,{to:`/guide`,className:`text-accent font-bold hover:underline`,children:`Start with the guide`}),`.`]})]}),(0,i.jsxs)(`div`,{className:`w-full max-w-4xl mx-auto flex flex-col gap-3 md:gap-4 relative`,children:[(0,i.jsx)(`div`,{className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[80%] h-[80%] bg-accent/5 blur-[120px] rounded-full pointer-events-none -z-10`}),e.map((e,n)=>{let r=e.icon;return(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{delay:n*.05},children:(0,i.jsxs)(c.Link,{to:e.path,className:`flex items-center gap-3 md:gap-5 w-full p-3.5 md:px-6 md:py-4 glass-panel border border-[var(--panel-border)] rounded-2xl hover:border-accent/40 transition-all duration-300 group hover:bg-foreground/[0.02]`,children:[(0,i.jsx)(`div`,{className:`w-10 h-10 md:w-12 md:h-12 rounded-xl bg-accent/10 flex items-center justify-center text-accent shrink-0 border border-accent/20 group-hover:scale-105 transition-transform`,children:(0,i.jsx)(r,{className:`w-5 h-5`})}),(0,i.jsxs)(`div`,{className:`flex flex-col flex-1 min-w-0`,children:[(0,i.jsx)(`h3`,{className:`text-[14px] md:text-[15px] font-bold text-foreground truncate`,children:e.title}),(0,i.jsx)(`p`,{className:`text-[12.5px] md:text-[13px] text-foreground/50 truncate font-medium`,children:e.description})]}),(0,i.jsx)(`span`,{"aria-hidden":`true`,className:`w-9 h-9 rounded-full flex items-center justify-center text-foreground/40 border border-[var(--panel-border)] shrink-0 group-hover:text-accent group-hover:border-accent/40 group-hover:translate-x-0.5 transition-all`,children:(0,i.jsx)(t.Xi,{className:`w-4 h-4`})})]})},e.id)})]})]})}var Qt=`Xl271wWblkY`,$t=[{title:`Open the Pages screen and press +`,body:`Pick Website Pages, for your public site, or Tabs, for the dashboard behind sign-in. A tab starts open to Members — everybody who registers — and its own row carries who can open it: switch it to Your team or Admins only any time, or, staying on Members, tick more than one audience or make a role of your own — Client, say — and keep the page for the people you mark with it.`},{title:`Name the page and say what is on it`,body:`The row opens in sections. The first is the page itself: its name, its web address and one box for what is on it, in your own words — every box shows a real example before you type. The name creates the page the moment you leave its box; the address is made from the name unless you write one, and a dashboard page takes the menu icon your words name. Whatever you skip, your assistant decides.`},{title:`If it needs forms, say so in the Forms section`,body:`Describe every form the page needs, one after the other — what each asks and what happens after — or name forms you already have. Your assistant builds them with the page, decides where each goes and what its button says, and every answer lands in your Inbox.`},{title:`Add your pictures, your booking and a linked page`,body:`Under Pictures, upload each picture — it gets a number — and say how they are used, by number. Under Booking, pick a schedule from the Schedule screen and say how booking works here. Under Linked pages, pick another of your pages — or make a new one right there, with the same sections — and say how the two connect. Pictures never travel through the chat; the sentence you copy carries them for you.`},{title:`Copy the sentence`,body:`Once email or payments are switched on, an Emails and a Payments section appear too. The finished sentence appears under the sections; copy it and paste it into your assistant’s chat. That is the whole hand-over.`},{title:`Change it later in the same place`,body:`Once the sentence is copied, the row knows the page is built: open it again and one box asks what to change, with the same sections under it. The sentence it hands you edits the page you already have — your words, plus only the sections you changed since — and nothing you did not mention is touched. Copying it blanks the box for next time. To rename or move the page, write Name: or Address: on a line of its own in that box.`}],en=[{name:`Website Pages`,where:`In the site menu`,who:`Everybody, signed in or not. This is your public website.`},{name:`Members`,where:`In the dashboard`,who:`Anyone who registers. Each person sees only their own information, never anyone else’s.`},{name:`Your team`,where:`In the dashboard`,who:`Only people you marked as team members on the Users screen, plus admins. Everyone on it sees the same information.`},{name:`Admins only`,where:`In the dashboard`,who:`You, and anyone you marked as an admin.`},{name:`A role of your own`,where:`In the dashboard`,who:`People you marked with a role you invented — Client, Supplier, whatever you need. You make one in the list on a Members page’s row, and mark people with it on the Users screen. They are ordinary Members in every other way; a page kept for a role is theirs alone, nobody else can even follow its address, and everyone marked with it sees the same information on it.`}],tn=[{title:`Someone registers`,body:`That makes them a Member, nothing more: they can open the pages for Members and see only their own information there.`},{title:`You give them rights on the Users screen`,body:`Mark a person as a team member to open your team’s pages, or as an admin to open everything — your admin screens included. Or mark them with a role of your own — Client, Supplier — which opens the pages you kept for that role and nothing else. Take any of them back the same way.`},{title:`The pages do the rest`,body:`Access always follows who a page is for. There is nothing to switch on per person beyond the mark you set — a new team page is open to your whole team the moment it exists.`}],nn=[{name:`Say what you are after`,body:`What you do, who it is for and the feeling you want. Upload your logo — its colours are where the look comes from — and give the site its name. Say whether it should be always light, always dark, or follow the visitor’s device only if you want that changed.`},{name:`Copy the sentence to your assistant`,body:`The Theme screen turns your answers into one sentence. Paste it into your assistant’s chat, and attach your logo picture to the same message — the assistant cannot open the link, and the picture is where it reads the colours.`},{name:`It designs the whole look`,body:`Colours for light and dark, the buttons, the headings, the corners, your logo and the name, all in one file. Ask it to be bold and it will be; ask it for calm and it will be that. There are no colour boxes or sliders to set by hand.`},{name:`Change it the same way`,body:`Once the look is in, the screen asks what you would like changed. Say just that — a softer green, warmer backgrounds — and copy the sentence again. Nothing you do not mention moves.`}],rn=[{screen:`Inbox`,path:`/inbox`,body:`Read every answer people sent through your forms.`},{screen:`Users`,path:`/users`,body:`Mark a person as a team member or an admin — or with a role of your own. Your own roles are kept in a card under the list: rename one and the new word appears everywhere at once, on every card and in every list, with nobody unmarked; remove one and the card first says what that will do — the people marked with it go back to being members, the pages kept for it go back to everybody signed in, and whatever those pages saved stays exactly where it is.`},{screen:`Pages`,path:`/pages`,body:`Press + and fill in the sections: the page itself — its name, its web address and what is on it — then its pictures, its forms (as many as you like, described one after the other), its schedules (whose working hours from the Schedule screen the page is built on — the week itself, one person each, never a meeting you designed — then how they will be used: a rota, who is in on Thursday, or a page people book time on; with more than one person picked you also say who a booking is with — one of them, all of them at once, or both with the visitor choosing — and last, only if they book, what they should be asked first. Nothing here waits on a booking link: the hours themselves are what is booked, read live, so changing your week changes the page), the booking links or booking pages you already made and want a link to on it, with a line on where that link should sit and how it should open, the pages it links to (one you have, or a new one made right there), and, once switched on, its emails and its payments; every box shows a real example before you type, and whatever you skip your assistant decides. Copy the sentence. The moment it is copied the page counts as built and the row asks what should change, with the same sections under it: the sentence carries your words plus only the sections you changed since, a rename or a move is a Name: or Address: line of its own, and copying blanks the box again — the forms box too, which then asks what should change about the forms. The home page, the dashboard, Contact and Support open on the same sections. Reorder, hide or delete a page from its row.`},{screen:`Schedule`,path:`/schedule`,body:`When you and your team are free, and everything built on it. A SCHEDULE is a week of hours with a name — Working hours, Evenings, Studio days — kept in that person’s own time zone, with the days they are away marked on it. Your own are in the first card and everyone else’s — anyone marked Internal or Admin on the Users screen — under their own name in the second, so press the Add a schedule of whoever the hours belong to. It arrives named, weekdays nine to five — hours have no on and off switch, they are simply the week you keep; change the hours, add a second stretch for a break in the middle, and add a day away for a holiday — every meeting booked in those hours loses that day at once, which is the whole point of entering it in one place. A BOOKING LINK, in the card under them, is what turns hours into something people can book: pick which hours it is booked in, what the meeting is called, how long it lasts, how far ahead and with how much notice, what it asks the visitor beyond their name and their email, and a payment if you want one taken first — then copy its link and send it to anyone. They see the free times in their own time zone, pick one, and book. One set of hours carries as many links as you like — a 15-minute intro and a 2-hour workshop on the same week — and they share one availability, so a time taken under one is gone from all of them. The switch on each row is what offers it: leave it off while you set it up, turn it on when you are ready. Under Your booking pages, Create a page makes ONE address that carries several of them: give it a name, a photo and a line about yourself, tick the meetings it should offer, and send that instead — whoever opens it sees what you do and everything you can be booked for, and books it the same way. You can also pick a schedule on the Pages screen under Schedules on that page — what you pick there is somebody’s WEEK, not one of these meetings, because a page built on your hours does not have to be a booking at all: say how it will be used and it is built on them, and leave the question about what people are asked empty when nothing is booked there. A booking link is not needed for any of that and is never asked for: if the page does book, it books those hours themselves, so the times follow your week wherever it is shown. Or, under Booking links there, tick a link or a page you have already made and it goes on that page as a plain link, opening the very one you ticked — say where it should sit and how it opens (a button that says Book time with me, opening in a pop-up) and nothing about it is rebuilt. Or add a Pick-a-time question to any form on the Forms screen. Every booking lands on the Calendar at the top of this screen, where you can cancel it, and in your Inbox like any form entry. That calendar is a month grid of everything booked: pick a day to see who is coming, with Paid beside a booking that was paid for, and Cancel to free the time. As an admin you can read it as your whole team at once, or as any one person — whoever has no schedule yet is greyed in the list — and Add puts an event of your own on the day you picked, in whosever diary you are reading. Taking a booking off the calendar for good is an admin’s alone: it destroys the record in every diary it was booked into and on the other side of it too, so everybody it belonged to is told before it goes, and an event you put on your own day is still yours to delete. Whoever booked reads the very same calendar under My bookings, from their end — what the meeting is and who it is with, never the name of the week it falls in — and cancels from it the same way, saying why. Everybody signed in has the bell, so a cancellation on either side reaches the other without anybody opening a page.`},{screen:`Payments`,path:`/payments`,body:`The Take payments switch at the top turns every Pay button on or off at once — off is a pause, not a disconnect, and your pages keep their settings. Under Payment links, every one-time payment has a page of its own you can send to anyone — add one from a name, a line about it and a price, copy the link, and press Customise this page to have your assistant make a page of your own for it. Check the connection, then describe what you sell under What you sell — things paid for once, each with a name and a price, as many as you like under one entry; or a subscription with plans and their Stripe ids — and press Proceed. That opens the same payment under How your payments work, where one box asks how it works, start to finish: what someone does, pays and gets, and anything you care about along the way — what they tell you first, what happens after, what a plan unlocks; whatever you skip, your assistant decides. Press Proceed once more and the same payment opens under Wire it into your pages: tick the pages this one goes on — where it sells, and where your team sees what it sold — and, if you like, say what should appear there or name a page to add and who will see it. Every payment has its own pages; under them, one request carries all of them, every page and the way your app makes pages, forms and links, so your assistant wires it in one go — and you change any page afterwards from its row on the Pages screen. Connection stands right under the switch and says which Stripe account you are on — Test mode connected while you are practising. Under it sits Go live, always there: flip it and it walks you through your live secret key, your live price ids if you sell subscriptions, and the webhook that keeps receipts and sale alerts sending when a buyer pays and never comes back. That last step waits until your app is published, because Stripe has to be able to reach it from the outside — tick step 3 on the Publish App screen, Add your domains and email sender, and it unlocks itself with your published address ready to copy. Your customers change or cancel their subscriptions on Stripe’s own page — switching plans (monthly to yearly, Basic to Pro) appears there only if you allow it, under Stripe’s Settings, Billing, Customer portal — so there is nothing to ask the assistant to build for cancellations.`},{screen:`Billing`,path:`/billing`,body:`Your buyers’ page, not yours: anyone signed in who has bought something finds what they bought here, with Stripe’s own button to change card, cancel or switch plans. It appears in their menu only after their first purchase — nobody who never bought anything sees it, and there is nothing to build.`},{screen:`Email`,path:`/email`,body:`Connect email, switch it on or off with Send email at the top — off stops every send at once and keeps your settings — send yourself one test email, after which the Connection card only says Connected and the address it sends from (it opens up again if you change the sender), and see what your app can do with it: hear about what happens on a page, confirm to the people who write in, send receipts and sale alerts, and — from a page for your team — write to anyone. Each says where it is switched on — a page on the Pages screen, a payment on the Payments screen. Receipts and sale alerts send themselves — every payment you describe on the Payments screen has both switched on unless you turn them off.`},{screen:`Forms`,path:`/forms`,body:`See every form. Add a question or change a form’s title and button text after it is built — forms are created with their pages.`},{screen:`Theme`,path:`/theme`,body:`Where you tell your assistant what look you want — your logo, the name, how the site opens, and the feeling you are after — and copy the one sentence that has it design the whole thing. Nothing is set by hand here.`},{screen:`Publish App`,path:`/publish`,body:`The last tab, for once your app works for you: how to put it in front of other people, one step at a time — each step appears only when you tick the one before it, and a finished step folds under its checkmark and opens again with a click. Step 1 publishes it in AI Studio and saves the app name you chose there; step 2 connects your own domain through Google Cloud Run and saves the domain; step 3 adds both addresses as authorised domains in Firebase and verifies your email sender, handing you both addresses to copy. If your payments are still on practice cards, a fourth step sends you to Go live on the Payments screen — whose webhook step is the one waiting on step 3 here. Stuck anywhere? The email and WhatsApp buttons at the top reach me.`}],an=[{title:`One page or one form per message`,body:`Describe it completely, then send. Ask for the next one when the first is live.`},{title:`Let the Pages screen write the request`,body:`Describe the page on its row and paste the sentence it hands you. It answers every question the assistant would otherwise stop to ask.`},{title:`Use the exact words you want to see`,body:`Headings, button labels, choices in a list. The assistant copies them; it does not improve them.`},{title:`When something is wrong, describe your screen`,body:`The web address, what you clicked, what happened, what you expected. Not what you think the cause is.`},{title:`Never accept homework`,body:`The assistant makes every change itself. If a reply ends with something for you to edit, paste or run, answer: "Do that for me."`}],on=[{id:`how-it-works`,short:`How it all works`},{id:`add-a-page`,short:`Adding a page`},{id:`audiences`,short:`The four kinds of pages`},{id:`users`,short:`Letting people in`},{id:`theme`,short:`Changing the look`},{id:`yourself`,short:`Where everything lives`},{id:`habits`,short:`Working with the assistant`}];function sn({children:e}){return(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px] mb-3`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e]})}function cn({id:e,index:n,kicker:r,title:a,children:o}){return(0,i.jsxs)(t.fr.section,{id:e,initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{delay:.05+n*.03},className:`mb-16 scroll-mt-24`,children:[(0,i.jsx)(sn,{children:`0${n+1} · ${r}`}),(0,i.jsx)(`h2`,{className:`text-2xl font-extrabold tracking-tight text-foreground mb-3`,children:a}),o]})}function ln({children:e}){return(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/65 font-medium leading-relaxed max-w-2xl mb-4 last:mb-0`,children:e})}function un({steps:e}){return(0,i.jsx)(`ol`,{className:`mt-6`,children:e.map((t,n)=>(0,i.jsxs)(`li`,{className:`relative grid grid-cols-[2.25rem_1fr] gap-x-4 pb-8 last:pb-0`,children:[n<e.length-1&&(0,i.jsx)(`span`,{"aria-hidden":!0,className:`absolute left-[1.125rem] top-10 bottom-1 w-px -translate-x-1/2 bg-[var(--panel-border)]`}),(0,i.jsx)(`span`,{className:`flex h-9 w-9 items-center justify-center rounded-full border border-[var(--panel-border)] bg-[var(--panel-bg)] text-[13px] font-bold text-accent tabular-nums select-none`,children:n+1}),(0,i.jsxs)(`div`,{className:`pt-1.5 min-w-0`,children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-bold tracking-tight text-foreground`,children:t.title}),(0,i.jsx)(`p`,{className:`mt-1.5 text-[14px] text-foreground/65 font-medium leading-relaxed max-w-2xl`,children:t.body})]})]},t.title))})}function dn({lead:e,children:t}){return(0,i.jsx)(`div`,{className:`mt-7 border-l-2 border-accent/50 pl-4`,children:(0,i.jsxs)(`p`,{className:`text-[13.5px] text-foreground/60 font-medium leading-relaxed max-w-2xl`,children:[(0,i.jsx)(`strong`,{className:`font-bold text-foreground/85`,children:e}),` `,t]})})}function fn(){return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-3xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-10 text-center`,children:[(0,i.jsx)(Ce,{children:`Guide`}),(0,i.jsx)(`p`,{className:`text-foreground/60 text-[14px] md:text-[15px] font-medium max-w-2xl mx-auto`,children:`Everything you run yourself, everything your assistant builds for you, and the one recipe that makes every page. Ten minutes, start to finish.`})]}),(0,i.jsxs)(t.fr.section,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`mb-10`,children:[(0,i.jsx)(`div`,{className:`relative w-full rounded-2xl overflow-hidden border border-[var(--panel-border)] glass-panel`,children:(0,i.jsx)(`div`,{className:`relative w-full aspect-video`,children:(0,i.jsx)(`iframe`,{className:`absolute inset-0 w-full h-full`,src:`https://www.youtube-nocookie.com/embed/${Qt}?start=1`,title:`Watch the guide`,allow:`accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share`,allowFullScreen:!0,loading:`lazy`,referrerPolicy:`strict-origin-when-cross-origin`})})}),(0,i.jsx)(`p`,{className:`mt-3 text-center text-[12.5px] text-foreground/45 font-medium`,children:`Six minutes, from an empty project to a finished site.`})]}),(0,i.jsxs)(t.fr.nav,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{delay:.03},"aria-label":`In this guide`,className:`mb-14`,children:[(0,i.jsx)(sn,{children:`In this guide`}),(0,i.jsx)(`ol`,{className:`grid gap-x-10 gap-y-1.5 sm:grid-cols-2`,children:on.map((e,t)=>(0,i.jsx)(`li`,{children:(0,i.jsxs)(`a`,{href:`#${e.id}`,className:`group flex items-baseline gap-2.5 py-0.5 w-fit`,children:[(0,i.jsxs)(`span`,{className:`text-[11px] font-bold text-foreground/35 tabular-nums`,children:[`0`,t+1]}),(0,i.jsx)(`span`,{className:`text-[14px] font-semibold text-foreground/75 group-hover:text-accent transition-colors`,children:e.short})]})},e.id))})]}),(0,i.jsxs)(cn,{id:`how-it-works`,index:0,kicker:`Start here`,title:`How it all works`,children:[(0,i.jsx)(ln,{children:`Your site is a set of pages. Some are open to the world — that is your public website. The rest live in the dashboard, behind a sign-in: pages every registered person can open, pages only your team can open, and pages only admins can open.`}),(0,i.jsx)(ln,{children:`You run all of it from the admin screens in your menu — the Inbox and Users first, because they fill on their own, then Pages and the screens you set up once. Everything on those screens changes with a click and takes effect at once: names, addresses, colours, who counts as team, who counts as admin.`}),(0,i.jsxs)(ln,{children:[`What goes `,(0,i.jsx)(`em`,{className:`not-italic font-bold text-foreground/80`,children:`on`}),` a page is the one thing you do not click together — your assistant builds it. But you never have to work out what to say to it: when you describe a page on the Pages screen, the screen writes the whole request as one sentence. You copy that sentence, paste it into your assistant’s chat, and the page gets built. That copy-and-paste is the entire relationship, and the next chapter walks through it.`]})]}),(0,i.jsxs)(cn,{id:`add-a-page`,index:1,kicker:`The one recipe`,title:`How to add a page — any kind`,children:[(0,i.jsx)(ln,{children:`The same six steps make every page: a public one for your website, a board for your team, a table each signed-in person has to themselves. Never ask the chat to create a page out of nowhere — the Pages screen writes a better request than anyone types by hand.`}),(0,i.jsx)(un,{steps:$t}),(0,i.jsxs)(dn,{lead:`Not sure which layout to pick?`,children:[(0,i.jsx)(c.Link,{to:`/templates`,className:`text-accent font-bold hover:underline`,children:`Look through the templates`}),` `,`to see each one working before you choose.`]})]}),(0,i.jsxs)(cn,{id:`audiences`,index:2,kicker:`Who it is for`,title:`The four kinds of pages`,children:[(0,i.jsx)(ln,{children:`Every page is for exactly one audience: it decides who can open the page and which menu it appears in. A Tab starts as Members and its own row says who can open it — Members, Your team, Admins only, or a role of your own. These are the words printed there:`}),(0,i.jsx)(`div`,{className:`mt-6 space-y-6`,children:en.map(e=>(0,i.jsxs)(`div`,{children:[(0,i.jsxs)(`div`,{className:`flex items-baseline gap-2.5 flex-wrap`,children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-bold tracking-tight text-foreground`,children:e.name}),(0,i.jsx)(`span`,{className:`text-[12px] text-accent font-semibold`,children:e.where})]}),(0,i.jsx)(`p`,{className:`mt-1 text-[14px] text-foreground/65 font-medium leading-relaxed max-w-2xl`,children:e.who})]},e.name))}),(0,i.jsx)(dn,{lead:`Careful:`,children:`Registering only makes someone a Member, not a team member. Never put your team’s information on a page for Members — any stranger who registers could open it.`})]}),(0,i.jsxs)(cn,{id:`users`,index:3,kicker:`Letting people in`,title:`How users work`,children:[(0,i.jsx)(ln,{children:`People let themselves in at the front door; you decide who gets further.`}),(0,i.jsx)(un,{steps:tn})]}),(0,i.jsxs)(cn,{id:`theme`,index:4,kicker:`The look`,title:`How to change the theme`,children:[(0,i.jsxs)(ln,{children:[`The look is your assistant’s job, and your`,` `,(0,i.jsx)(c.Link,{to:`/theme`,className:`text-accent font-bold hover:underline`,children:`Theme screen`}),` `,`is where you brief it. There are no colour boxes to fill in: you say what you are after, copy one sentence, and the assistant designs the whole thing. Four steps:`]}),(0,i.jsx)(`div`,{className:`mt-6 space-y-6`,children:nn.map(e=>(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-bold tracking-tight text-foreground`,children:e.name}),(0,i.jsx)(`p`,{className:`mt-1 text-[14px] text-foreground/65 font-medium leading-relaxed max-w-2xl`,children:e.body})]},e.name))})]}),(0,i.jsxs)(cn,{id:`yourself`,index:5,kicker:`No assistant needed`,title:`Where everything lives`,children:[(0,i.jsx)(ln,{children:`These are switches and boxes in your admin screens. Asking the assistant for them only gets you sent here.`}),(0,i.jsx)(`div`,{className:`mt-6 space-y-6`,children:rn.map(e=>(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-bold tracking-tight w-fit`,children:(0,i.jsx)(c.Link,{to:e.path,className:`text-foreground hover:text-accent transition-colors`,children:e.screen})}),(0,i.jsx)(`p`,{className:`mt-1 text-[14px] text-foreground/65 font-medium leading-relaxed max-w-2xl`,children:e.body})]},e.screen))}),(0,i.jsx)(dn,{lead:`Good to know:`,children:`The Guide, Templates and Contact pages come with the app and are visible on purpose. Hide any of them on the Pages screen with the switch next to its name. Setup is not one of them: it is the walkthrough that connects your app to Firebase, it is finished before anybody signs in, and it is in no menu — type /setup after your address to open it, which is how you come back to re-paste the rules after an update.`})]}),(0,i.jsxs)(cn,{id:`habits`,index:6,kicker:`Five habits`,title:`Working with the assistant`,children:[(0,i.jsx)(ln,{children:`Five habits keep the assistant on track. There is nothing to memorise beyond them.`}),(0,i.jsx)(`div`,{className:`mt-6 space-y-6`,children:an.map(e=>(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-bold tracking-tight text-foreground`,children:e.title}),(0,i.jsx)(`p`,{className:`mt-1 text-[14px] text-foreground/65 font-medium leading-relaxed max-w-2xl`,children:e.body})]},e.title))})]})]})}function pn(){let[e,n]=(0,r.useState)({favoriteService:``,satisfactionRating:``,detailedThoughts:``}),[a,s]=(0,r.useState)(`idle`);return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col`,children:[(0,i.jsx)(`div`,{className:`w-full max-w-5xl mx-auto mb-6`,children:(0,i.jsx)(Wt,{to:`/templates`})}),(0,i.jsx)(`div`,{className:`w-full max-w-5xl mx-auto mt-6`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`w-full max-w-[500px] p-6 sm:p-8 lg:p-10 rounded-3xl md:rounded-3xl glass-form relative glow-hover shadow-[0_8px_32px_rgba(0,0,0,0.08)] z-10 mx-auto`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-30 blur-[20px] rounded-3xl md:rounded-3xl -z-10`}),(0,i.jsx)(`div`,{className:`relative z-10 w-full`,children:a===`success`?(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex flex-col items-center justify-center py-8 text-center`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-full bg-green-500/10 border border-green-500/20 flex items-center justify-center text-green-500 mb-4`,children:(0,i.jsx)(t.Ni,{className:`w-8 h-8`})}),(0,i.jsx)(`h4`,{className:`text-lg font-bold text-foreground mb-2`,children:`Simulation Complete!`}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/60 leading-relaxed`,children:`Your test data was sent successfully. Log in as an admin and open your Inbox to see it.`})]}):a===`loading`?(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:`flex flex-col items-center justify-center py-16 text-center`,children:[(0,i.jsx)(`div`,{className:`w-10 h-10 border-4 border-accent border-r-transparent rounded-full animate-spin mb-4`}),(0,i.jsx)(`h4`,{className:`text-lg font-bold text-foreground tracking-tight`,children:`Processing`}),(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/50 mt-1`,children:`Simulating submission...`})]}):(0,i.jsxs)(t.fr.div,{initial:{opacity:0},animate:{opacity:1},children:[(0,i.jsxs)(`div`,{className:`mb-6 text-center`,children:[(0,i.jsx)(`h3`,{className:`text-2xl sm:text-3xl font-extrabold mb-2 text-foreground tracking-tight break-words`,children:`Inline Form Template`}),(0,i.jsx)(`p`,{className:`text-[14px] md:text-[15px] font-medium text-foreground/60 tracking-wide leading-relaxed`,children:`Try interacting with this simulated inline template block.`})]}),(0,i.jsxs)(`form`,{onSubmit:async r=>{r.preventDefault(),s(`loading`);try{let r=t.Ea.currentUser?.uid||`guest`;await(0,o.addDoc)((0,o.collection)(t.Da,`user_submissions`),{uid:r,...e,type:`template_simulation`,submittedAt:(0,o.serverTimestamp)()}),s(`success`),setTimeout(()=>{s(`idle`),n({favoriteService:``,satisfactionRating:``,detailedThoughts:``})},3e3)}catch{s(`error`)}},className:`space-y-4 w-full`,children:[(0,i.jsx)(t.lr,{label:`Favorite Service`,placeholder:`e.g. Design Consulting`,value:e.favoriteService,onChange:t=>n({...e,favoriteService:t.target.value})}),(0,i.jsx)(t.lr,{label:`Satisfaction Rating`,type:`number`,placeholder:`1 to 10`,value:e.satisfactionRating,onChange:t=>n({...e,satisfactionRating:t.target.value})}),(0,i.jsxs)(`div`,{className:`flex flex-col w-full relative`,children:[(0,i.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,children:`Detailed Thoughts`}),(0,i.jsx)(`textarea`,{rows:3,placeholder:`Type something here...`,value:e.detailedThoughts,onChange:t=>n({...e,detailedThoughts:t.target.value}),className:`flex w-full rounded-xl text-[15px] text-foreground px-4 py-3 transition-all duration-300 placeholder:text-foreground/40 focus:outline-none focus:border-accent glow-focus disabled:cursor-not-allowed disabled:opacity-50 glass-panel min-h-[100px] resize-none`})]}),(0,i.jsx)(`div`,{className:`pt-2`,children:(0,i.jsx)(t.cr,{type:`submit`,className:`w-full px-6 md:px-8 py-3 md:py-3.5 rounded-xl font-semibold tracking-wide btn-primary text-[15px] shadow-xl transition-all duration-300 hover:-translate-y-1 active:scale-95 flex items-center justify-center`,isLoading:!1,children:`Trigger Simulation`})})]})]})})]})})]})}function mn(){let[e,n]=(0,r.useState)(!1),[a,s]=(0,r.useState)({concept:``,featureRequest:``,notes:``}),[c,l]=(0,r.useState)(`idle`);return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4`,children:[(0,i.jsx)(`div`,{className:`mb-3`,children:(0,i.jsx)(Wt,{to:`/templates`})}),(0,i.jsx)(Ce,{children:`Popup Form`}),(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/popup_form`]})]}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden shadow-2xl relative flex flex-col w-full min-h-[150px] p-6 lg:p-10`,children:[(0,i.jsx)(`div`,{className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[800px] h-[800px] bg-accent/5 blur-[120px] rounded-full pointer-events-none -z-10`}),(0,i.jsxs)(`div`,{className:`flex flex-col sm:flex-row h-full w-full gap-4 sm:gap-6 justify-between sm:items-center relative z-10`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-xl md:text-2xl font-extrabold text-foreground tracking-tight mb-2`,children:`A form in a pop-up`}),(0,i.jsx)(`p`,{className:`text-[13px] md:text-[14px] text-foreground/60 font-medium leading-relaxed max-w-md`,children:`The page stays where it is and the form opens over it, with the background blurred. Close it and nothing is lost.`})]}),(0,i.jsxs)(t.cr,{onClick:()=>n(!0),className:`px-6 py-2.5 text-[14px] font-bold rounded-xl shadow-lg flex items-center justify-center gap-2 btn-primary transition-all hover:-translate-y-1 shrink-0`,children:[(0,i.jsx)(t.Ur,{className:`w-4 h-4`}),` Open Form`]})]})]}),(0,i.jsx)(t.pr,{children:e&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[100] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-xl cursor-pointer`,onClick:()=>n(!1)}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`w-full max-w-[500px] p-6 sm:p-8 lg:p-10 rounded-3xl md:rounded-3xl glass-popover relative shadow-[0_8px_32px_rgba(0,0,0,0.08)] z-10 mx-4 max-h-[95vh] overflow-y-auto no-scrollbar`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-30 blur-[20px] rounded-3xl md:rounded-3xl -z-10`}),(0,i.jsxs)(`div`,{className:`relative z-10 w-full`,children:[(0,i.jsx)(`button`,{onClick:()=>n(!1),className:`absolute -top-2 -right-2 w-8 h-8 flex items-center justify-center rounded-full hover:bg-foreground/5 text-foreground/60 hover:text-foreground transition-colors z-20`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})}),c===`success`?(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex flex-col items-center justify-center py-12 text-center`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-full bg-green-500/10 border border-green-500/20 flex items-center justify-center text-green-500 mb-4`,children:(0,i.jsx)(t.Ni,{className:`w-8 h-8`})}),(0,i.jsx)(`h4`,{className:`text-xl font-bold text-foreground mb-2`,children:`Simulation Complete!`}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/60 leading-relaxed max-w-[280px]`,children:`Your test data was sent successfully. Log in as an admin and open your Inbox to see it.`})]}):c===`loading`?(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:`flex flex-col items-center justify-center py-16 text-center`,children:[(0,i.jsx)(`div`,{className:`w-10 h-10 border-4 border-accent border-r-transparent rounded-full animate-spin mb-4`}),(0,i.jsx)(`h4`,{className:`text-lg font-bold text-foreground tracking-tight`,children:`Processing`}),(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/50 mt-1`,children:`Simulating submission...`})]}):(0,i.jsxs)(t.fr.div,{initial:{opacity:0},animate:{opacity:1},children:[(0,i.jsxs)(`div`,{className:`mb-6 text-center`,children:[(0,i.jsx)(`h3`,{className:`text-2xl sm:text-3xl font-extrabold mb-2 text-foreground tracking-tight break-words`,children:`Popup Template`}),(0,i.jsx)(`p`,{className:`text-[14px] md:text-[15px] font-medium text-foreground/60 tracking-wide leading-relaxed`,children:`Fill out the simulated fields below to test the interaction.`})]}),(0,i.jsxs)(`form`,{onSubmit:async e=>{e.preventDefault(),l(`loading`);try{let e=t.Ea.currentUser?.uid||`guest`;await(0,o.addDoc)((0,o.collection)(t.Da,`user_submissions`),{uid:e,...a,type:`template_simulation`,submittedAt:(0,o.serverTimestamp)()}),l(`success`),setTimeout(()=>{l(`idle`),s({concept:``,featureRequest:``,notes:``}),n(!1)},3e3)}catch{l(`error`)}},className:`space-y-4 w-full`,children:[(0,i.jsx)(t.lr,{label:`Concept Name`,placeholder:`e.g. Project Apollo`,value:a.concept,onChange:e=>s({...a,concept:e.target.value})}),(0,i.jsx)(t.lr,{label:`Feature Request`,placeholder:`e.g. Real-time sync`,value:a.featureRequest,onChange:e=>s({...a,featureRequest:e.target.value})}),(0,i.jsxs)(`div`,{className:`flex flex-col w-full relative`,children:[(0,i.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,children:`Simulated Notes`}),(0,i.jsx)(`textarea`,{rows:3,placeholder:`Type something here...`,value:a.notes,onChange:e=>s({...a,notes:e.target.value}),className:`flex w-full rounded-xl text-[15px] text-foreground px-4 py-3 transition-all duration-300 placeholder:text-foreground/40 focus:outline-none focus:border-accent glow-focus disabled:cursor-not-allowed disabled:opacity-50 glass-panel min-h-[100px] resize-none`})]}),(0,i.jsx)(`div`,{className:`pt-2`,children:(0,i.jsx)(t.cr,{type:`submit`,className:`w-full px-6 md:px-8 py-3 md:py-3.5 rounded-xl font-semibold tracking-wide btn-primary text-[15px] shadow-xl transition-all duration-300 hover:-translate-y-1 active:scale-95 flex items-center justify-center`,isLoading:!1,children:`Trigger Simulation`})})]})]})]})]})]})})]})}var hn=e=>({creatorName:e?.displayName||e?.email?.split(`@`)[0]||``,creatorAvatar:e?.photoURL||``}),gn=(e,t)=>{if(e?.creatorName)return{name:e.creatorName,avatar:e.creatorAvatar||``};if(e?.uid&&t?.uid&&e.uid===t.uid){let e=hn(t);return e.creatorName?{name:e.creatorName,avatar:e.creatorAvatar}:null}return null},_n=[{text:`text-red-400`,bgCircle:`bg-red-400`,bgCard:`bg-red-500/[0.08]`,borderCard:`border-red-500/30`,bgLight:`bg-red-500/15`,bgHover:`hover:bg-red-500`,bgAlt:`bg-red-500/[0.04]`,name:`Red`},{text:`text-orange-400`,bgCircle:`bg-orange-400`,bgCard:`bg-orange-500/[0.08]`,borderCard:`border-orange-500/30`,bgLight:`bg-orange-500/15`,bgHover:`hover:bg-orange-500`,bgAlt:`bg-orange-500/[0.04]`,name:`Orange`},{text:`text-yellow-400`,bgCircle:`bg-yellow-400`,bgCard:`bg-yellow-500/[0.08]`,borderCard:`border-yellow-500/30`,bgLight:`bg-yellow-500/15`,bgHover:`hover:bg-yellow-500`,bgAlt:`bg-yellow-500/[0.04]`,name:`Yellow`},{text:`text-green-400`,bgCircle:`bg-green-400`,bgCard:`bg-green-500/[0.08]`,borderCard:`border-green-500/30`,bgLight:`bg-green-500/15`,bgHover:`hover:bg-green-500`,bgAlt:`bg-green-500/[0.04]`,name:`Green`},{text:`text-blue-400`,bgCircle:`bg-blue-400`,bgCard:`bg-blue-500/[0.08]`,borderCard:`border-blue-500/30`,bgLight:`bg-blue-500/15`,bgHover:`hover:bg-blue-500`,bgAlt:`bg-blue-500/[0.04]`,name:`Blue`},{text:`text-accent`,bgCircle:`bg-accent`,bgCard:`bg-accent/[0.08]`,borderCard:`border-accent/30`,bgLight:`bg-accent/15`,bgHover:`hover:bg-accent`,bgAlt:`bg-accent/[0.04]`,name:`Purple`},{text:`text-pink-400`,bgCircle:`bg-pink-400`,bgCard:`bg-pink-500/[0.08]`,borderCard:`border-pink-500/30`,bgLight:`bg-pink-500/15`,bgHover:`hover:bg-pink-500`,bgAlt:`bg-pink-500/[0.04]`,name:`Pink`},{text:`text-foreground/60`,bgCircle:`bg-foreground/30`,bgCard:`bg-foreground/[0.04]`,borderCard:`border-[var(--panel-border)]/50`,bgLight:`bg-foreground/15`,bgHover:`hover:bg-foreground/30`,bgAlt:`bg-foreground/[0.02]`,name:`Default`}];function vn({title:e=`Board View`,subtitle:n=`/board`,backUrl:a=`/templates`,tasksCollection:s=`pub_tasks`,categoriesCollection:c=`pub_categories`,config:l,customContent:u}){let{user:d}=t.na(),f=!!l,p=l?.isInternal||l?.isShared;l?.isPrivate&&l?.isAdmin;let m=l?.isAdmin||p,h=f?m||s.startsWith(`role_`):!0,g=(e,t,n,r)=>d?e.startsWith(`user_`)?{...t,uid:d.uid}:n?{uid:d.uid,...r?hn(d):{},...t}:t:t,_=!!u,v=l?.showButton!==!1&&!_,y=l?.buttonText||`+`,b=l?.buttonStyle||`primary`,x=l?.keyName||`key`,S=l?.valueName||`value`,[C,w]=(0,r.useState)([]),[T,E]=(0,r.useState)([]),[D,O]=(0,r.useState)(null),[k,A]=(0,r.useState)(null),[j,M]=(0,r.useState)({name:``}),[N,P]=(0,r.useState)([]),[F,I]=(0,r.useState)(null),[L,R]=(0,r.useState)(null),[z,B]=(0,r.useState)(null),[V,H]=(0,r.useState)(null),[U,W]=(0,r.useState)(!1),[G,ee]=(0,r.useState)(null),[K,q]=(0,r.useState)(``),[J,Y]=(0,r.useState)(null);(0,r.useEffect)(()=>{let e=s.startsWith(`user_`),n=c.startsWith(`user_`);if(e&&!d)return;try{let e=localStorage.getItem(`fbos_board_tasks_${s}`);e&&w(JSON.parse(e));let t=localStorage.getItem(`fbos_board_cats_${c}`);t&&E(JSON.parse(t))}catch{}let r=(0,o.onSnapshot)(e&&d?(0,o.query)((0,o.collection)(t.Da,s),(0,o.where)(`uid`,`==`,d.uid)):(0,o.collection)(t.Da,s),e=>{let t=[];e.forEach(e=>{let n=e.data();t.push({id:e.id,categoryId:n.categoryId,name:n.name||n.text||`Unnamed Item`,fields:n.fields||(n.value?[{key:`Label`,value:n.value}]:[]),order:n.order||0,uid:n.uid,creatorName:n.creatorName,creatorAvatar:n.creatorAvatar})});let n=t.sort((e,t)=>(e.order||0)-(t.order||0));w(n),localStorage.setItem(`fbos_board_tasks_${s}`,JSON.stringify(n))}),i=(0,o.onSnapshot)(n&&d?(0,o.query)((0,o.collection)(t.Da,c),(0,o.where)(`uid`,`==`,d.uid)):(0,o.collection)(t.Da,c),e=>{let r=[];if(e.forEach(e=>{r.push({id:e.id,...e.data()})}),r.length===0){let e=[{id:`todo`,title:`To Do`,createdAt:Date.now()-2e3},{id:`in_progress`,title:`In Progress`,createdAt:Date.now()-1e3},{id:`review`,title:`Review`,createdAt:Date.now()}],r=d?{uid:d.uid}:{},i=n&&d?`_${d.uid}`:``;e.forEach(e=>(0,o.setDoc)((0,o.doc)(t.Da,c,`${e.id}${i}`),{...r,title:e.title,createdAt:e.createdAt}))}else E(r),localStorage.setItem(`fbos_board_cats_${c}`,JSON.stringify(r))});return()=>{r(),i()}},[s,c,d]);let te=(e,t)=>{t?(A(t.id),M({id:t.id,name:t.name}),P(t.fields?.length?[...t.fields,{key:``,value:``}]:[{key:``,value:``}])):(O(e),M({name:``}),P([{key:``,value:``}]))},ne=(e,t,n)=>{let r=[...N];r[e]={key:t,value:n},e===N.length-1&&(t.trim()!==``||n.trim()!==``)&&r.push({key:``,value:``}),P(r)},re=(e,t)=>{e.dataTransfer.effectAllowed=`move`,e.dataTransfer.setData(`taskId`,t),I(t)},X=(e,t)=>{e.preventDefault(),e.stopPropagation(),t!==F&&R(t)},Z=(e,t)=>{e.preventDefault(),e.stopPropagation(),B(t)},Q=e=>{e.preventDefault(),R(null),B(null)},ie=async(e,n,r)=>{e.preventDefault(),e.stopPropagation(),R(null),B(null);let i=e.dataTransfer.getData(`taskId`);if(!i||i===r){I(null);return}let a=C.find(e=>e.id===i);if(!a)return;let c=C.filter(e=>e.categoryId===n).sort((e,t)=>(e.order||0)-(t.order||0));if(a.categoryId===n?(c=c.filter(e=>e.id!==i),c.push(a)):c.push({...a,categoryId:n}),r){let e=c.findIndex(e=>e.id===r),t=c.findIndex(e=>e.id===i),[n]=c.splice(t,1);c.splice(e,0,n)}c.forEach((e,r)=>{let i={categoryId:n,order:r};d&&s.startsWith(`user_`)&&(i.uid=d.uid),(0,o.setDoc)((0,o.doc)(t.Da,s,e.id),i,{merge:!0})}),I(null)},ae=async e=>{let n=j.id||`item_${Date.now()}`,r=j.name.trim(),i=r||`Untitled Item`,a=N.filter(e=>e.key.trim()!==``||e.value.trim()!==``),c=!0,l=j.id?C.find(e=>e.id===j.id):null;if(l){let e=JSON.stringify(l.fields||[]),t=JSON.stringify(a);l.name===i&&e===t&&(c=!1)}else !r&&a.length===0&&(c=!1);if(!c){O(null),A(null);return}H(j.id||`new`);let u={categoryId:e,name:i,fields:a};d&&!j.id&&Object.assign(u,{uid:d.uid},hn(d)),await(0,o.setDoc)((0,o.doc)(t.Da,s,n),u,{merge:!0}),setTimeout(()=>{O(null),A(null),H(null)},400)},oe=(e,t)=>{Y({type:`item`,id:e,title:t})},se=async()=>{let e=`cat_${Date.now()}`,n={title:``,createdAt:Date.now()};d&&(n.uid=d.uid),await(0,o.setDoc)((0,o.doc)(t.Da,c,e),n),ee(e),q(``),setTimeout(()=>{let e=document.getElementById(`board-container`);e&&e.scrollTo({left:e.scrollWidth,behavior:`smooth`})},150)},ce=async(e,n)=>{E(t=>t.map(t=>t.id===e?{...t,color:n}:t)),await(0,o.setDoc)((0,o.doc)(t.Da,c,e),{color:n},{merge:!0})},le=async e=>{K.trim()?await(0,o.setDoc)((0,o.doc)(t.Da,c,e),{title:K},{merge:!0}):await(0,o.deleteDoc)((0,o.doc)(t.Da,c,e)),ee(null)},ue=(e,t)=>{Y({type:`category`,id:e,title:t})},de=async()=>{if(J){W(!0);try{if(J.type===`item`)await(0,o.deleteDoc)((0,o.doc)(t.Da,s,J.id)),A(null);else{let e=C.filter(e=>e.categoryId===J.id);for(let n of e)await(0,o.deleteDoc)((0,o.doc)(t.Da,s,n.id));await(0,o.deleteDoc)((0,o.doc)(t.Da,c,J.id))}}catch{}W(!1),Y(null)}},fe=[...T].sort((e,t)=>(e.createdAt||0)-(t.createdAt||0));return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen overflow-x-hidden`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[!f&&a&&(0,i.jsx)(Wt,{to:a}),(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(Ce,{children:e}),n&&(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),n]})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 min-h-0 pb-16`,children:[f&&(0,i.jsx)(Fe,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 min-h-[400px] shadow-2xl bg-background relative z-10`,children:[(0,i.jsx)(`div`,{className:`absolute top-0 right-0 w-[400px] h-[400px] bg-accent/5 blur-[100px] rounded-full pointer-events-none -z-10`}),(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4 p-4 sm:p-6 md:px-8 md:py-6 border-b border-[var(--panel-border)]/50 bg-background/50 shrink-0 relative z-20`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-lg sm:text-xl font-extrabold text-foreground tracking-tight truncate`,children:l?.tabTitle||l?.tabName||e}),(0,i.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:[C.length,` `,C.length===1?`item`:`items`,` · `,fe.length,` `,fe.length===1?`category`:`categories`]})]}),v&&(0,i.jsx)(t.cr,{variant:b===`secondary`?`secondary`:void 0,onClick:se,className:`px-3 py-2.5 text-[14px] font-bold rounded-xl shadow-lg hover:-translate-y-0.5 transition-all shrink-0`,children:y===`+`?(0,i.jsx)(t.Ur,{className:`w-4 h-4`}):y})]}),(0,i.jsx)(`div`,{className:`flex-1 w-full relative z-40 min-h-0 flex flex-col`,children:u?(0,i.jsx)(`div`,{className:`fbos-content-slot w-full flex-1 overflow-y-auto p-4 md:p-6`,children:(0,i.jsx)(u,{config:l,actions:{tasks:C,categories:T,collection:s,catCollection:c,user:d,saveTask:async(e,n)=>{let r=e||`item_${Date.now()}`,i=g(s,n,!C.some(e=>e.id===r),!0);w(e=>e.find(e=>e.id===r)?e.map(e=>e.id===r?{...e,...i}:e):[...e,{id:r,...i}]),await(0,o.setDoc)((0,o.doc)(t.Da,s,r),i,{merge:!0})},deleteTask:async e=>{w(t=>t.filter(t=>t.id!==e)),await(0,o.deleteDoc)((0,o.doc)(t.Da,s,e))},saveCategory:async(e,n)=>{let r=g(c,n,!T.some(t=>t.id===e),!1);E(t=>t.find(t=>t.id===e)?t.map(t=>t.id===e?{...t,...r}:t):[...t,{id:e,...r}]),await(0,o.setDoc)((0,o.doc)(t.Da,c,e),r,{merge:!0})},deleteCategory:async e=>{E(t=>t.filter(t=>t.id!==e)),await(0,o.deleteDoc)((0,o.doc)(t.Da,c,e))},openInlineEditor:(e,t)=>te(e,t)}})}):(0,i.jsxs)(`div`,{id:`board-container`,className:`w-full flex-1 min-h-0 flex flex-row gap-4 md:gap-6 overflow-x-auto p-4 md:p-6 snap-x snap-mandatory styled-scrollbars items-start`,children:[fe.map((e,n)=>{let r=C.filter(t=>t.categoryId===e.id);r.sort((e,t)=>(e.order||0)-(t.order||0));let a=_n.find(t=>t.text===e.color)||_n.find(e=>e.text===`text-accent`);return a.text,a.bgLight,a.bgHover,(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:n*.1},className:`w-[calc(100vw-80px)] sm:w-[300px] md:w-[320px] shrink-0 flex flex-col max-h-full rounded-3xl p-4 snap-center relative border transition-colors ${_n.find(t=>t.text===e.color)?.bgCard||`bg-foreground/[0.02]`} ${_n.find(t=>t.text===e.color)?.borderCard||`border-[var(--panel-border)]/50`}`,children:[(0,i.jsx)(`div`,{className:`flex items-center justify-between mb-4 px-2 relative z-[200]`,children:(0,i.jsxs)(`h3`,{className:`font-bold text-[14px] flex items-center w-full text-foreground/80 group relative z-[200]`,children:[G===e.id?(0,i.jsxs)(`div`,{className:`relative flex-1 w-full flex items-center pr-8 z-[200]`,children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-[-1]`,onClick:t=>{t.stopPropagation(),le(e.id)}}),(0,i.jsx)(`input`,{value:K,onChange:e=>q(e.target.value),onBlur:t=>{t.relatedTarget?.closest(`.category-color-picker`)||le(e.id)},onKeyDown:t=>t.key===`Enter`&&le(e.id),className:`bg-transparent border-none outline-none font-bold text-[14px] w-full p-0 ${e.color||`text-foreground/80`}`,placeholder:`Category name`,autoFocus:!0}),(0,i.jsxs)(`div`,{className:`absolute top-8 left-0 flex gap-1.5 bg-background/95 backdrop-blur-xl border border-[var(--panel-border)] p-2 rounded-xl shadow-xl z-[100] category-color-picker items-center`,tabIndex:-1,children:[(0,i.jsx)(`button`,{onClick:async t=>{t.preventDefault(),t.stopPropagation(),await ce(e.id,``),ee(null)},className:`w-4 h-4 rounded-full flex items-center justify-center bg-foreground/10 hover:bg-red-500/20 hover:text-red-500 text-foreground/40 transition-colors border border-[var(--panel-border)]/50 shrink-0`,title:`Reset Category Color`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})}),(0,i.jsx)(`div`,{className:`h-4 w-px bg-[var(--panel-border)]/50 mx-0.5`}),_n.map(t=>(0,i.jsx)(`button`,{onMouseDown:async n=>{n.preventDefault(),await ce(e.id,t.text)},className:`w-4 h-4 rounded-full ${t.bgCircle} hover:scale-125 transition-transform border border-[var(--panel-border)]/50 shrink-0`},t.name))]})]}):(0,i.jsxs)(`div`,{className:`flex items-center gap-2 w-full cursor-pointer hover:text-foreground transition-colors pr-8`,onClick:()=>{ee(e.id),q(e.title)},children:[(0,i.jsx)(`span`,{className:`w-2.5 h-2.5 rounded-full ${_n.find(t=>t.text===e.color)?.bgCircle||`bg-foreground/20`} transition-colors shrink-0`}),(0,i.jsx)(`span`,{className:`truncate flex-1 max-w-[200px] ${e.color||``}`,children:e.title||`Untitled Category`}),(0,i.jsx)(`span`,{className:`text-[11px] bg-foreground/10 text-foreground/60 px-1.5 py-0.5 rounded-md font-medium shrink-0`,children:r.length})]}),T.length>1&&(0,i.jsx)(`button`,{onClick:()=>ue(e.id,e.title),className:`absolute right-0 opacity-100 md:opacity-0 md:group-hover:opacity-100 text-foreground/30 hover:text-red-500 transition-all shrink-0`,children:(0,i.jsx)(t.Dr,{className:`w-3.5 h-3.5`})})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2.5 flex-1 overflow-y-auto styled-scrollbars pr-1 relative min-h-[150px] rounded-xl transition-all ${z===e.id&&!L?`bg-foreground/5 scale-[1.01] border-dashed border border-accent/20`:``}`,onDragOver:t=>Z(t,e.id),onDragLeave:Q,onDrop:t=>ie(t,e.id),children:[(0,i.jsx)(t.pr,{children:r.map(n=>k===n.id?(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:`bg-background/80 rounded-xl p-3 shadow-md border border-accent/40 transition-all flex flex-col gap-2 relative z-[100]`,children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-[-1]`,onClick:t=>{t.stopPropagation(),ae(e.id)}}),(0,i.jsx)(`textarea`,{placeholder:`Write an item name...`,className:`no-glow bg-transparent border-none outline-none text-[13px] text-foreground/90 font-medium leading-snug resize-none w-full min-h-[40px] relative z-10`,value:j.name,onChange:e=>M({...j,name:e.target.value}),onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),ae(e.id))}}),(0,i.jsx)(`div`,{className:`flex flex-col gap-2 mt-1 relative z-10 w-full`,children:N.map((t,n)=>(0,i.jsxs)(`div`,{className:`flex items-start bg-foreground/[0.04] border border-[var(--panel-border)]/50 rounded-[8px] px-2.5 py-1.5 w-full`,children:[(0,i.jsx)(`input`,{placeholder:x,value:t.key,onChange:e=>ne(n,e.target.value,t.value),onKeyDown:t=>t.key===`Enter`&&ae(e.id),className:`no-glow bg-transparent outline-none text-[11px] text-foreground/50 font-bold placeholder:text-foreground/30 relative top-[1px] shrink-0`,style:{width:`${Math.max(3,t.key.length||x.length)}ch`}}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/50 font-bold mr-1.5 relative top-[1px]`,children:`:`}),(0,i.jsx)(`textarea`,{rows:1,placeholder:S,value:t.value,onChange:e=>ne(n,t.key,e.target.value),onInput:e=>{let t=e.target;t.style.height=`auto`,t.style.height=t.scrollHeight+`px`},onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),ae(e.id))},className:`no-glow bg-transparent outline-none text-[12px] text-foreground/90 font-medium flex-1 min-w-[40px] placeholder:opacity-40 resize-none overflow-hidden leading-tight relative top-[1px]`})]},n))}),V===n.id&&(0,i.jsx)(`div`,{className:`flex items-center justify-end pt-1`,children:(0,i.jsx)(`div`,{className:`w-3 h-3 border-2 border-accent border-t-transparent rounded-full animate-spin`})})]},n.id):(0,i.jsxs)(t.fr.div,{draggable:!0,onDragStart:e=>re(e,n.id),onDragOver:e=>X(e,n.id),onDragLeave:Q,onDrop:t=>ie(t,e.id,n.id),initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:`bg-background/80 rounded-xl p-3 shadow-sm hover:shadow-md cursor-grab active:cursor-grabbing hover:border-accent/40 transition-all group flex flex-col gap-2 relative z-10 border ${L===n.id?`border-accent border-t-2 translate-y-1`:`border-[var(--panel-border)]`} ${F===n.id?`opacity-30 scale-95 border-dashed border-2`:``}`,children:[(0,i.jsxs)(`div`,{className:`absolute top-2 right-2 flex items-center gap-1.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity bg-background/90 backdrop-blur-md border border-[var(--panel-border)] rounded-lg p-1 z-20 shadow-md`,children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),te(e.id,n)},className:`p-1 hover:bg-foreground/5 rounded-md text-foreground/60 hover:text-accent transition-colors`,children:(0,i.jsx)(t.Kr,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`button`,{onClick:e=>{e.stopPropagation(),oe(n.id,n.name)},className:`p-1 hover:bg-red-500/10 rounded-md text-foreground/60 hover:text-red-500 transition-colors`,children:(0,i.jsx)(t.Dr,{className:`w-3.5 h-3.5`})})]}),(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/90 font-medium leading-snug break-words pr-12`,children:n.name}),n.fields&&n.fields.length>0&&(0,i.jsx)(`div`,{className:`flex flex-row flex-wrap gap-2 mt-2`,children:n.fields.map((e,t)=>(0,i.jsxs)(`div`,{className:`inline-flex bg-foreground/[0.04] border border-[var(--panel-border)]/50 rounded-[8px] px-2.5 py-1.5 max-w-full`,children:[(0,i.jsxs)(`span`,{className:`text-[11px] text-foreground/50 font-bold mr-1.5 relative -top-[1px] shrink-0 break-all`,children:[e.key,`:`]}),(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/90 font-medium break-words leading-tight min-w-0`,children:e.value})]},t))}),(0,i.jsxs)(`div`,{className:`flex items-end justify-between mt-3 pt-3 border-t border-[var(--panel-border)]/50 w-full gap-2`,children:[(()=>{let e=h&&f?gn(n,d):null;return e?(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 pr-2 border-r border-[var(--panel-border)] border-dashed mr-auto`,children:[e.avatar?(0,i.jsx)(`img`,{src:e.avatar,className:`w-4 h-4 rounded-full shrink-0 object-cover`}):(0,i.jsx)(`div`,{className:`w-4 h-4 rounded-full bg-accent/20 text-accent flex items-center justify-center text-[9px] font-bold shrink-0`,children:e.name[0].toUpperCase()}),(0,i.jsx)(`span`,{className:`text-[10px] font-bold text-foreground/60 truncate max-w-[80px]`,children:e.name})]}):(0,i.jsx)(`div`,{className:`flex items-center gap-2 pr-2 border-r border-[var(--panel-border)] border-dashed mr-auto`})})(),(0,i.jsx)(`span`,{className:`text-[10px] text-foreground/40 font-bold text-right pt-0.5 shrink-0 max-w-[50%] truncate flex-1`,children:n.id.startsWith(`item_`)?new Date(parseInt(n.id.split(`_`)[1])).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`}):`Recently Added`})]})]},n.id))}),D===e.id?(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:`bg-background/80 rounded-xl p-3 shadow-md border border-accent/40 transition-all flex flex-col gap-2 relative z-[100] mt-1`,children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-[-1]`,onClick:t=>{t.stopPropagation(),ae(e.id)}}),(0,i.jsx)(`textarea`,{placeholder:`Write an item name...`,className:`no-glow bg-transparent border-none outline-none text-[13px] text-foreground/90 font-medium leading-snug resize-none w-full min-h-[40px] relative z-10`,value:j.name,onChange:e=>M({...j,name:e.target.value}),onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),ae(e.id))},autoFocus:!0}),(0,i.jsx)(`div`,{className:`flex flex-col gap-2 mt-1 relative z-10 w-full`,children:N.map((t,n)=>(0,i.jsxs)(`div`,{className:`flex items-start bg-foreground/[0.04] border border-[var(--panel-border)]/50 rounded-[8px] px-2.5 py-1.5 w-full`,children:[(0,i.jsx)(`input`,{placeholder:x,style:{width:`${Math.max(3,t.key.length||x.length)}ch`},value:t.key,onChange:e=>ne(n,e.target.value,t.value),onKeyDown:t=>t.key===`Enter`&&ae(e.id),className:`no-glow bg-transparent outline-none text-[11px] text-foreground/50 font-bold placeholder:text-foreground/30 relative top-[1px]`}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/50 font-bold mr-1.5 relative top-[1px]`,children:`:`}),(0,i.jsx)(`textarea`,{rows:1,placeholder:S,value:t.value,onChange:e=>ne(n,t.key,e.target.value),onInput:e=>{let t=e.target;t.style.height=`auto`,t.style.height=t.scrollHeight+`px`},onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),ae(e.id))},className:`no-glow bg-transparent outline-none text-[12px] text-foreground/90 font-medium flex-1 min-w-[40px] placeholder:opacity-40 resize-none overflow-hidden leading-tight relative top-[1px]`})]},n))}),V===`new`&&(0,i.jsx)(`div`,{className:`flex items-center justify-end pt-1`,children:(0,i.jsx)(`div`,{className:`w-3 h-3 border-2 border-accent border-t-transparent rounded-full animate-spin`})})]}):(0,i.jsxs)(`button`,{onClick:()=>te(e.id),className:`flex items-center gap-2 justify-center w-full py-2.5 mt-1 rounded-xl border border-transparent text-[12px] font-bold text-foreground/40 hover:text-foreground hover:bg-foreground/[0.03] transition-all shrink-0`,children:[(0,i.jsx)(t.Ur,{className:`w-4 h-4`}),` Add Item`]})]})]},e.id)}),(0,i.jsx)(`div`,{className:`w-[10px] shrink-0 pointer-events-none`})]})})]})]}),(0,i.jsx)(`style`,{children:`.styled-scrollbars::-webkit-scrollbar { width: 6px; height: 6px; } .styled-scrollbars::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--accent-color) 20%, transparent); border-radius: 4px; } .styled-scrollbars::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--accent-color) 40%, transparent); }`}),(0,i.jsx)(Ve,{isOpen:!!J,title:`Confirm Deletion`,message:(0,i.jsxs)(i.Fragment,{children:[`Are you sure you want to delete `,(0,i.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:J?.title}),` This action is permanent.`]}),onConfirm:de,onCancel:()=>Y(null),isProcessing:U,confirmText:`Yes, Delete`})]})}function yn(e){return Array.isArray?Array.isArray(e):kn(e)===`[object Array]`}function bn(e){if(typeof e==`string`)return e;if(typeof e==`bigint`)return e.toString();let t=e+``;return t==`0`&&1/e==-1/0?`-0`:t}function xn(e){return e==null?``:bn(e)}function Sn(e){return typeof e==`string`}function Cn(e){return typeof e==`number`}function wn(e){return e===!0||e===!1||En(e)&&kn(e)==`[object Boolean]`}function Tn(e){return typeof e==`object`}function En(e){return Tn(e)&&e!==null}function Dn(e){return e!=null}function On(e){return!e.trim().length}function kn(e){return e==null?e===void 0?`[object Undefined]`:`[object Null]`:Object.prototype.toString.call(e)}var An=`Incorrect 'index' type`,jn=e=>`Invalid value for key ${e}`,Mn=e=>`Pattern length exceeds max of ${e}.`,Nn=e=>`Missing ${e} property in key`,Pn=e=>`Property 'weight' in key '${e}' must be a positive integer`,Fn=Object.prototype.hasOwnProperty,In=class{constructor(e){this._keys=[],this._keyMap={};let t=0;e.forEach(e=>{let n=Ln(e);this._keys.push(n),this._keyMap[n.id]=n,t+=n.weight}),this._keys.forEach(e=>{e.weight/=t})}get(e){return this._keyMap[e]}keys(){return this._keys}toJSON(){return JSON.stringify(this._keys)}};function Ln(e){let t=null,n=null,r=null,i=1,a=null;if(Sn(e)||yn(e))r=e,t=Rn(e),n=zn(e);else{if(!Fn.call(e,`name`))throw Error(Nn(`name`));let o=e.name;if(r=o,Fn.call(e,`weight`)&&(i=e.weight,i<=0))throw Error(Pn(o));t=Rn(o),n=zn(o),a=e.getFn}return{path:t,id:n,weight:i,src:r,getFn:a}}function Rn(e){return yn(e)?e:e.split(`.`)}function zn(e){return yn(e)?e.join(`.`):e}function Bn(e,t){let n=[],r=!1,i=(e,t,a,o)=>{if(Dn(e))if(!t[a])n.push(o===void 0?e:{v:e,i:o});else{let s=e[t[a]];if(!Dn(s))return;if(a===t.length-1&&(Sn(s)||Cn(s)||wn(s)||typeof s==`bigint`))n.push(o===void 0?xn(s):{v:xn(s),i:o});else if(yn(s)){r=!0;for(let e=0,n=s.length;e<n;e+=1)i(s[e],t,a+1,e)}else t.length&&i(s,t,a+1,o)}};return i(e,Sn(t)?t.split(`.`):t,0),r?n:n[0]}var Vn={includeMatches:!1,findAllMatches:!1,minMatchCharLength:1},Hn={isCaseSensitive:!1,ignoreDiacritics:!1,includeScore:!1,keys:[],shouldSort:!0,sortFn:(e,t)=>e.score===t.score?e.idx<t.idx?-1:1:e.score<t.score?-1:1},Un={location:0,threshold:.6,distance:100},Wn={useExtendedSearch:!1,useTokenSearch:!1,getFn:Bn,ignoreLocation:!1,ignoreFieldNorm:!1,fieldNormWeight:1},$=Object.freeze({...Hn,...Vn,...Un,...Wn}),Gn=/[^ ]+/g;function Kn(e=1,t=3){let n=new Map,r=10**t;return{get(t){let i=t.match(Gn).length;if(n.has(i))return n.get(i);let a=1/i**(.5*e),o=parseFloat(Math.round(a*r)/r);return n.set(i,o),o},clear(){n.clear()}}}var qn=class{constructor({getFn:e=$.getFn,fieldNormWeight:t=$.fieldNormWeight}={}){this.norm=Kn(t,3),this.getFn=e,this.isCreated=!1,this.docs=[],this.keys=[],this._keysMap={},this.setIndexRecords()}setSources(e=[]){this.docs=e}setIndexRecords(e=[]){this.records=e}setKeys(e=[]){this.keys=e,this._keysMap={},e.forEach((e,t)=>{this._keysMap[e.id]=t})}create(){this.isCreated||!this.docs.length||(this.isCreated=!0,Sn(this.docs[0])?this.docs.forEach((e,t)=>{this._addString(e,t)}):this.docs.forEach((e,t)=>{this._addObject(e,t)}),this.norm.clear())}add(e){let t=this.size();Sn(e)?this._addString(e,t):this._addObject(e,t)}removeAt(e){this.records.splice(e,1);for(let t=e,n=this.size();t<n;t+=1)--this.records[t].i}removeAll(e){for(let t=e.length-1;t>=0;--t)this.records.splice(e[t],1);for(let e=0,t=this.records.length;e<t;e+=1)this.records[e].i=e}getValueForItemAtKeyId(e,t){return e[this._keysMap[t]]}size(){return this.records.length}_addString(e,t){if(!Dn(e)||On(e))return;let n={v:e,i:t,n:this.norm.get(e)};this.records.push(n)}_addObject(e,t){let n={i:t,$:{}};this.keys.forEach((t,r)=>{let i=t.getFn?t.getFn(e):this.getFn(e,t.path);if(Dn(i)){if(yn(i)){let e=[];for(let t=0,n=i.length;t<n;t+=1){let n=i[t];if(Dn(n)){if(Sn(n)){if(!On(n)){let r={v:n,i:t,n:this.norm.get(n)};e.push(r)}}else if(Dn(n.v)){let t=Sn(n.v)?n.v:xn(n.v);if(!On(t)){let r={v:t,i:n.i,n:this.norm.get(t)};e.push(r)}}}}n.$[r]=e}else if(Sn(i)&&!On(i)){let e={v:i,n:this.norm.get(i)};n.$[r]=e}}}),this.records.push(n)}toJSON(){return{keys:this.keys.map(({getFn:e,...t})=>t),records:this.records}}};function Jn(e,t,{getFn:n=$.getFn,fieldNormWeight:r=$.fieldNormWeight}={}){let i=new qn({getFn:n,fieldNormWeight:r});return i.setKeys(e.map(Ln)),i.setSources(t),i.create(),i}function Yn(e,{getFn:t=$.getFn,fieldNormWeight:n=$.fieldNormWeight}={}){let{keys:r,records:i}=e,a=new qn({getFn:t,fieldNormWeight:n});return a.setKeys(r),a.setIndexRecords(i),a}function Xn(e=[],t=$.minMatchCharLength){let n=[],r=-1,i=-1,a=0;for(let o=e.length;a<o;a+=1){let o=e[a];o&&r===-1?r=a:!o&&r!==-1&&(i=a-1,i-r+1>=t&&n.push([r,i]),r=-1)}return e[a-1]&&a-r>=t&&n.push([r,a-1]),n}var Zn=32;function Qn(e,t,n,{location:r=$.location,distance:i=$.distance,threshold:a=$.threshold,findAllMatches:o=$.findAllMatches,minMatchCharLength:s=$.minMatchCharLength,includeMatches:c=$.includeMatches,ignoreLocation:l=$.ignoreLocation}={}){if(t.length>Zn)throw Error(Mn(Zn));let u=t.length,d=e.length,f=Math.max(0,Math.min(r,d)),p=a,m=f,h=(e,t)=>{let n=e/u;if(l)return n;let r=Math.abs(f-t);return i?n+r/i:r?1:n},g=s>1||c,_=g?Array(d):[],v;for(;(v=e.indexOf(t,m))>-1;){let e=h(0,v);if(p=Math.min(e,p),m=v+u,g){let e=0;for(;e<u;)_[v+e]=1,e+=1}}m=-1;let y=[],b=1,x=u+d,S=1<<u-1;for(let t=0;t<u;t+=1){let r=0,i=x;for(;r<i;)h(t,f+i)<=p?r=i:x=i,i=Math.floor((x-r)/2+r);x=i;let a=Math.max(1,f-i+1),s=o?d:Math.min(f+i,d)+u,c=Array(s+2);c[s+1]=(1<<t)-1;for(let r=s;r>=a;--r){let i=r-1,o=n[e[i]];if(g&&(_[i]=+!!o),c[r]=(c[r+1]<<1|1)&o,t&&(c[r]|=(y[r+1]|y[r])<<1|1|y[r+1]),c[r]&S&&(b=h(t,i),b<=p)){if(p=b,m=i,m<=f)break;a=Math.max(1,2*f-m)}}if(h(t+1,f)>p)break;y=c}let C={isMatch:m>=0,score:Math.max(.001,b)};if(g){let e=Xn(_,s);e.length?c&&(C.indices=e):C.isMatch=!1}return C}function $n(e){let t={};for(let n=0,r=e.length;n<r;n+=1){let i=e.charAt(n);t[i]=(t[i]||0)|1<<r-n-1}return t}function er(e){if(e.length<=1)return e;e.sort((e,t)=>e[0]-t[0]||e[1]-t[1]);let t=[e[0]];for(let n=1,r=e.length;n<r;n+=1){let r=t[t.length-1],i=e[n];i[0]<=r[1]+1?r[1]=Math.max(r[1],i[1]):t.push(i)}return t}var tr={ł:`l`,Ł:`L`,đ:`d`,Đ:`D`,ø:`o`,Ø:`O`,ħ:`h`,Ħ:`H`,ŧ:`t`,Ŧ:`T`,ı:`i`,ß:`ss`},nr=RegExp(`[`+Object.keys(tr).join(``)+`]`,`g`),rr=String.prototype.normalize?e=>e.normalize(`NFD`).replace(/[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C04\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]/g,``).replace(nr,e=>tr[e]):e=>e,ir=class{constructor(e,{location:t=$.location,threshold:n=$.threshold,distance:r=$.distance,includeMatches:i=$.includeMatches,findAllMatches:a=$.findAllMatches,minMatchCharLength:o=$.minMatchCharLength,isCaseSensitive:s=$.isCaseSensitive,ignoreDiacritics:c=$.ignoreDiacritics,ignoreLocation:l=$.ignoreLocation}={}){if(this.options={location:t,threshold:n,distance:r,includeMatches:i,findAllMatches:a,minMatchCharLength:o,isCaseSensitive:s,ignoreDiacritics:c,ignoreLocation:l},e=s?e:e.toLowerCase(),e=c?rr(e):e,this.pattern=e,this.chunks=[],!this.pattern.length)return;let u=(e,t)=>{this.chunks.push({pattern:e,alphabet:$n(e),startIndex:t})},d=this.pattern.length;if(d>Zn){let e=0,t=d%Zn,n=d-t;for(;e<n;)u(this.pattern.substr(e,Zn),e),e+=Zn;if(t){let e=d-Zn;u(this.pattern.substr(e),e)}}else u(this.pattern,0)}searchIn(e){let{isCaseSensitive:t,ignoreDiacritics:n,includeMatches:r}=this.options;if(e=t?e:e.toLowerCase(),e=n?rr(e):e,this.pattern===e){let t={isMatch:!0,score:0};return r&&(t.indices=[[0,e.length-1]]),t}let{location:i,distance:a,threshold:o,findAllMatches:s,minMatchCharLength:c,ignoreLocation:l}=this.options,u=[],d=0,f=!1;this.chunks.forEach(({pattern:t,alphabet:n,startIndex:p})=>{let{isMatch:m,score:h,indices:g}=Qn(e,t,n,{location:i+p,distance:a,threshold:o,findAllMatches:s,minMatchCharLength:c,includeMatches:r,ignoreLocation:l});m&&(f=!0),d+=h,m&&g&&u.push(...g)});let p={isMatch:f,score:f?d/this.chunks.length:1};return f&&r&&(p.indices=er(u)),p}},ar=class{constructor(e){this.pattern=e}static isMultiMatch(e){return or(e,this.multiRegex)}static isSingleMatch(e){return or(e,this.singleRegex)}search(e){return{isMatch:!1,score:1}}};function or(e,t){let n=e.match(t);return n?n[1]:null}var sr=class extends ar{constructor(e){super(e)}static get type(){return`exact`}static get multiRegex(){return/^="(.*)"$/}static get singleRegex(){return/^=(.*)$/}search(e){let t=e===this.pattern;return{isMatch:t,score:+!t,indices:[0,this.pattern.length-1]}}},cr=class extends ar{constructor(e){super(e)}static get type(){return`inverse-exact`}static get multiRegex(){return/^!"(.*)"$/}static get singleRegex(){return/^!(.*)$/}search(e){let t=e.indexOf(this.pattern)===-1;return{isMatch:t,score:+!t,indices:[0,e.length-1]}}},lr=class extends ar{constructor(e){super(e)}static get type(){return`prefix-exact`}static get multiRegex(){return/^\^"(.*)"$/}static get singleRegex(){return/^\^(.*)$/}search(e){let t=e.startsWith(this.pattern);return{isMatch:t,score:+!t,indices:[0,this.pattern.length-1]}}},ur=class extends ar{constructor(e){super(e)}static get type(){return`inverse-prefix-exact`}static get multiRegex(){return/^!\^"(.*)"$/}static get singleRegex(){return/^!\^(.*)$/}search(e){let t=!e.startsWith(this.pattern);return{isMatch:t,score:+!t,indices:[0,e.length-1]}}},dr=class extends ar{constructor(e){super(e)}static get type(){return`suffix-exact`}static get multiRegex(){return/^"(.*)"\$$/}static get singleRegex(){return/^(.*)\$$/}search(e){let t=e.endsWith(this.pattern);return{isMatch:t,score:+!t,indices:[e.length-this.pattern.length,e.length-1]}}},fr=class extends ar{constructor(e){super(e)}static get type(){return`inverse-suffix-exact`}static get multiRegex(){return/^!"(.*)"\$$/}static get singleRegex(){return/^!(.*)\$$/}search(e){let t=!e.endsWith(this.pattern);return{isMatch:t,score:+!t,indices:[0,e.length-1]}}},pr=class extends ar{constructor(e,{location:t=$.location,threshold:n=$.threshold,distance:r=$.distance,includeMatches:i=$.includeMatches,findAllMatches:a=$.findAllMatches,minMatchCharLength:o=$.minMatchCharLength,isCaseSensitive:s=$.isCaseSensitive,ignoreDiacritics:c=$.ignoreDiacritics,ignoreLocation:l=$.ignoreLocation}={}){super(e),this._bitapSearch=new ir(e,{location:t,threshold:n,distance:r,includeMatches:i,findAllMatches:a,minMatchCharLength:o,isCaseSensitive:s,ignoreDiacritics:c,ignoreLocation:l})}static get type(){return`fuzzy`}static get multiRegex(){return/^"(.*)"$/}static get singleRegex(){return/^(.*)$/}search(e){return this._bitapSearch.searchIn(e)}},mr=class extends ar{constructor(e){super(e)}static get type(){return`include`}static get multiRegex(){return/^'"(.*)"$/}static get singleRegex(){return/^'(.*)$/}search(e){let t=0,n,r=[],i=this.pattern.length;for(;(n=e.indexOf(this.pattern,t))>-1;)t=n+i,r.push([n,t-1]);let a=!!r.length;return{isMatch:a,score:+!a,indices:r}}},hr=[sr,mr,lr,ur,fr,dr,cr,pr],gr=hr.length,_r=`\0`,vr=`|`;function yr(e){let t=[],n=e.length,r=0;for(;r<n;){for(;r<n&&e[r]===` `;)r++;if(r>=n)break;let i=r;for(;i<n&&e[i]!==` `&&e[i]!==`"`;)i++;if(i<n&&e[i]===`"`){for(i++;i<n;){if(e[i]===`"`){let t=i+1;if(t>=n||e[t]===` `){i++;break}if(e[t]===`$`&&(t+1>=n||e[t+1]===` `)){i+=2;break}}i++}t.push(e.substring(r,i)),r=i}else{for(;i<n&&e[i]!==` `;)i++;t.push(e.substring(r,i)),r=i}}return t}function br(e,t={}){return e.replace(/\\\|/g,_r).split(vr).map(e=>{let n=yr(e.replace(/\u0000/g,`|`).trim()).filter(e=>e&&!!e.trim()),r=[];for(let e=0,i=n.length;e<i;e+=1){let i=n[e],a=!1,o=-1;for(;!a&&++o<gr;){let e=hr[o],n=e.isMultiMatch(i);n&&(r.push(new e(n,t)),a=!0)}if(!a)for(o=-1;++o<gr;){let e=hr[o],n=e.isSingleMatch(i);if(n){r.push(new e(n,t));break}}}return r})}var xr=new Set([pr.type,mr.type]),Sr=class{constructor(e,{isCaseSensitive:t=$.isCaseSensitive,ignoreDiacritics:n=$.ignoreDiacritics,includeMatches:r=$.includeMatches,minMatchCharLength:i=$.minMatchCharLength,ignoreLocation:a=$.ignoreLocation,findAllMatches:o=$.findAllMatches,location:s=$.location,threshold:c=$.threshold,distance:l=$.distance}={}){this.query=null,this.options={isCaseSensitive:t,ignoreDiacritics:n,includeMatches:r,minMatchCharLength:i,findAllMatches:o,ignoreLocation:a,location:s,threshold:c,distance:l},e=t?e:e.toLowerCase(),e=n?rr(e):e,this.pattern=e,this.query=br(this.pattern,this.options)}static condition(e,t){return t.useExtendedSearch}searchIn(e){let t=this.query;if(!t)return{isMatch:!1,score:1};let{includeMatches:n,isCaseSensitive:r,ignoreDiacritics:i}=this.options;e=r?e:e.toLowerCase(),e=i?rr(e):e;let a=0,o=[],s=0,c=!1;for(let r=0,i=t.length;r<i;r+=1){let i=t[r];o.length=0,a=0,c=!1;for(let t=0,r=i.length;t<r;t+=1){let r=i[t],{isMatch:l,indices:u,score:d}=r.search(e);if(l){a+=1,s+=d;let e=r.constructor.type;e.startsWith(`inverse`)&&(c=!0),n&&(xr.has(e)?o.push(...u):o.push(u))}else{s=0,a=0,o.length=0,c=!1;break}}if(a){let e={isMatch:!0,score:s/a};return c&&(e.hasInverse=!0),n&&(e.indices=er(o)),e}}return{isMatch:!1,score:1}}},Cr=[];function wr(...e){Cr.push(...e)}function Tr(e,t){for(let n=0,r=Cr.length;n<r;n+=1){let r=Cr[n];if(r.condition(e,t))return new r(e,t)}return new ir(e,t)}var Er={AND:`$and`,OR:`$or`},Dr={PATH:`$path`,PATTERN:`$val`},Or=e=>!!(e[Er.AND]||e[Er.OR]),kr=e=>!!e[Dr.PATH],Ar=e=>!yn(e)&&Tn(e)&&!Or(e),jr=e=>({[Er.AND]:Object.keys(e).map(t=>({[t]:e[t]}))});function Mr(e,t,{auto:n=!0}={}){let r=e=>{if(Sn(e)){let r={keyId:null,pattern:e};return n&&(r.searcher=Tr(e,t)),r}let i=Object.keys(e),a=kr(e);if(!a&&i.length>1&&!Or(e))return r(jr(e));if(Ar(e)){let r=a?e[Dr.PATH]:i[0],o=a?e[Dr.PATTERN]:e[r];if(!Sn(o))throw Error(jn(r));let s={keyId:zn(r),pattern:o};return n&&(s.searcher=Tr(o,t)),s}let o={children:[],operator:i[0]};return i.forEach(t=>{let n=e[t];yn(n)&&n.forEach(e=>{o.children.push(r(e))})}),o};return Or(e)||(e=jr(e)),r(e)}function Nr(e,{ignoreFieldNorm:t=$.ignoreFieldNorm}){let n=1;return e.forEach(({key:e,norm:r,score:i})=>{let a=e?e.weight:null;n*=(i===0&&a?2**-52:i)**+((a||1)*(t?1:r))}),n}function Pr(e,{ignoreFieldNorm:t=$.ignoreFieldNorm}){e.forEach(e=>{e.score=Nr(e.matches,{ignoreFieldNorm:t})})}var Fr=class{constructor(e){this.limit=e,this.heap=[]}get size(){return this.heap.length}shouldInsert(e){return this.size<this.limit||e<this.heap[0].score}insert(e){this.size<this.limit?(this.heap.push(e),this._bubbleUp(this.size-1)):e.score<this.heap[0].score&&(this.heap[0]=e,this._sinkDown(0))}extractSorted(e){return this.heap.sort(e)}_bubbleUp(e){let t=this.heap;for(;e>0;){let n=e-1>>1;if(t[e].score<=t[n].score)break;let r=t[e];t[e]=t[n],t[n]=r,e=n}}_sinkDown(e){let t=this.heap,n=t.length,r=e;do{e=r;let i=2*e+1,a=2*e+2;if(i<n&&t[i].score>t[r].score&&(r=i),a<n&&t[a].score>t[r].score&&(r=a),r!==e){let n=t[e];t[e]=t[r],t[r]=n}}while(r!==e)}};function Ir(e,t){let n=e.matches;t.matches=[],Dn(n)&&n.forEach(e=>{if(!Dn(e.indices)||!e.indices.length)return;let{indices:n,value:r}=e,i={indices:n,value:r};e.key&&(i.key=e.key.src),e.idx>-1&&(i.refIndex=e.idx),t.matches.push(i)})}function Lr(e,t){t.score=e.score}function Rr(e,t,{includeMatches:n=$.includeMatches,includeScore:r=$.includeScore}={}){let i=[];return n&&i.push(Ir),r&&i.push(Lr),e.map(e=>{let{idx:n}=e,r={item:t[n],refIndex:n};return i.length&&i.forEach(t=>{t(e,r)}),r})}var zr=/\b\w+\b/g;function Br({isCaseSensitive:e=!1,ignoreDiacritics:t=!1}={}){return{tokenize(n){return e||(n=n.toLowerCase()),t&&(n=rr(n)),n.match(zr)||[]}}}function Vr(e,t,n){let r=new Map,i=new Map,a=0;function o(e,t,o,s){let c=n.tokenize(e);if(!c.length)return;a++;let l=new Map;for(let e of c)l.set(e,(l.get(e)||0)+1);for(let[e,n]of l){let a={docIdx:t,keyIdx:o,subIdx:s,tf:n},c=r.get(e);c||(c=[],r.set(e,c)),c.push(a),i.set(e,(i.get(e)||0)+1)}}for(let n of e){let{i:e,v:r,$:i}=n;if(r!==void 0){o(r,e,-1,-1);continue}if(i)for(let n=0;n<t;n++){let t=i[n];if(t)if(Array.isArray(t))for(let r of t)o(r.v,e,n,r.i??-1);else o(t.v,e,n,-1)}}return{terms:r,fieldCount:a,df:i}}function Hr(e,t,n,r){let{i,v:a,$:o}=t;function s(t,n,a){let o=r.tokenize(t);if(!o.length)return;e.fieldCount++;let s=new Map;for(let e of o)s.set(e,(s.get(e)||0)+1);for(let[t,r]of s){let o={docIdx:i,keyIdx:n,subIdx:a,tf:r},s=e.terms.get(t);s||(s=[],e.terms.set(t,s)),s.push(o),e.df.set(t,(e.df.get(t)||0)+1)}}if(a!==void 0){s(a,-1,-1);return}if(o)for(let e=0;e<n;e++){let t=o[e];if(t)if(Array.isArray(t))for(let n of t)s(n.v,e,n.i??-1);else s(t.v,e,-1)}}function Ur(e,t){for(let[n,r]of e.terms){let i=r.filter(e=>e.docIdx!==t),a=r.length-i.length;a>0&&(e.fieldCount-=a,e.df.set(n,(e.df.get(n)||0)-a),i.length===0?(e.terms.delete(n),e.df.delete(n)):e.terms.set(n,i))}}var Wr=class{constructor(e,t,n){this.options={...$,...t},this.options.useExtendedSearch,this.options.useTokenSearch,this._keyStore=new In(this.options.keys),this._docs=e,this._myIndex=null,this._invertedIndex=null,this.setCollection(e,n),this._lastQuery=null,this._lastSearcher=null}_getSearcher(e){if(this._lastQuery===e)return this._lastSearcher;let t=Tr(e,this._invertedIndex?{...this.options,_invertedIndex:this._invertedIndex}:this.options);return this._lastQuery=e,this._lastSearcher=t,t}setCollection(e,t){if(this._docs=e,t&&!(t instanceof qn))throw Error(An);if(this._myIndex=t||Jn(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight}),this.options.useTokenSearch){let e=Br({isCaseSensitive:this.options.isCaseSensitive,ignoreDiacritics:this.options.ignoreDiacritics});this._invertedIndex=Vr(this._myIndex.records,this._myIndex.keys.length,e)}}add(e){if(Dn(e)&&(this._docs.push(e),this._myIndex.add(e),this._invertedIndex)){let e=this._myIndex.records[this._myIndex.records.length-1],t=Br({isCaseSensitive:this.options.isCaseSensitive,ignoreDiacritics:this.options.ignoreDiacritics});Hr(this._invertedIndex,e,this._myIndex.keys.length,t)}}remove(e=()=>!1){let t=[],n=[];for(let r=0,i=this._docs.length;r<i;r+=1)e(this._docs[r],r)&&(t.push(this._docs[r]),n.push(r));if(n.length){if(this._invertedIndex)for(let e of n)Ur(this._invertedIndex,e);for(let e=n.length-1;e>=0;--e)this._docs.splice(n[e],1);this._myIndex.removeAll(n)}return t}removeAt(e){this._invertedIndex&&Ur(this._invertedIndex,e);let t=this._docs.splice(e,1)[0];return this._myIndex.removeAt(e),t}getIndex(){return this._myIndex}search(e,t){let{limit:n=-1}=t||{},{includeMatches:r,includeScore:i,shouldSort:a,sortFn:o,ignoreFieldNorm:s}=this.options;if(Sn(e)&&!e.trim()){let e=this._docs.map((e,t)=>({item:e,refIndex:t}));return Cn(n)&&n>-1&&(e=e.slice(0,n)),e}let c=Cn(n)&&n>0&&Sn(e),l;if(c){let t=new Fr(n);Sn(this._docs[0])?this._searchStringList(e,{heap:t,ignoreFieldNorm:s}):this._searchObjectList(e,{heap:t,ignoreFieldNorm:s}),l=t.extractSorted(o)}else l=Sn(e)?Sn(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e),Pr(l,{ignoreFieldNorm:s}),a&&l.sort(o),Cn(n)&&n>-1&&(l=l.slice(0,n));return Rr(l,this._docs,{includeMatches:r,includeScore:i})}_searchStringList(e,{heap:t,ignoreFieldNorm:n}={}){let r=this._getSearcher(e),{records:i}=this._myIndex,a=t?null:[];return i.forEach(({v:e,i,n:o})=>{if(!Dn(e))return;let{isMatch:s,score:c,indices:l}=r.searchIn(e);if(s){let r={item:e,idx:i,matches:[{score:c,value:e,norm:o,indices:l}]};t?(r.score=Nr(r.matches,{ignoreFieldNorm:n}),t.shouldInsert(r.score)&&t.insert(r)):a.push(r)}}),a}_searchLogical(e){let t=Mr(e,this.options),n=(e,t,r)=>{if(!(`children`in e)){let{keyId:n,searcher:i}=e,a;return n===null?(a=[],this._myIndex.keys.forEach((e,n)=>{a.push(...this._findMatches({key:e,value:t[n],searcher:i}))})):a=this._findMatches({key:this._keyStore.get(n),value:this._myIndex.getValueForItemAtKeyId(t,n),searcher:i}),a&&a.length?[{idx:r,item:t,matches:a}]:[]}let{children:i,operator:a}=e,o=[];for(let e=0,s=i.length;e<s;e+=1){let s=i[e],c=n(s,t,r);if(c.length)o.push(...c);else if(a===Er.AND)return[]}return o},r=this._myIndex.records,i=new Map,a=[];return r.forEach(({$:e,i:r})=>{if(Dn(e)){let o=n(t,e,r);o.length&&(i.has(r)||(i.set(r,{idx:r,item:e,matches:[]}),a.push(i.get(r))),o.forEach(({matches:e})=>{i.get(r).matches.push(...e)}))}}),a}_searchObjectList(e,{heap:t,ignoreFieldNorm:n}={}){let r=this._getSearcher(e),{keys:i,records:a}=this._myIndex,o=t?null:[];return a.forEach(({$:e,i:a})=>{if(!Dn(e))return;let s=[],c=!1,l=!1;if(i.forEach((t,n)=>{let i=this._findMatches({key:t,value:e[n],searcher:r});i.length?(s.push(...i),i[0].hasInverse&&(l=!0)):c=!0}),!(l&&c)&&s.length){let r={idx:a,item:e,matches:s};t?(r.score=Nr(r.matches,{ignoreFieldNorm:n}),t.shouldInsert(r.score)&&t.insert(r)):o.push(r)}}),o}_findMatches({key:e,value:t,searcher:n}){if(!Dn(t))return[];let r=[];if(yn(t))t.forEach(({v:t,i,n:a})=>{if(!Dn(t))return;let{isMatch:o,score:s,indices:c,hasInverse:l}=n.searchIn(t);o&&r.push({score:s,key:e,value:t,idx:i,norm:a,indices:c,hasInverse:l})});else{let{v:i,n:a}=t,{isMatch:o,score:s,indices:c,hasInverse:l}=n.searchIn(i);o&&r.push({score:s,key:e,value:i,norm:a,indices:c,hasInverse:l})}return r}},Gr=class{static condition(e,t){return t.useTokenSearch}constructor(e,t){this.options=t,this.analyzer=Br({isCaseSensitive:t.isCaseSensitive,ignoreDiacritics:t.ignoreDiacritics});let n=this.analyzer.tokenize(e),{df:r,fieldCount:i}=t._invertedIndex;this.termSearchers=[],this.idfWeights=[];for(let e of n){this.termSearchers.push(new ir(e,{location:t.location,threshold:t.threshold,distance:t.distance,includeMatches:t.includeMatches,findAllMatches:t.findAllMatches,minMatchCharLength:t.minMatchCharLength,isCaseSensitive:t.isCaseSensitive,ignoreDiacritics:t.ignoreDiacritics,ignoreLocation:!0}));let n=r.get(e)||0,a=Math.log(1+(i-n+.5)/(n+.5));this.idfWeights.push(a)}}searchIn(e){if(!this.termSearchers.length)return{isMatch:!1,score:1};let t=[],n=0,r=0,i=0;for(let a=0;a<this.termSearchers.length;a++){let o=this.termSearchers[a].searchIn(e),s=this.idfWeights[a];r+=s,o.isMatch&&(i++,n+=s*(1-o.score),o.indices&&t.push(...o.indices))}if(i===0)return{isMatch:!1,score:1};let a=r>0?1-n/r:0,o={isMatch:!0,score:Math.max(.001,a)};return this.options.includeMatches&&t.length&&(o.indices=er(t)),o}};Wr.version=`7.3.0`,Wr.createIndex=Jn,Wr.parseIndex=Yn,Wr.config=$,Wr.match=function(e,t,n){return Tr(e,{...$,...n}).searchIn(t)},Wr.parseQuery=Mr,wr(Sr),wr(Gr),Wr.use=function(...e){e.forEach(e=>wr(e))};var Kr=[{text:`text-red-400`,bgCircle:`bg-red-400`,bgCard:`bg-red-500/[0.08]`,borderCard:`border-red-500/30`,bgLight:`bg-red-500/15`,bgHover:`hover:bg-red-500`,bgAlt:`bg-red-500/[0.04]`,name:`Red`},{text:`text-orange-400`,bgCircle:`bg-orange-400`,bgCard:`bg-orange-500/[0.08]`,borderCard:`border-orange-500/30`,bgLight:`bg-orange-500/15`,bgHover:`hover:bg-orange-500`,bgAlt:`bg-orange-500/[0.04]`,name:`Orange`},{text:`text-yellow-400`,bgCircle:`bg-yellow-400`,bgCard:`bg-yellow-500/[0.08]`,borderCard:`border-yellow-500/30`,bgLight:`bg-yellow-500/15`,bgHover:`hover:bg-yellow-500`,bgAlt:`bg-yellow-500/[0.04]`,name:`Yellow`},{text:`text-green-400`,bgCircle:`bg-green-400`,bgCard:`bg-green-500/[0.08]`,borderCard:`border-green-500/30`,bgLight:`bg-green-500/15`,bgHover:`hover:bg-green-500`,bgAlt:`bg-green-500/[0.04]`,name:`Green`},{text:`text-blue-400`,bgCircle:`bg-blue-400`,bgCard:`bg-blue-500/[0.08]`,borderCard:`border-blue-500/30`,bgLight:`bg-blue-500/15`,bgHover:`hover:bg-blue-500`,bgAlt:`bg-blue-500/[0.04]`,name:`Blue`},{text:`text-accent`,bgCircle:`bg-accent`,bgCard:`bg-accent/[0.08]`,borderCard:`border-accent/30`,bgLight:`bg-accent/15`,bgHover:`hover:bg-accent`,bgAlt:`bg-accent/[0.04]`,name:`Purple`},{text:`text-pink-400`,bgCircle:`bg-pink-400`,bgCard:`bg-pink-500/[0.08]`,borderCard:`border-pink-500/30`,bgLight:`bg-pink-500/15`,bgHover:`hover:bg-pink-500`,bgAlt:`bg-pink-500/[0.04]`,name:`Pink`},{text:`text-foreground/60`,bgCircle:`bg-foreground/30`,bgCard:`bg-foreground/[0.04]`,borderCard:`border-[var(--panel-border)]/50`,bgLight:`bg-foreground/15`,bgHover:`hover:bg-foreground/30`,bgAlt:`bg-foreground/[0.02]`,name:`Default`}];function qr({title:e=`Table View`,subtitle:n=`/table`,backUrl:a=`/templates`,tableCollection:s=`pub_table_data`,config:c,customContent:l}){let{user:u}=t.na(),d=!!c,f=c?.isInternal||c?.isShared;c?.isPrivate&&c?.isAdmin;let p=c?.isAdmin||f,m=d?p||s.startsWith(`role_`):!0,h=(e,t)=>u?s.startsWith(`user_`)?{...e,uid:u.uid}:t?{uid:u.uid,...e}:e:e,g=!!l,_=c?.showButton!==!1&&!g,v=c?.buttonText||`+`,y=c?.buttonStyle||`secondary`,b=c?.showExportButton!==!1,[x,S]=(0,r.useState)([]),[C,w]=(0,r.useState)(`demo`),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(!1),[k,A]=(0,r.useState)(``),[j,M]=(0,r.useState)(!1),[N,P]=(0,r.useState)(null),[F,I]=(0,r.useState)(null),[L,R]=(0,r.useState)(``),[z,B]=(0,r.useState)(!1),[V,H]=(0,r.useState)(``),[U,W]=(0,r.useState)(null),[G,ee]=(0,r.useState)(null),[K,q]=(0,r.useState)(!1);(0,r.useEffect)(()=>{let e=s.startsWith(`user_`);if(e&&!u)return;try{let e=localStorage.getItem(`fbos_tables_${s}`);e&&S(JSON.parse(e))}catch{}let n=(0,o.onSnapshot)(e&&u?(0,o.query)((0,o.collection)(t.Da,s),(0,o.where)(`uid`,`==`,u.uid)):(0,o.collection)(t.Da,s),n=>{let r=[];if(n.forEach(e=>{r.push({id:e.id,...e.data()})}),r.length===0){let n={name:`Unnamed Table`,columns:[`Column 1`,`Column 2`,`Column 3`,`Column 4`],...u?{uid:u.uid}:{},rows:[{id:`1`,"Column 1":``,"Column 2":``,"Column 3":``,"Column 4":``},{id:`2`,"Column 1":``,"Column 2":``,"Column 3":``,"Column 4":``}]};(0,o.setDoc)((0,o.doc)(t.Da,s,e&&u?`demo_${u.uid}`:`demo`),n)}else{let e=r.sort((e,t)=>(e.name||``).localeCompare(t.name||``));S(e),localStorage.setItem(`fbos_tables_${s}`,JSON.stringify(e))}});return()=>n()},[s,u]);let J=x.find(e=>e.id===C)||x[0]||{columns:[],rows:[]},Y=async e=>{J.id&&(u&&s.startsWith(`user_`)&&(e.uid=u.uid),await(0,o.setDoc)((0,o.doc)(t.Da,s,J.id),e,{merge:!0}))},te=()=>{if(!J.rows||J.rows.length===0)return;let e=J.columns.join(`,`),t=J.rows.map(e=>J.columns.map(t=>`"${e[t]||``}"`).join(`,`)).join(`
|
|
4
|
-
`),n=new Blob([`${e}\n${t}`],{type:`text/csv`}),r=window.URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`export_${J.name||`table`}.csv`,i.click(),window.URL.revokeObjectURL(r)},ne=(e,t,n)=>{Y({...J,rows:J.rows.map(r=>r.id===e?{...r,[t]:n}:r)})},re=()=>{let e=hn(u),t={id:Date.now().toString(),...u?{_uid:u.uid,_creatorName:e.creatorName,_creatorAvatar:e.creatorAvatar}:{}};J.columns.forEach(e=>t[e]=``),Y({...J,rows:[...J.rows||[],t]})},X=e=>{Y({...J,rows:J.rows.filter(t=>t.id!==e)})},Z=()=>{let e=`Column ${(J.columns?.length||0)+1}`;J.columns?.includes(e)||(Y({...J,columns:[...J.columns||[],e]}),setTimeout(()=>{let e=document.getElementById(`table-scroll-container`);e&&e.scrollTo({left:e.scrollWidth,behavior:`smooth`})},100))},Q=e=>{let t=(J.columns||[]).filter(t=>t!==e),n=(J.rows||[]).map(t=>{let n={...t};return delete n[e],n}),r={...J.colColors||{}};delete r[e],Y({...J,columns:t,rows:n,colColors:r})},ie=async e=>{e.trim()&&J.id&&e!==J.name&&await(0,o.setDoc)((0,o.doc)(t.Da,s,J.id),{name:e},{merge:!0})},ae=async()=>{M(!0),E(!1);let e=`tbl_${Date.now()}`;await(0,o.setDoc)((0,o.doc)(t.Da,s,e),{name:`Unnamed Table`,columns:[`Column 1`,`Column 2`,`Column 3`],...u?{uid:u.uid}:{},rows:[]}),setTimeout(()=>{w(e),M(!1)},600)},oe=e=>{let t=V.trim();if(t&&t!==e&&!J.columns?.includes(t)){let n=J.columns.map(n=>n===e?t:n),r=(J.rows||[]).map(n=>{let r={...n};return r[t]=r[e]||``,delete r[e],r}),i={...J.colColors||{}};i[e]&&(i[t]=i[e],delete i[e]),Y({...J,columns:n,rows:r,colColors:i})}I(null)},se=e=>gn({uid:e._uid,creatorName:e._creatorName,creatorAvatar:e._creatorAvatar},u),ce=J.rows||[];return L.trim()!==``&&(ce=new Wr(ce.map(e=>({...e,_creatorMatch:se(e)?.name||``})),{keys:(J.columns||[]).concat([`_creatorMatch`]),threshold:.4,ignoreLocation:!0}).search(L).map(e=>{let{_creatorMatch:t,...n}=e.item;return n})),(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[!d&&a&&(0,i.jsx)(Wt,{to:a}),(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(Ce,{children:e}),n&&(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),n]})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 min-h-0 pb-16`,children:[d&&(0,i.jsx)(Fe,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden shadow-2xl relative z-10 flex flex-col flex-1 min-h-[400px]`,children:[(0,i.jsx)(`div`,{className:`absolute top-0 right-0 w-[400px] h-[400px] bg-accent/5 blur-[100px] rounded-full pointer-events-none -z-10`}),(0,i.jsxs)(`div`,{className:`p-4 md:px-6 border-b border-[var(--panel-border)]/50 flex items-center justify-between bg-foreground/[0.01] gap-3 sm:gap-4`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 relative`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 relative`,children:[(0,i.jsxs)(`div`,{className:`relative flex items-center`,children:[D?(0,i.jsx)(`div`,{contentEditable:!0,suppressContentEditableWarning:!0,onBlur:e=>{O(!1),ie(e.currentTarget.textContent||``)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},className:`bg-transparent border-b-2 border-accent outline-none text-[16px] font-bold text-foreground inline-block min-w-[20px] whitespace-nowrap px-1 py-0.5`,children:J.name||`Unnamed Table`}):(0,i.jsx)(`h3`,{className:`font-bold text-[16px] text-foreground/90 cursor-pointer hover:text-accent transition-colors truncate max-w-[38vw] sm:max-w-[200px]`,onClick:()=>O(!0),title:`Click to rename table`,children:J.name||`Unnamed Table`}),(0,i.jsx)(t.pr,{children:T&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>E(!1)}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},exit:{opacity:0,y:-10},className:`absolute top-[120%] left-0 w-[220px] bg-background/95 backdrop-blur-xl border border-[var(--panel-border)] rounded-2xl shadow-2xl z-50 py-2 flex flex-col`,children:[(0,i.jsx)(`div`,{className:`px-4 py-2 text-[10px] font-bold uppercase tracking-wider text-foreground/40 border-b border-[var(--panel-border)] mb-1`,children:`Your Tables`}),(0,i.jsx)(`div`,{className:`max-h-[250px] overflow-y-auto styled-scrollbars z-50 relative`,children:x.map(e=>(0,i.jsx)(`button`,{onClick:()=>{w(e.id),E(!1)},className:`w-full px-4 py-2 text-[13px] font-bold text-left hover:bg-foreground/[0.03] transition-colors truncate ${C===e.id?`text-accent bg-accent/5`:`text-foreground/70`}`,children:e.name||`Unnamed Table`},e.id))}),(0,i.jsx)(`div`,{className:`w-full h-[1px] bg-[var(--panel-border)]/50 my-1`}),(0,i.jsxs)(`button`,{onClick:ae,className:`w-full px-4 py-2.5 text-[13px] font-bold text-left text-foreground/70 hover:text-foreground hover:bg-foreground/5 transition-colors flex items-center gap-2`,children:[(0,i.jsx)(t.Ur,{className:`w-4 h-4`}),` Create New Table`]})]})]})})]}),(0,i.jsx)(`button`,{onClick:()=>E(!T),className:`p-1 px-1.5 rounded-lg hover:bg-foreground/5 transition-colors text-foreground/40 hover:text-foreground shrink-0 border border-transparent hover:border-[var(--panel-border)]`,children:(0,i.jsx)(t.Ri,{className:`w-4 h-4 transition-transform ${T?`rotate-180 text-accent`:``}`})})]}),(0,i.jsxs)(`span`,{className:`opacity-40 text-[11px] font-bold mt-1 uppercase tracking-wider`,children:[(J.rows||[]).length,` Records`]})]}),(0,i.jsx)(`div`,{className:`relative shrink-0 ${z?`flex-1 min-w-[130px] max-w-[300px]`:``}`,children:z?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.Lr,{className:`absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-foreground/40`}),(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,"aria-label":`Search records`,placeholder:`Search records...`,value:L,onChange:e=>R(e.target.value),onBlur:()=>{L.trim()||B(!1)},onKeyDown:e=>{e.key===`Escape`&&(R(``),B(!1))},className:`w-full bg-background border border-[var(--panel-border)] rounded-xl py-2.5 px-9 text-[13px] font-medium text-foreground focus:outline-none focus:border-accent transition-colors shadow-inner`})]}):(0,i.jsx)(`button`,{type:`button`,onClick:()=>B(!0),"aria-label":`Search records`,title:`Search records`,className:`w-10 h-10 flex items-center justify-center rounded-xl border border-[var(--panel-border)] text-foreground/50 hover:text-accent hover:bg-foreground/5 transition-colors`,children:(0,i.jsx)(t.Lr,{className:`w-4 h-4`})})}),(0,i.jsxs)(`div`,{className:`flex gap-2 shrink-0`,children:[b&&(0,i.jsx)(t.cr,{variant:`secondary`,onClick:te,className:`px-3 py-2.5 font-bold rounded-xl shadow-sm border border-[var(--panel-border)] flex items-center gap-2`,children:(0,i.jsx)(t.Si,{className:`w-4 h-4`})}),_&&(0,i.jsx)(t.cr,{variant:y===`primary`?void 0:`secondary`,onClick:re,className:`px-3 py-2.5 font-bold rounded-xl border border-[var(--panel-border)] shadow-sm flex items-center gap-2 whitespace-nowrap`,children:v===`+`?(0,i.jsx)(t.Ur,{className:`w-4 h-4`}):v})]})]}),(0,i.jsx)(`div`,{id:`table-scroll-container`,className:`overflow-auto w-full flex-1 min-h-[300px] relative styled-scrollbars`,children:l?(0,i.jsx)(`div`,{className:`fbos-content-slot p-4 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:(0,i.jsx)(l,{config:c,actions:{tables:x,activeTable:J,collection:s,user:u,saveTable:async(e,n)=>{let r=h(n,!x.some(t=>t.id===e));S(t=>t.find(t=>t.id===e)?t.map(t=>t.id===e?{...t,...r}:t):[...t,{id:e,...r}]),await(0,o.setDoc)((0,o.doc)(t.Da,s,e),r,{merge:!0})},deleteTable:async e=>{S(t=>t.filter(t=>t.id!==e)),await(0,o.deleteDoc)((0,o.doc)(t.Da,s,e))},updateCell:(e,t,n)=>ne(e,t,n),addRow:()=>re(),addColumn:()=>Z()}})}):(0,i.jsx)(t.pr,{mode:`wait`,children:j?(0,i.jsxs)(t.fr.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 flex flex-col items-center justify-center bg-background/40 backdrop-blur-[2px] z-50`,children:[(0,i.jsx)(`div`,{className:`w-8 h-8 rounded-full border-2 border-accent border-r-transparent animate-spin mb-4`}),(0,i.jsx)(`p`,{className:`text-[11px] font-bold text-foreground/50 uppercase tracking-widest`,children:`Generating Table`})]},`loader`):(0,i.jsxs)(t.fr.table,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`w-full text-left border-collapse table-auto relative min-w-[800px]`,children:[(0,i.jsx)(`thead`,{children:(0,i.jsxs)(`tr`,{className:`border-b border-[var(--panel-border)] transition-colors ${J.headerColor?Kr.find(e=>e.text===J.headerColor)?.bgAlt:`bg-foreground/[0.02]`}`,children:[(0,i.jsx)(`th`,{className:`py-4 px-6 text-[12px] font-bold uppercase tracking-wider whitespace-nowrap text-foreground/50 w-32 border-r border-[var(--panel-border)]/20 ${m?``:`hidden`}`,children:`Creator`}),(J.columns||[]).map((e,n)=>{let r=(J.colColors||{})[e],a=(J.colorTimestamps||{})[`col_${e}`]||0;J.headerColor;let o=(J.colorTimestamps||{}).header||0,s=`bg-transparent`,c=`text-foreground/50`;if(r&&r!==`none`&&a>=o){let e=Kr.find(e=>e.text===r);e&&(s=e.bgCard,c=e.text)}return(0,i.jsx)(`th`,{className:`py-3 px-6 text-[12px] font-bold uppercase tracking-wider relative group h-[53px] min-w-[120px] ${c} ${s} border-r border-[var(--panel-border)]/20 last:border-r-0 select-none align-middle`,children:(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-2 w-full h-full`,children:[F===e?(0,i.jsx)(`div`,{className:`flex-1 min-w-[50px]`,children:(0,i.jsx)(`span`,{contentEditable:!0,suppressContentEditableWarning:!0,onBlur:t=>{I(null),H(t.currentTarget.textContent||``),(t.currentTarget.textContent||``).trim()!==``&&oe(e)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},className:`bg-transparent outline-none border-b border-accent/40 font-bold text-[12px] uppercase tracking-wider p-0 m-0 ${c} block w-full whitespace-nowrap overflow-hidden cursor-text`,ref:e=>{e&&requestAnimationFrame(()=>{e.focus()})},children:V})}):(0,i.jsx)(`div`,{className:`flex items-center gap-2 flex-1 overflow-hidden`,onClick:()=>{I(e),H(e)},children:(0,i.jsx)(`span`,{className:`truncate cursor-text`,children:e})}),(0,i.jsxs)(`div`,{className:`relative shrink-0 flex items-center h-full gap-0.5`,children:[(0,i.jsx)(`button`,{onClick:()=>ee(G===e?null:e),className:`p-1.5 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity hover:bg-foreground/10 ${r&&r!==`none`?`!opacity-100`:``} text-current`,children:(0,i.jsx)(t.Jr,{className:`w-4 h-4`})}),(J.columns||[]).length>1&&(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),Q(e)},className:`p-1.5 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity hover:bg-red-500/10 text-foreground/30 hover:text-red-500`,title:`Delete column`,children:(0,i.jsx)(t.Dr,{className:`w-3.5 h-3.5`})}),G===e&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-30`,onClick:()=>ee(null)}),(0,i.jsxs)(`div`,{className:`absolute top-8 right-0 flex gap-1.5 bg-background/95 backdrop-blur-xl border border-[var(--panel-border)] p-2 rounded-xl shadow-xl z-50 items-center`,children:[(0,i.jsx)(`button`,{onClick:t=>{t.preventDefault(),t.stopPropagation();let n={...J.colColors||{},[e]:`none`},r={...J.colorTimestamps||{},[`col_${e}`]:Date.now()};Y({...J,colColors:n,colorTimestamps:r}),ee(null)},className:`w-4 h-4 rounded-full flex items-center justify-center bg-foreground/10 hover:bg-red-500/20 hover:text-red-500 text-foreground/40 transition-colors border border-[var(--panel-border)]/50 shrink-0`,title:`Remove Color`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})}),(0,i.jsx)(`div`,{className:`h-4 w-px bg-[var(--panel-border)]/50 mx-0.5`}),Kr.map(t=>(0,i.jsx)(`button`,{onClick:n=>{n.preventDefault(),n.stopPropagation();let r={...J.colColors||{},[e]:t.text},i={...J.colorTimestamps||{},[`col_${e}`]:Date.now()};Y({...J,colColors:r,colorTimestamps:i}),ee(null)},className:`w-4 h-4 rounded-full ${t.bgCircle} hover:scale-125 transition-transform border border-[var(--panel-border)]/50 shrink-0`},t.name))]})]})]})]})},`col_${n}_${e}`)}),(0,i.jsx)(`th`,{className:`py-4 px-4 w-14 border-l border-[var(--panel-border)]/30 relative`,children:(0,i.jsxs)(`div`,{className:`flex items-center justify-end gap-0.5 relative z-20`,children:[(0,i.jsx)(`button`,{onClick:()=>q(!K),className:`p-1.5 rounded-lg transition-colors hover:bg-foreground/10 ${J.headerColor?Kr.find(e=>e.text===J.headerColor)?.text:`text-foreground/30`}`,children:(0,i.jsx)(t.Jr,{className:`w-4 h-4`})}),K&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-30`,onClick:()=>q(!1)}),(0,i.jsxs)(`div`,{className:`absolute top-6 right-8 flex gap-1.5 bg-background/90 backdrop-blur-xl border border-[var(--panel-border)] p-2 rounded-xl shadow-xl z-50 items-center`,children:[(0,i.jsx)(`button`,{onClick:()=>{Y({...J,headerColor:``}),q(!1)},className:`w-4 h-4 rounded-full flex items-center justify-center bg-foreground/10 hover:bg-red-500/20 hover:text-red-500 text-foreground/40 transition-colors border border-[var(--panel-border)]/50 shrink-0`,title:`Remove Header Color`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})}),(0,i.jsx)(`div`,{className:`h-4 w-px bg-[var(--panel-border)]/50 mx-0.5`}),Kr.map(e=>(0,i.jsx)(`button`,{onClick:()=>{let t={...J.colorTimestamps||{},header:Date.now()};Y({...J,headerColor:e.text,colorTimestamps:t}),q(!1)},className:`w-4 h-4 rounded-full ${e.bgCircle} hover:scale-125 transition-transform border border-[var(--panel-border)]/50`},e.name))]})]}),(0,i.jsx)(`button`,{onClick:Z,className:`p-1.5 rounded-lg text-foreground/40 hover:text-accent hover:bg-accent/10 transition-colors flex items-center justify-center`,children:(0,i.jsx)(t.Ur,{className:`w-4 h-4`})})]})})]})}),(0,i.jsxs)(`tbody`,{children:[ce.map((e,n)=>{let r=n%2==1,a=(J.rowColors||{})[e.id],o=a?r?Kr.find(e=>e.text===a)?.bgAlt:Kr.find(e=>e.text===a)?.bgCard:r?`bg-foreground/[0.02]`:`bg-transparent`;return(0,i.jsxs)(`tr`,{className:`border-b border-[var(--panel-border)]/30 hover:bg-foreground/[0.04] transition-colors group`,children:[(0,i.jsx)(`td`,{className:`py-4 px-6 whitespace-nowrap h-[53px] border-r border-[var(--panel-border)]/20 ${o} ${m?``:`hidden`}`,children:(0,i.jsx)(`div`,{className:`flex items-center gap-2`,children:d?(()=>{let t=se(e);return t?(0,i.jsxs)(i.Fragment,{children:[t.avatar?(0,i.jsx)(`img`,{src:t.avatar,className:`w-5 h-5 rounded-full shrink-0 object-cover`}):(0,i.jsx)(`div`,{className:`w-5 h-5 rounded-full bg-accent/20 text-accent flex items-center justify-center text-[10px] font-bold shrink-0`,children:t.name[0].toUpperCase()}),(0,i.jsx)(`span`,{className:`text-[11px] font-bold text-foreground/80 tracking-tight shrink-0`,children:t.name})]}):(0,i.jsx)(`span`,{className:`text-[11px] font-bold text-foreground/30`,children:`—`})})():(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`w-5 h-5 rounded-full bg-accent/20 text-accent flex items-center justify-center text-[10px] font-bold shrink-0 shadow-inner group-hover:scale-110 transition-transform`,children:`G`}),(0,i.jsx)(`span`,{className:`text-[11px] font-bold text-foreground/80 tracking-tight shrink-0`,children:`Guest`})]})})}),(J.columns||[]).map(t=>{let a=N?.id===e.id&&N?.field===t,o=(J.colColors||{})[t],s=(J.colorTimestamps||{})[`col_${t}`]||0,c=(J.rowColors||{})[e.id],l=(J.colorTimestamps||{})[`row_${e.id}`]||0,u=``;u=l>s?c===`none`?``:c:s>l?o===`none`?``:o:c===`none`?``:c||o||``,u===`none`&&(u=``);let d=u?Kr.find(e=>e.text===u):null,f=d?r?d.bgAlt:d.bgCard:r?`bg-foreground/[0.02]`:`bg-transparent`,p=d?d.text:`text-foreground/80`;return(0,i.jsxs)(`td`,{className:`py-4 px-6 whitespace-pre-wrap min-w-[120px] text-[14px] font-medium relative ${f} align-top border-r border-[var(--panel-border)]/10 last:border-r-0`,onClick:()=>!a&&P({id:e.id,field:t}),children:[a?(0,i.jsx)(`textarea`,{autoFocus:!0,value:e[t]||``,onChange:n=>ne(e.id,t,n.target.value),onBlur:()=>P(null),onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&P(null)},className:`absolute inset-0 bg-transparent !border-0 !outline-none focus:!outline-none focus:!ring-0 !ring-0 !shadow-none focus:!shadow-none p-4 px-6 text-[14px] font-medium w-full h-full caret-accent ${p} z-20 resize-none styled-scrollbars`}):null,(0,i.jsx)(`span`,{className:`block w-full min-h-[20px] break-words transition-all ${a?`opacity-0`:`opacity-100`} ${p} ${t===`Status`&&e[t]===`Active`&&!u?`text-green-500`:``}`,children:e[t]||(0,i.jsx)(`span`,{className:`opacity-30 italic font-normal`,children:`empty`})})]},`cell_${e.id||n}_${t}`)}),(0,i.jsx)(`td`,{className:`py-4 px-4 whitespace-nowrap text-right h-[53px] ${o} relative z-10`,children:(0,i.jsxs)(`div`,{className:`flex items-center justify-end gap-1 opacity-100 md:opacity-20 md:group-hover:opacity-100 transition-opacity relative`,children:[(0,i.jsx)(`button`,{onClick:()=>W(U===e.id?null:e.id),className:`p-1.5 rounded-lg transition-colors hover:bg-foreground/10 ${a?Kr.find(e=>e.text===a)?.text:`text-foreground/40`}`,children:(0,i.jsx)(t.Jr,{className:`w-4 h-4`})}),U===e.id&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-30`,onClick:()=>W(null)}),(0,i.jsxs)(`div`,{className:`absolute top-6 right-8 flex gap-1.5 bg-background/90 backdrop-blur-xl border border-[var(--panel-border)] p-2 rounded-xl shadow-xl z-50 items-center`,children:[(0,i.jsx)(`button`,{onClick:t=>{t.preventDefault(),t.stopPropagation();let n={...J.rowColors||{},[e.id]:`none`},r={...J.colorTimestamps||{},[`row_${e.id}`]:Date.now()};Y({...J,rowColors:n,colorTimestamps:r}),W(null)},className:`w-4 h-4 rounded-full flex items-center justify-center bg-foreground/10 hover:bg-red-500/20 hover:text-red-500 text-foreground/40 transition-colors border border-[var(--panel-border)]/50 shrink-0`,title:`Remove Row Color`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})}),(0,i.jsx)(`div`,{className:`h-4 w-px bg-[var(--panel-border)]/50 mx-0.5`}),Kr.map(t=>(0,i.jsx)(`button`,{onClick:()=>{let n={...J.colorTimestamps||{},[`row_${e.id}`]:Date.now()};Y({...J,rowColors:{...J.rowColors||{},[e.id]:t.text},colorTimestamps:n}),W(null)},className:`w-4 h-4 rounded-full ${t.bgCircle} hover:scale-125 transition-transform border border-[var(--panel-border)]/50`},t.name))]})]}),(0,i.jsx)(`button`,{onClick:()=>X(e.id),className:`p-2 ml-auto rounded-lg text-foreground/20 hover:text-red-500 hover:bg-red-500/10 transition-colors flex items-center justify-center`,children:(0,i.jsx)(t.Dr,{className:`w-4 h-4`})})]})})]},e.id||`row_${n}`)}),ce.length===0&&(0,i.jsx)(`tr`,{children:(0,i.jsxs)(`td`,{colSpan:(J.columns||[]).length+2,className:`py-12 text-center text-foreground/40 text-[14px] font-medium border border-[var(--panel-border)] m-4 rounded-xl border-dashed`,children:[`No records found in `,J.name||`this table`,`.`]})}),(0,i.jsx)(`tr`,{children:(0,i.jsx)(`td`,{colSpan:(J.columns||[]).length+2,className:`py-2 px-4 border-none bg-foreground/[0.01]`,children:(0,i.jsx)(`div`,{className:`flex items-center gap-4`,children:(0,i.jsx)(`button`,{onClick:re,className:`p-1.5 rounded-lg text-foreground/40 hover:text-accent hover:bg-accent/10 transition-colors flex items-center justify-center ml-2 border border-transparent hover:border-accent/20`,children:(0,i.jsx)(t.Ur,{className:`w-4 h-4`})})})})})]})]},`table`)})})]})]})]})}var Jr=[{text:`text-red-400`,bgCircle:`bg-red-400`,bgCard:`bg-red-500/[0.08]`,borderCard:`border-red-500/30`,bgLight:`bg-red-500/15`,bgHover:`hover:bg-red-500`,bgAlt:`bg-red-500/[0.04]`,name:`Red`},{text:`text-orange-400`,bgCircle:`bg-orange-400`,bgCard:`bg-orange-500/[0.08]`,borderCard:`border-orange-500/30`,bgLight:`bg-orange-500/15`,bgHover:`hover:bg-orange-500`,bgAlt:`bg-orange-500/[0.04]`,name:`Orange`},{text:`text-yellow-400`,bgCircle:`bg-yellow-400`,bgCard:`bg-yellow-500/[0.08]`,borderCard:`border-yellow-500/30`,bgLight:`bg-yellow-500/15`,bgHover:`hover:bg-yellow-500`,bgAlt:`bg-yellow-500/[0.04]`,name:`Yellow`},{text:`text-green-400`,bgCircle:`bg-green-400`,bgCard:`bg-green-500/[0.08]`,borderCard:`border-green-500/30`,bgLight:`bg-green-500/15`,bgHover:`hover:bg-green-500`,bgAlt:`bg-green-500/[0.04]`,name:`Green`},{text:`text-blue-400`,bgCircle:`bg-blue-400`,bgCard:`bg-blue-500/[0.08]`,borderCard:`border-blue-500/30`,bgLight:`bg-blue-500/15`,bgHover:`hover:bg-blue-500`,bgAlt:`bg-blue-500/[0.04]`,name:`Blue`},{text:`text-accent`,bgCircle:`bg-accent`,bgCard:`bg-accent/[0.08]`,borderCard:`border-accent/30`,bgLight:`bg-accent/15`,bgHover:`hover:bg-accent`,bgAlt:`bg-accent/[0.04]`,name:`Purple`},{text:`text-pink-400`,bgCircle:`bg-pink-400`,bgCard:`bg-pink-500/[0.08]`,borderCard:`border-pink-500/30`,bgLight:`bg-pink-500/15`,bgHover:`hover:bg-pink-500`,bgAlt:`bg-pink-500/[0.04]`,name:`Pink`},{text:`text-foreground/60`,bgCircle:`bg-foreground/30`,bgCard:`bg-foreground/[0.04]`,borderCard:`border-[var(--panel-border)]/50`,bgLight:`bg-foreground/15`,bgHover:`hover:bg-foreground/30`,bgAlt:`bg-foreground/[0.02]`,name:`Default`}],Yr={dateStr:``,title:``,description:``,time:`12:00`,duration:`60`,color:``,guestEmail:``,customFields:{}};function Xr({title:e=`Calendar View`,subtitle:n=`/calendar`,backUrl:s=`/templates`,eventsCollection:l=`pub_events`,defaultTimeFormat:u=`12h`,config:d,customContent:f}){let p=!!(d?.isPrivate||d?.isAdmin||d?.isInternal||d?.isShared);d?.isAdmin,d?.isInternal||d?.isShared,d?.isPrivate;let m=d?.showButton!==!1,h=d?.buttonText||`+`,g=d?.buttonStyle||`primary`,_=d?.showViewsButton!==!1,v=d?.viewsButtonStyle||`secondary`,y=d?.defaultView||`calendar`,b=d?.customFields||[],x=l.startsWith(`user_`)?`user`:l.startsWith(`mem_`)||l.startsWith(`role_`)?`internal`:l.startsWith(`admin_`)?`admin_only`:`public`,[S,C]=(0,r.useState)(()=>{try{let e=localStorage.getItem(`cal_view_${l}`);if(e===`list`||e===`month`)return e}catch{}return y===`board`?`list`:`month`}),[w,T]=(0,r.useState)([]),[E,D]=(0,r.useState)(!1),[O,k]=(0,r.useState)(null),[A,j]=(0,r.useState)(!1),[M,N]=(0,r.useState)(!1),[P,F]=(0,r.useState)(null),[I,L]=(0,r.useState)(Yr),[R,z]=(0,r.useState)(new Date),[B,V]=(0,r.useState)(null),[H,U]=(0,r.useState)(null),[W,G]=(0,r.useState)(!1),ee=`cal_24h_${l}`,[K,q]=(0,r.useState)(()=>{try{let e=localStorage.getItem(ee);if(e!==null)return e===`true`}catch{}return u===`24h`}),J=()=>{let e=!K;q(e);try{localStorage.setItem(ee,String(e))}catch{}};(0,r.useEffect)(()=>{try{localStorage.setItem(`cal_view_${l}`,S)}catch{}},[S,l,x]);let Y=()=>{let e=S===`month`?`list`:`month`;C(e);try{localStorage.setItem(`cal_view_${l}`,e)}catch{}},te=()=>{try{return sessionStorage.getItem(`cal_guest_email`)||``}catch{return``}},ne=e=>{try{sessionStorage.setItem(`cal_guest_email`,e)}catch{}};(0,r.useEffect)(()=>(0,a.onAuthStateChanged)(t.Ea,async e=>{if(V(e),e&&x===`admin_only`)try{let n=await(0,o.getDoc)((0,o.doc)(t.Da,`user_profiles`,e.uid));n.exists()&&U(n.data())}catch{}G(!0)}),[x]),(0,r.useEffect)(()=>{if(!W)return;if(x!==`public`&&!B){T([]);return}try{let e=localStorage.getItem(`fbos_cal_${l}`);e&&T(JSON.parse(e))}catch{}let e=(0,o.onSnapshot)(x===`user`&&B?(0,o.query)((0,o.collection)(t.Da,l),(0,o.where)(`uid`,`==`,B.uid)):(0,o.collection)(t.Da,l),e=>{let t=[];e.forEach(e=>t.push({id:e.id,...e.data()})),T(t),localStorage.setItem(`fbos_cal_${l}`,JSON.stringify(t))},e=>console.error(`Calendar events:`,e));return()=>e()},[l,x,B?.uid,W]);let re=e=>!!B&&B.uid===e.uid,X=e=>x===`public`?!1:x===`user`?!!B:re(e),Z=(e,t)=>!B||x===`public`?e:x===`user`?{...e,uid:B.uid}:t?{uid:B.uid,creatorEmail:B.email||``,creatorName:B.displayName||``,creatorAvatar:B.photoURL||``,...e}:e,Q=e=>{if(!e)return``;if(K)return e;let[t,n]=e.split(`:`),r=parseInt(t,10),i=r>=12?`PM`:`AM`;return r=r%12||12,`${r}:${n} ${i}`},ie=e=>{if(!e)return`60m`;let t=parseInt(e,10);return isNaN(t)?e:t>=60?t%60==0?`${t/60}h`:`${Math.floor(t/60)}h ${t%60}m`:`${t}m`},ae=e=>{let[t,n]=(e||`12:00`).split(`:`),r=parseInt(t,10)||0,i=parseInt(n,10)||0,a=r>=12?`PM`:`AM`;return r=r%12||12,{h:r,m:i,ampm:a}},oe=(e,t,n)=>{let r=e%12;return n===`PM`&&(r+=12),`${r.toString().padStart(2,`0`)}:${t.toString().padStart(2,`0`)}`},se=e=>{let t=e.getTimezoneOffset()*6e4;return new Date(e.getTime()-t).toISOString().split(`T`)[0]},ce=()=>se(new Date),le=new Date(R.getFullYear(),R.getMonth(),1),ue=new Date(R.getFullYear(),R.getMonth()+1,0),de=le.getDay(),fe=ue.getDate(),pe=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],me=Array.from({length:42},(e,t)=>{let n=t-de+1,r=new Date(R.getFullYear(),R.getMonth(),n);return{day:r.getDate(),dateStr:se(r),isCurrentMonth:n>0&&n<=fe}}),he=()=>z(S===`month`?new Date(R.getFullYear(),R.getMonth()-1,1):new Date(R.getFullYear(),R.getMonth(),R.getDate()-1)),ge=()=>z(S===`month`?new Date(R.getFullYear(),R.getMonth()+1,1):new Date(R.getFullYear(),R.getMonth(),R.getDate()+1)),_e=e=>{if(x!==`public`&&!B)return;let t=new Date;t.setDate(t.getDate()+1);let n=new Date().getHours().toString().padStart(2,`0`);L({...Yr,dateStr:e||se(t),time:`${n}:00`,guestEmail:x===`public`?te():``,customFields:{}}),D(!0)},ve=e=>{let t=e.time;if(t){let[e,n]=t.split(`:`);e&&n&&(t=`${e.padStart(2,`0`)}:${n}`)}L({id:e.id,uid:e.uid,dateStr:e.dateStr,title:e.title,description:e.description||``,time:t||`12:00`,duration:e.duration||`60`,color:e.color||``,guestEmail:e.creatorEmail||``,customFields:e.customFields||{}}),D(!0)},ye=async e=>{if(e.preventDefault(),I.title.trim()){j(!0);try{let e={dateStr:I.dateStr,title:I.title.trim(),description:I.description.trim(),time:I.time,duration:I.duration||`60`};if(I.color&&(e.color=I.color),b.length>0&&(e.customFields=I.customFields),!I.id)if(x===`public`){let t=I.guestEmail.trim();e.creatorEmail=t,ne(t)}else x===`user`||x===`internal`?(e.uid=B?.uid,e.creatorEmail=B?.email||``,e.creatorName=B?.displayName||``,e.creatorAvatar=B?.photoURL||``):x===`admin_only`&&(e.uid=B?.uid,e.creatorEmail=H?.email||B?.email||``,e.creatorName=H?.displayName||H?.name||``,e.creatorAvatar=H?.avatar||H?.avatarUrl||B?.photoURL||``);I.id?(await(0,o.setDoc)((0,o.doc)(t.Da,l,I.id),e,{merge:!0}),O?.id===I.id&&k({...O,...e})):await(0,o.setDoc)((0,o.doc)(t.Da,l,`ev_${Date.now()}`),e,{merge:!0}),D(!1)}catch(e){console.error(e)}j(!1)}},be=async()=>{if(P){N(!0);try{await(0,o.deleteDoc)((0,o.doc)(t.Da,l,P.id)),O?.id===P.id&&k(null),F(null),D(!1)}catch{}N(!1)}},xe=e=>{if(x===`user`||!e.creatorEmail&&!e.creatorName)return null;let t=(e.creatorName||e.creatorEmail||`?`).charAt(0).toUpperCase(),n=Jr.find(t=>t.text===e.color);return(0,i.jsxs)(`div`,{className:`flex items-center gap-3 mt-4 p-3 rounded-xl bg-foreground/[0.03] border border-[var(--panel-border)]/50`,children:[e.creatorAvatar?(0,i.jsx)(`img`,{src:e.creatorAvatar,alt:``,className:`w-8 h-8 rounded-full object-cover shrink-0`}):(0,i.jsx)(`div`,{className:`w-8 h-8 rounded-full ${n?.bgCircle||`bg-accent`} flex items-center justify-center text-[13px] font-extrabold text-white shrink-0`,children:t}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0`,children:[e.creatorName&&(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground/90 truncate`,children:e.creatorName}),e.creatorEmail&&(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/50 truncate`,children:e.creatorEmail})]})]})},Se=e=>{if(x===`user`||x===`public`||!e.creatorName&&!e.creatorEmail)return null;let t=e.creatorName||e.creatorEmail?.split(`@`)[0]||``,n=t.split(` `).map(e=>e[0]).join(``).toUpperCase().slice(0,2);return(0,i.jsxs)(`div`,{className:`flex items-center gap-2 mt-2 pt-2 border-t border-[var(--panel-border)]/30`,children:[e.creatorAvatar?(0,i.jsx)(`img`,{src:e.creatorAvatar,alt:``,className:`w-5 h-5 rounded-full object-cover shrink-0`}):(0,i.jsx)(`div`,{className:`w-5 h-5 rounded-full bg-accent/15 text-accent flex items-center justify-center text-[8px] font-extrabold shrink-0`,children:n}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 truncate`,children:t}),e.creatorEmail&&(0,i.jsxs)(`span`,{className:`text-[10px] text-foreground/25 truncate`,children:[`· `,e.creatorEmail]})]})]})};if(W&&x!==`public`&&!B)return(0,i.jsx)(`main`,{className:`flex-1 w-full flex items-center justify-center min-h-screen p-8`,children:(0,i.jsxs)(`div`,{className:`text-center glass-panel border border-[var(--panel-border)] rounded-3xl p-12 max-w-sm w-full`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-full bg-accent/10 border border-accent/20 flex items-center justify-center mx-auto mb-4`,children:(0,i.jsx)(t.Zr,{className:`w-7 h-7 text-accent`})}),(0,i.jsx)(`h2`,{className:`text-2xl font-extrabold mb-2`,children:`Sign in required`}),(0,i.jsx)(`p`,{className:`text-foreground/50 text-[14px] mb-6`,children:`You need to be signed in to access this calendar.`}),(0,i.jsx)(c.Link,{to:`/login`,className:`inline-flex items-center justify-center gap-2 px-6 py-2.5 rounded-xl btn-primary font-bold text-[14px] w-full`,children:`Sign In`})]})});if(!W&&x!==`public`)return(0,i.jsx)(`main`,{className:`flex-1 w-full flex items-center justify-center min-h-screen`,children:(0,i.jsx)(t.ti,{className:`w-8 h-8 animate-spin text-accent`})});let we=!!f,Te=(x===`public`||!!B)&&m&&!we,Ee=()=>(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4 p-4 sm:p-6 md:px-8 md:py-6 border-b border-[var(--panel-border)]/50 bg-background/50 shrink-0`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:d?.tabTitle||d?.tabName||e}),(0,i.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:[w.length,` `,w.length===1?`event`:`events`,` · `,S===`month`?`Month`:`Board`,` View`]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:J,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer btn-secondary text-[12px] font-extrabold`,children:K?`24h`:`12h`}),_&&!we&&(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:Y,title:S===`month`?`Switch to Board`:`Switch to Calendar`,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer ${v===`primary`?`btn-primary`:`btn-secondary`}`,children:S===`month`?(0,i.jsx)(t.oi,{className:`w-4 h-4`}):(0,i.jsx)(t.Vi,{className:`w-4 h-4`})}),Te&&(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>_e(),title:`Add event`,"aria-label":`Add event`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer ${h===`+`?`w-10`:`px-5`} ${g===`primary`?`btn-primary`:`btn-secondary`}`,children:h===`+`?(0,i.jsx)(t.Ur,{className:`w-4 h-4`}):(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:h})})]})]}),De=()=>(0,i.jsxs)(`div`,{className:`p-4 md:p-6 border-b border-[var(--panel-border)]/50 flex flex-wrap items-center justify-between gap-x-3 gap-y-2 bg-foreground/[0.01]`,children:[(0,i.jsx)(`h3`,{className:`text-lg md:text-xl font-extrabold tracking-tight ml-2 min-w-0`,children:S===`month`?R.toLocaleString(`default`,{month:`long`,year:`numeric`}):R.toLocaleString(`default`,{month:`long`,day:`numeric`,year:`numeric`})}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,i.jsx)(`button`,{onClick:()=>z(new Date),className:`px-3 md:px-4 py-2 text-[13px] font-bold border border-[var(--panel-border)] rounded-xl mr-1 md:mr-2 hover:bg-foreground/5 transition-colors`,children:`Today`}),(0,i.jsx)(`button`,{onClick:he,className:`p-2 rounded-xl text-foreground/50 hover:text-foreground hover:bg-foreground/5 transition-colors border border-transparent hover:border-[var(--panel-border)]`,children:(0,i.jsx)(t.Li,{className:`w-5 h-5`})}),(0,i.jsx)(`button`,{onClick:ge,className:`p-2 rounded-xl text-foreground/50 hover:text-foreground hover:bg-foreground/5 transition-colors border border-transparent hover:border-[var(--panel-border)]`,children:(0,i.jsx)(t.Ii,{className:`w-5 h-5`})})]})]}),Oe=()=>(0,i.jsxs)(i.Fragment,{children:[De(),f?(0,i.jsx)(`div`,{className:`fbos-content-slot p-4 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:(0,i.jsx)(f,{config:d,actions:{events:w,loading:!W,collection:l,currentUser:B,user:B,saveEvent:async e=>{let n=e.id||`ev_${Date.now()}`,r=Z(e,!w.some(e=>e.id===n));T(e=>e.find(e=>e.id===n)?e.map(e=>e.id===n?{...e,...r}:e):[...e,{id:n,...r}]),await(0,o.setDoc)((0,o.doc)(t.Da,l,n),r,{merge:!0})},deleteEvent:async e=>{T(t=>t.filter(t=>t.id!==e)),await(0,o.deleteDoc)((0,o.doc)(t.Da,l,e))},openAddModal:e=>_e(e),openEditModal:e=>ve(e),setViewingEvent:e=>k(e),currentDate:R,setCurrentDate:z,goToPrev:he,goToNext:ge,goToToday:()=>z(new Date)}})}):S===`month`?(0,i.jsx)(`div`,{className:`overflow-x-auto w-full flex-1`,children:(0,i.jsxs)(`div`,{className:`min-w-[800px] h-full flex flex-col`,children:[(0,i.jsx)(`div`,{className:`grid grid-cols-7 border-b border-[var(--panel-border)]/50 bg-foreground/[0.02]`,children:pe.map(e=>(0,i.jsx)(`div`,{className:`py-3 text-center text-[12px] font-bold uppercase tracking-wider text-foreground/40`,children:e},e))}),(0,i.jsx)(`div`,{className:`grid grid-cols-7 auto-rows-auto bg-[var(--panel-border)] gap-[1px] relative flex-1`,children:me.map((e,n)=>{let r=e.dateStr===ce(),a=w.filter(t=>t.dateStr===e.dateStr);return(0,i.jsxs)(`div`,{onClick:()=>e.isCurrentMonth&&Te&&_e(e.dateStr),className:`min-h-[140px] p-2 bg-[var(--panel-bg)] flex flex-col relative group
|
|
5
|
-
${e.isCurrentMonth?Te?`hover:bg-foreground/[0.03] transition-colors cursor-cell`:``:`opacity-30 bg-background/50 pointer-events-none`}`,children:[(0,i.jsx)(`div`,{className:`flex justify-between items-start mb-2 shrink-0`,children:(0,i.jsx)(`span`,{className:`w-8 h-8 rounded-full flex items-center justify-center text-[14px] font-bold ${r?`bg-accent text-white shadow-lg shadow-accent/20`:`text-foreground/70 group-hover:text-foreground`}`,children:e.day})}),(0,i.jsx)(`div`,{className:`flex flex-col gap-1.5 flex-1 w-full relative z-10 pb-1`,children:a.map(e=>{let n=Jr.find(t=>t.text===e.color),r=X(e);return(0,i.jsxs)(`div`,{className:`px-2 py-1.5 rounded-lg border transition-colors shadow-sm cursor-pointer group/ev relative ${n?n.bgCard+` `+n.borderCard:`bg-accent/20 border-accent/30 hover:bg-accent/40`}`,onClick:t=>{t.stopPropagation(),k(e)},children:[(0,i.jsx)(`p`,{className:`text-[12px] font-bold truncate leading-tight ${r?`pr-5`:``} ${n?n.text:`text-foreground`}`,children:e.title}),(0,i.jsx)(`p`,{className:`text-[10px] text-foreground/70 mt-0.5`,children:Q(e.time)}),r&&(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),ve(e)},className:`absolute top-1 right-1 opacity-0 group-hover/ev:opacity-100 p-1 text-foreground/60 hover:bg-foreground/10 hover:text-foreground transition-all rounded`,children:(0,i.jsx)(t.Kr,{className:`w-3 h-3`})})]},e.id)})})]},n)})}),(0,i.jsx)(`style`,{children:`
|
|
6
|
-
|
|
7
|
-
.styled-scrollbars::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--accent-color) 30%,transparent);border-radius:4px}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
input[type="date"]::-webkit-calendar-picker-indicator:hover{opacity:1}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
|
|
15
|
-
input[type="number"]{-moz-appearance:textfield}
|
|
16
|
-
`}),(0,i.jsxs)(`div`,{className:`relative group/date flex flex-col w-full`,children:[(0,i.jsx)(t.lr,{type:`date`,label:`Date`,required:!0,value:I.dateStr,onChange:e=>L({...I,dateStr:e.target.value}),className:`pr-10`}),(0,i.jsx)(`div`,{className:`absolute right-4 bottom-4 pointer-events-none group-focus-within/date:text-accent text-foreground/40 transition-colors`,children:(0,i.jsx)(t.Vi,{className:`w-4 h-4`})})]}),(0,i.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-4`,children:[K?(0,i.jsx)(t.lr,{type:`time`,label:`Time`,value:I.time,onChange:e=>L({...I,time:e.target.value}),required:!0}):(()=>{let{h:e,m:t,ampm:n}=ae(I.time);return(0,i.jsxs)(`div`,{className:`flex flex-col w-full`,children:[(0,i.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,children:`Time`}),(0,i.jsxs)(`div`,{className:`flex items-center h-12 glass-panel border border-[var(--panel-border)] rounded-xl px-3 gap-1 focus-within:border-accent transition-colors`,children:[(0,i.jsx)(`input`,{type:`number`,min:1,max:12,value:e,onChange:e=>L({...I,time:oe(Math.min(12,Math.max(1,parseInt(e.target.value)||12)),t,n)}),className:`w-8 text-center bg-transparent focus:outline-none text-foreground font-bold text-[15px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none`}),(0,i.jsx)(`span`,{className:`text-foreground/40 font-bold text-[15px] select-none`,children:`:`}),(0,i.jsx)(`input`,{type:`number`,min:0,max:59,value:t.toString().padStart(2,`0`),onChange:t=>L({...I,time:oe(e,Math.min(59,Math.max(0,parseInt(t.target.value)||0)),n)}),className:`w-8 text-center bg-transparent focus:outline-none text-foreground font-bold text-[15px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>L({...I,time:oe(e,t,n===`AM`?`PM`:`AM`)}),className:`ml-auto px-2 py-0.5 rounded-md bg-accent/10 text-accent text-[11px] font-extrabold uppercase tracking-wider hover:bg-accent/20 transition-colors shrink-0`,children:n})]})]})})(),(0,i.jsx)(t.lr,{type:`number`,min:`1`,max:`1440`,label:`Duration (min)`,value:I.duration,onChange:e=>L({...I,duration:e.target.value}),placeholder:`60`,required:!0})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsx)(`label`,{className:`text-[11px] font-bold text-foreground/50 uppercase tracking-widest mt-1`,children:`Event Color`}),(0,i.jsx)(`div`,{className:`flex gap-2 items-center relative z-10 w-full h-[46px]`,children:Jr.map(e=>(0,i.jsx)(`button`,{type:`button`,onClick:()=>L({...I,color:I.color===e.text?``:e.text}),className:`w-6 h-6 rounded-full shrink-0 ${e.bgCircle} hover:scale-110 transition-transform flex items-center justify-center border border-[var(--panel-border)]`,children:I.color===e.text&&(0,i.jsx)(`div`,{className:`w-2.5 h-2.5 rounded-full bg-background`})},e.name))})]}),(0,i.jsx)(`div`,{className:`pt-2`,children:(0,i.jsx)(t.cr,{type:`submit`,isLoading:A,className:`w-full py-3`,children:I.id?`Save Changes`:`Create Event`})})]})]})]},`edit-modal`),(0,i.jsx)(Ve,{isOpen:!!P,title:`Confirm Deletion`,message:(0,i.jsxs)(i.Fragment,{children:[`Are you sure you want to delete `,(0,i.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:P?.title}),` This action is permanent.`]}),onConfirm:be,onCancel:()=>{F(null)},isProcessing:M,confirmText:`Yes, Delete`})]});return p?(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(Ce,{children:d?.tabTitle||d?.tabName||e}),n&&(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),n]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background`,children:[Ee(),Oe()]})]}),ke()]}):(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[s&&(0,i.jsx)(Wt,{to:s}),(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(Ce,{children:e}),n&&(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),n]})]})]}),(0,i.jsx)(`div`,{className:`flex flex-col gap-6 flex-1 min-h-0 pb-16`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 min-h-[400px] shadow-2xl bg-background relative`,children:[(0,i.jsx)(`div`,{className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[800px] h-[800px] bg-accent/5 blur-[120px] rounded-full pointer-events-none -z-10`}),Ee(),Oe()]})}),ke()]})}var Zr=`fbos_theme_ai_draft`,Qr=()=>{try{return JSON.parse(localStorage.getItem(Zr)||`{}`)}catch{return{}}},$r=e=>{let t=String(e?.defaultTheme||``).trim();return t===`light`||t===`dark`?t:null},ei=`My logo is attached to this message as a picture. Read the colours straight out of that picture and build this look from them — that is what matching my logo means. If no picture reached you, say so and ask me for it, rather than picking colours of your own.`,ti=`Do it all in one file: src/your-ai-workflow-firebase-os/configs/theme.config.ts — the colours and how rounded things are. Do not restyle by rewriting components, and do not put colours of your own anywhere else.`,ni=`Use every colour the picture has, not just one. The accent is the one that stands out most — never one close to the accent the file holds now, so the change is plain to see — and the others go into the button fade, the heading gradient, the notification dot, the tint behind panels and the highlight behind selected text. Even the two backgrounds carry a faint wash of the logo instead of plain white or black. Read the exact shades off the picture; do not round them to the nearest colour you already know.`,ri=`Mix a palette of your own for this brief — more than one colour. The accent is the one that stands out most — never one close to the accent the file holds now, so the change is plain to see — and the others go into the button fade, the heading gradient, the notification dot, the tint behind panels and the highlight behind selected text. Even the two backgrounds carry a faint wash of the palette instead of plain white or black.`,ii=`Be as bold as my brief allows and decide everything yourself: this is your design, and a look that could pass for a default is the one thing I do not want. Mix each shade for this look. A swatch you know by heart from Tailwind, Material or any other stock palette — #38bdf8, #0f172a, #f8fafc and their kind — means you did not look, so mix your own instead. Keep text readable on its background in both modes.`,ai=`Every mode needs these five: background, backgroundSecondary, foreground, accent and buttonText. The other colours the file allows — the button fade and its hover, the quiet button, panel fill and edge, the focus glow, the notification dot, the heading gradient, and the highlight behind text someone selects together with the colour of that selected text — are yours to set wherever the look calls for them, and a colourful look wants the button fade, the heading gradient and the selection highlight at the least: selected text left in a colour from the look before is the first thing people notice. Where I have named a colour myself, use my exact value. Anything left in the file that you did not choose for this look, delete rather than keep: a colour left over from the look before is what makes a new theme come out wrong.`,oi=`Every mode keeps its five: background, backgroundSecondary, foreground, accent and buttonText. Where I name a colour, use my exact value, in both modes. If the change touches the accent, the highlight behind selected text follows it. Mix any new shade for this look rather than taking a stock swatch, and never copy a colour from another theme or an example.`,si=(e,t)=>String(e||``).trim()===String(t||``).trim(),ci=(e,t)=>e===`light`||e===`dark`?t.defaultTheme===e&&t.showThemeToggle===!1:e===`system`?t.defaultTheme===`system`:!1,li=(e,t)=>{if(!t)return e;let n={...e};return si(e.appName,t.appName)&&delete n.appName,si(e.logoUrl,t.logoUrl)&&delete n.logoUrl,si(e.faviconUrl,t.faviconUrl)&&delete n.faviconUrl,ci(String(e.defaultTheme||``).trim(),t)&&delete n.defaultTheme,n},ui=`Before you tell me it is done, read the file back: if background, backgroundSecondary, foreground or accent is still the value it held when you started, in either mode, then you have not done what I asked — go and set it. And if every value you wrote is a stock swatch, you have not designed anything — go back and mix your own.`,di=e=>{let t=$r(e),n=`That is ten values at the least — five in dark, five in light — and every one of them changes: the colours in that file now are the look I am replacing, so a colour you leave where it is is the mistake I am trying to avoid.`;if(t){let e=t===`light`?`dark`:`light`;return`My site is ${t} only, so the ${t} colours are the ones everyone sees — design those with the most care. Set the ${e} colours as well, the same look ${e===`dark`?`at night`:`by day`}, since the file needs both. ${n}`}return`Set the dark colours and the light colours both, so my site reads well either way — the same hues in both, dark mode being the same look at night, not a second palette. ${n}`},fi=e=>{let t=String(e?.brief||``).trim(),n=String(e?.logoUrl||``).trim()!==``;return[...[`Design the look of my whole app. Here is what I am after: ${t||`___`}`,...n?[ei]:[],ti,di(e),n?ni:ri,ii,ai,...hi(e),ui],...gi].join(`
|
|
17
|
-
`)},pi=(e,t)=>{let n=String(e?.changes||``).trim(),r=li(e||{},t);return[...[`My app already has a look I am happy with, set in one file: src/your-ai-workflow-firebase-os/configs/theme.config.ts.`,`Change that one file, and change only what I ask for below. Do not restyle by rewriting components, and do not put colours of your own anywhere else.`,`Leave everything else in that file exactly as it is — how rounded things are, and every colour I have not mentioned. Do not tidy up, rebalance or improve anything I did not ask about.`,`If what I ask for is a colour, set it in the dark colours and the light colours both, so my site still reads well either way.`,oi,`Here is what I would like changed: ${n||`___`}`,...hi(r,`change`)],...gi].join(`
|
|
18
|
-
`)},mi=e=>{let t=String(e?.defaultTheme||``).trim();return t===`light`||t===`dark`?`In that same file, set defaultTheme to '${t}' and showThemeToggle to false: my site is ${t} only, and visitors get no switch.`:t===`system`?`In that same file, set defaultTheme to 'system', so my site opens in whichever mode the visitor's device already uses, and leave showThemeToggle as it is.`:`Leave defaultTheme exactly as it is — how my site opens is not part of this job, and changing it is not a redesign.`},hi=(e,t=`design`)=>{let n=String(e?.appName||``).trim(),r=String(e?.logoUrl||``).trim(),i=String(e?.faviconUrl||``).trim(),a=[`light`,`dark`,`system`].includes(String(e?.defaultTheme||``).trim()),o=a||t===`design`?[mi(e)]:[];if(n&&o.push(`In that same file, set appName to exactly: ${n}`),r&&o.push(`In that same file, set logoUrl to exactly this link: ${r} — that is my logo for the top bar. Use my link character for character, and never swap it for a placeholder or a picture of your own.`),i&&o.push(i===r?`Set faviconUrl to that same link — it is my browser tab icon too.`:`In that same file, set faviconUrl to exactly this link: ${i} — that is my browser tab icon. Use my link character for character.`),t===`change`){let e=[...r?[]:[`logoUrl`],...i?[]:[`faviconUrl`],...n?[]:[`appName`],...a?[]:[`defaultTheme and showThemeToggle`]];if(e.length){let t=e.length>1?`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`:e[0];o.push(`Leave ${t} exactly as they are — not part of this change.`)}return o}return!r&&!i?o.push(`Leave logoUrl and faviconUrl exactly as they are. The logo and the browser tab icon are mine, and my Theme screen is the only place they change.`):r?i||o.push(`Leave faviconUrl exactly as it is — my browser tab icon is mine, and my Theme screen is the only place it changes.`):o.push(`Leave logoUrl exactly as it is — my logo is mine, and my Theme screen is the only place it changes.`),o},gi=[`Tell me what you picked and why, in one short paragraph.`],_i=(e,t=`design`)=>t===`change`?String(e?.changes||``).trim()?``:`Say what you would like changed, and this sentence is ready to copy.`:String(e?.brief||``).trim()?``:`Say what look you are after, and this sentence is ready to copy.`;function vi(){let{activeConfig:e}=t.ja(),[n,a]=(0,r.useState)(Qr),[o,s]=(0,r.useState)(()=>Qr().mode===`change`?`change`:`design`),l=e=>{s(e),a(t=>{let n={...t};e===`change`?n.mode=`change`:delete n.mode;try{localStorage.setItem(Zr,JSON.stringify(n))}catch{}return n})},u=(e,t)=>a(n=>{let r={...n,[e]:t};try{localStorage.setItem(Zr,JSON.stringify(r))}catch{}return r}),[d,f]=(0,r.useState)(!1),[p,m]=(0,r.useState)(null),h=()=>{f(!0);try{localStorage.removeItem(Zr),localStorage.removeItem(`theme-mode`),localStorage.removeItem(`last-seen-default-theme`),localStorage.removeItem(`theme_saved_cache`)}catch{}a({}),s(`design`),setTimeout(()=>f(!1),600)};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(Ce,{children:`Theme`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/theme`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,i.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-extrabold text-foreground tracking-tight`,children:o===`change`?`Change it with your assistant`:`Design it with your assistant`}),(0,i.jsxs)(`p`,{className:`text-[12.5px] sm:text-[13.5px] font-medium text-foreground/55 mt-1 sm:mt-1.5`,children:[(0,i.jsx)(`span`,{className:`sm:hidden`,children:`Fill these in for your assistant.`}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:o===`change`?`Say what to change, then copy the sentence below into your assistant’s chat. Nothing you do not mention is touched.`:`Fill these in, then copy the sentence below into your assistant’s chat. It designs the whole look — colours, corners, logo — and there is nothing to set by hand.`})]})]}),(0,i.jsx)(`div`,{className:`shrink-0 flex items-center gap-2`,children:(0,i.jsx)(t.Q,{icon:t.Rr,tone:`danger`,compact:!0,busy:d,title:`Start the whole look again`,onClick:()=>m({title:`Start the whole look again?`,message:`Your answers here clear and the sentence goes back to designing the whole look. Your theme file is not touched — copy the new sentence to your assistant to change it.`,apply:h}),children:`Start again`})})]}),(0,i.jsx)(st,{label:`Logo`,hint:`The picture in the top bar. Attach this same picture in your assistant's chat — it cannot open the link, and the picture is where the colours come from.`,value:n.logoUrl||``,onChange:e=>u(`logoUrl`,e),tips:lt}),(0,i.jsx)(st,{label:`Browser tab icon`,hint:`The tiny picture on the browser tab.`,value:n.faviconUrl||``,onChange:e=>u(`faviconUrl`,e),tips:ut}),(0,i.jsx)(t.ft,{label:`App name`,hint:`It goes in the top bar and on the browser tab.`,value:n.appName||``,onChange:e=>u(`appName`,e),placeholder:`Bright Studio`}),(0,i.jsx)(t.ct,{label:`How the site opens`,hint:`Only if you want it changed. Always light or always dark means one mode and no switch; otherwise whichever one the visitor already uses on their device, with a switch.`,value:n.defaultTheme||``,onChange:e=>u(`defaultTheme`,e),placeholder:`Leave it as it is`,options:[{value:`system`,label:`Whatever their device uses`},{value:`light`,label:`Always light`},{value:`dark`,label:`Always dark`}]}),o===`change`?(0,i.jsx)(t.dt,{label:`What would you like changed?`,hint:`Name just the parts you want moved. Everything else stays as it is.`,value:n.changes||``,onChange:e=>u(`changes`,e),placeholder:`Make the buttons a softer green, and warm up the page background a little. Leave the cards as they are.`}):(0,i.jsx)(t.dt,{label:`What look would you like?`,hint:`What you do, who it is for, and the feeling you are after. Your assistant designs the rest — the more feeling you give it, the further it goes.`,value:n.brief||``,onChange:e=>u(`brief`,e),placeholder:`A calm, modern look for a small physiotherapy clinic. Soft greens, lots of white space, nothing shouty. Rounded corners.`}),(0,i.jsx)(it,{title:`Copy this to your assistant`,prompt:o===`change`?pi(n,e):fi(n),locked:!!_i(n,o),onCopied:o===`change`?void 0:()=>l(`change`)}),(0,i.jsxs)(`p`,{className:`text-[11.5px] text-foreground/45 font-medium leading-snug px-1`,children:[`That sentence is the only way the look changes — there is nothing to set by hand here. Uploads are kept on your`,` `,(0,i.jsx)(c.Link,{to:`/assets`,className:`text-accent font-bold hover:underline`,children:`Assets page`}),` `,`too; edit the fields and copy the sentence again any time.`]})]})})]}),(0,i.jsx)(Ve,{isOpen:!!p,title:p?.title||``,message:p?.message||``,confirmText:`Start again`,cancelText:`Keep it`,isProcessing:d,onCancel:()=>m(null),onConfirm:()=>{p?.apply(),m(null)}})]})}function yi({tone:e,title:t,message:n,action:r}){let a=e===`red`?`border-red-500/20`:`border-amber-500/25`,o=e===`red`?`bg-red-500/5`:`bg-amber-500/5`,s=e===`red`?`text-red-500`:`text-amber-500`;return(0,i.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-center relative z-10 min-h-[60vh] animate-in fade-in duration-500`,children:(0,i.jsxs)(`div`,{className:`glass-panel p-8 md:p-10 rounded-3xl border ${a} text-center shadow-xl max-w-sm w-full relative overflow-hidden`,children:[(0,i.jsx)(`div`,{className:`absolute inset-0 ${o}`}),(0,i.jsx)(`h2`,{className:`text-2xl font-black ${s} mb-3 relative z-10 tracking-tight`,children:t}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/70 font-medium leading-relaxed relative z-10 mb-6`,children:n}),(0,i.jsx)(`div`,{className:`relative z-10`,children:r})]})})}var bi=`w-full block py-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground text-[14px] font-bold rounded-xl transition-colors`,xi=`No access`,Si=`You do not have access to view this page. If you think you should, ask whoever runs this app.`,Ci=()=>(0,i.jsx)(yi,{tone:`amber`,title:xi,message:Si,action:(0,i.jsx)(c.Link,{to:`/dashboard`,className:bi,children:`Back to dashboard`})}),wi=Ci,Ti=Ci,Ei={route:`/page_1`,pageName:`New Page`,pageTitle:`My New Page`,template:`none`,form:``},Di={tabName:`New Page`,iconName:``,route:`/new-page`,tabTitle:`Your Page`,template:`none`,form:``},Oi={tabName:`New Admin Page`,iconName:``,route:`/new-admin-page`,tabTitle:`Admin Page`,template:`none`,form:``},ki={tabName:`New Team Page`,iconName:``,route:`/new-team-page`,tabTitle:`Team Page`,template:`none`,form:``},Ai=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``),ji=`sys_payments`,Mi=`_settings`,Ni=()=>({on:!1,amount:``,priceId:``,livePriceId:``}),Pi=()=>({name:``,description:``,monthly:{...Ni(),on:!0},yearly:Ni()}),Fi=()=>({name:``,amount:``}),Ii=e=>({id:e,name:``,description:``,kind:``,amount:``,items:[],plans:[],how:``,emailReceipt:!0,notifyOwner:!0,pageIds:[],pagesNote:``,customNote:``,customPath:``,createdAt:Date.now()}),Li=e=>e.kind===`once`?e.items.length?e.items:e.name.trim()||e.amount.trim()?[{name:e.name,amount:e.amount}]:[]:[],Ri=e=>{let t=Number(String(e||``).trim().replace(/[^0-9.]/g,``));return Number.isFinite(t)&&t>0?t:null},zi=e=>({on:!!e?.on,amount:String(e?.amount||``),priceId:String(e?.priceId||``),livePriceId:String(e?.livePriceId||``)}),Bi=e=>/^(no|none|nothing|n\/?a|nothing needed|nothing else|-)[.!]*$/i.test(e.trim()),Vi=e=>/[.!?]$/.test(e)?e:`${e}.`,Hi=e=>{let t=[],n=String(e?.how||``),r=String(e?.collect||``).trim();r&&!Bi(r)&&t.push(`Before paying, the buyer tells me: ${Vi(r)}`);let i=String(e?.after||``).trim();if(i&&t.push(`After they pay: ${Vi(i)}`),Array.isArray(e?.plans))for(let n of e.plans){let e=String(n?.name||``).trim()||`The plan`,r=String(n?.features||``).trim(),i=String(n?.sees||``).trim();r&&t.push(`${e} unlocks: ${Vi(r)}`),i&&t.push(`Someone on ${e} sees: ${Vi(i)}`)}return t.length?[...n.trim()?[Vi(n.trim())]:[],...t].join(` `):n},Ui=(e,t)=>{let n=t?.kind===`once`||t?.kind===`subscription`?t.kind:``,r=Array.isArray(t?.items)?t.items.map(e=>({name:String(e?.name||``),amount:String(e?.amount||``)})):[],i=String(t?.name||``),a=String(t?.amount||``);return n===`once`&&!r.length&&(i.trim()||a.trim())&&(r=[{name:i,amount:a}],i=``,a=``),{id:e,name:i,description:String(t?.description||``),kind:n,amount:a,items:r,plans:Array.isArray(t?.plans)?t.plans.map(e=>({name:String(e?.name||``),description:String(e?.description||``),monthly:zi(e?.monthly),yearly:zi(e?.yearly)})):[],how:Hi(t),emailReceipt:t?.emailReceipt!==!1,notifyOwner:t?.notifyOwner!==!1,pageIds:Array.isArray(t?.pageIds)?t.pageIds.map(e=>String(e||``)).filter(Boolean):[],pagesNote:String(t?.pagesNote||``),customNote:String(t?.customNote||``),customPath:String(t?.customPath||``),createdAt:typeof t?.createdAt==`number`?t.createdAt:void 0}},Wi=e=>/^price_[A-Za-z0-9]+$/.test(e.trim()),Gi=(e,t=ka())=>t?e.livePriceId:e.priceId;function Ki(e,t=ka()){if(!e.kind)return`Say how it is paid — once, or a subscription.`;if(e.kind===`once`){let t=Li(e);if(!t.length)return`Add something to sell — a name and a price.`;for(let e of t){let t=e.name.trim();if(Ri(e.amount)===null)return`Give ${t||`it`} a price — just a number, like 25.`;if(!t)return`Give it a name, the way a buyer should read it.`}return``}if(!e.plans.length)return`Add at least one plan.`;for(let n of e.plans){let e=n.name.trim()||`each plan`;if(!n.name.trim())return`Give each plan a name.`;if(!n.monthly.on&&!n.yearly.on)return`Turn on monthly or yearly for ${e}.`;for(let[r,i]of[[`monthly`,n.monthly],[`yearly`,n.yearly]])if(i.on){if(Ri(i.amount)===null)return`Give ${e} its ${r} price — just a number.`;if(!Wi(Gi(i,t)))return t?`Paste the live ${r} price id for ${e} — live mode is a fresh Stripe catalogue, so the price is made again there. Your test id is kept.`:`Paste the ${r} price id for ${e} — the steps above say where it comes from in Stripe.`}}return``}var qi=(e,t=ka())=>Ki(e,t)===``,Ji=e=>e.kind===`subscription`&&e.plans.length>0&&e.plans.every(e=>e.name.trim()!==``&&(e.monthly.on||e.yearly.on)&&(!e.monthly.on||Ri(e.monthly.amount)!==null)&&(!e.yearly.on||Ri(e.yearly.amount)!==null));function Yi(e){let t=e.name.trim();if(t)return t;let n=Li(e);return n.length===1&&n[0].name.trim()?n[0].name.trim():`this product`}function Xi(e){let t=e.name.trim();if(!e.kind)return t?`${t} — say how it is paid`:`A new product — say how it is paid`;if(e.kind===`once`){let n=Li(e);if(n.length<=1){let e=n[0],r=e?.name.trim()||t,i=e?.amount.trim();return`${r||`A new product`}${i?` — ${i}, paid once`:` — paid once`}`}return`${t||n.map(e=>e.name.trim()).filter(Boolean).slice(0,3).join(`, `)||`A new product`} — ${n.length} things, paid once`}let n=e.plans.length;return`${t||`A new subscription`} — a subscription${n?`, ${n} plan${n===1?``:`s`}`:``}`}function Zi(e,t,n=ka()){let r=e.name.trim(),i=`${t.name.trim()||`this plan`}${r?` — ${r}`:``}`,a=t.description.trim(),o=t.monthly.on&&t.yearly.on,s=t.monthly.on?t.monthly:t.yearly,c=t.monthly.on?`Monthly`:`Yearly`,l=[n?`In your Stripe dashboard, switch Test mode OFF — live mode is its own catalogue, so the plan is made once more there. Then open Product catalogue and click Add product.`:`In your Stripe dashboard, open Product catalogue and click Add product.`,`Name it "${i}"${a?` and paste your one-liner into the Description box: "${a}"`:``}.`,`On the same form, choose Recurring, type ${s.amount.trim()||`…`} as the amount, set the billing period to ${c}, and click Add product to save.`,o?`Click the product you just made, then click its ${c.toLowerCase()} price. The price id — it starts with price_ — sits in the top right corner: copy it and paste it into the ${c.toLowerCase()} box below.`:`Click the product you just made, then click the price inside it. The price id — it starts with price_ — sits in the top right corner: copy it and paste it into the box below.`];return o&&l.push(`Go back to the product. In its Pricing section click + to add a second price: Recurring, ${t.yearly.amount.trim()||`…`} as the amount, billing period Yearly — save it.`,`Click that yearly price, copy its id from the top right corner, and paste it into the yearly box below.`),l}var Qi=e=>e.includes(`'`)?`"${e}"`:`'${e}'`,$i=`Every payment goes through the app's own <PayButton> — never build a checkout, a card form or Stripe code of your own. The button's words, colour and place on the page are yours to design.`,ea=(e,t=ka())=>{let n=e.name.trim()||`this product`,r=e.description.trim();if(e.kind===`once`){let t=Li(e),r=e=>`<PayButton amount={${Ri(e.amount)??0}} productName=${Qi(e.name.trim())}>`;if(t.length<=1){let i=t[0]||{name:e.name,amount:e.amount};return[`It sells ${i.name.trim()||n} for ${i.amount.trim()}, paid once: ${r(i)}.`]}let i=e.name.trim();return[`It sells ${t.length} things${i?` under ${i}`:``}, each paid once with its own button:`,...t.map(e=>`${e.name.trim()||`Something`} for ${e.amount.trim()}: ${r(e)}.`)]}let i=[`It sells ${n}${r?` (${r})`:``} as a subscription. Lay its plans out as one pricing section — each plan is bought with its own button, and where a plan has monthly and yearly, offer a monthly/yearly switch:`];for(let n of e.plans){let e=n.name.trim()||`Plan`,r=n.description.trim(),a=[];n.monthly.on&&a.push(`${n.monthly.amount.trim()} per month: <PayButton priceId='${Gi(n.monthly,t).trim()}' mode='subscription'>`),n.yearly.on&&a.push(`${n.yearly.amount.trim()} per year: <PayButton priceId='${Gi(n.yearly,t).trim()}' mode='subscription'>`),i.push(`${e}${r?` (${r})`:``} — ${a.join(`; `)}.`)}return i},ta=`If my words ask the buyer for anything before paying — a phone number, a note, what they need — ask it with a form made the app's way: a *Form.config.ts whose fields are properly typed (tel for a phone number, email, date), shown with <ContactPopup formId='…' isInline onSubmitted={…} /> — never inputs you build by hand. onSubmitted hands you the answers as strings: put each one into the button's metadata as a plain string, and they read beside the order on my Payments screen. If my words ask for nothing, put no form in front of the button. Never ask for their email (Stripe collects it at checkout) and never build a backend of your own for this.`,na=`Show and hide what a plan unlocks with the app's own useMyPayments() — it returns { loading, active, subscriptions, payments } — and that is presentation, not protection: anything genuinely paid, like a file or a secret, must come from the server.`;function ra(e,t=``,n=ka()){let r=[...ea(e,n)],i=e.how.trim();i&&r.push(`Here is how this payment should work, start to finish: ${i}`),r.push(ta),e.kind===`subscription`&&r.push(na),r.push(`Set each button's successPath to ${t||`the page the button is on`} so the buyer lands back where they paid and finds what my words say happens after.`);let a=[];return e.emailReceipt&&a.push(`emailReceipt: 'yes'`),e.notifyOwner&&a.push(`notifyOwner: 'yes'`),a.length&&r.push(`Put ${a.join(` and `)} in the button's metadata — the app then sends ${a.length===2?`those emails`:`that email`} on its own.`),r}var ia=e=>e===`internal`||e===`admin`,aa=()=>({name:``,address:``,type:`internal`,iconName:``,template:`none`,form:``,formFields:``,formButton:``,formSpot:``,about:``,formWish:``,images:[],imageNotes:``,booking:{schedules:[],party:`each`,ask:``,how:``}}),oa=e=>Array.isArray(e?.links)?e.links.map(e=>{let n={pageId:String(e?.pageId||``),how:String(e?.how||``)};if(e?.draft&&typeof e.draft==`object`){let r=e.draft,i=aa();n.draft={name:String(r.name??i.name),address:String(r.address??i.address),type:String(r.type||i.type),iconName:String(r.iconName??i.iconName),template:String(r.template||i.template),form:String(r.form??i.form),formFields:String(r.formFields??i.formFields),formButton:String(r.formButton??i.formButton),formSpot:String(r.formSpot??i.formSpot),about:String(r.about??i.about),formWish:String(r.formWish??i.formWish),images:Array.isArray(r.images)?r.images.map(e=>({url:String(e?.url||``),where:String(e?.where||``)})).filter(e=>e.url):[],imageNotes:String(r.imageNotes??i.imageNotes),booking:{schedules:Array.isArray(r.booking?.schedules)?r.booking.schedules.map(String).filter(Boolean):[],party:t.Wn(r.booking),ask:String(r.booking?.ask||``),how:String(r.booking?.how||``)}}}return n}):[],sa=(e,t)=>t.find(t=>t.id===e)||t.find(t=>String(t.config?.contentKey||``).trim()===e),ca=(e,t)=>e===t.id||e===String(t.config?.contentKey||``).trim();function la(e){return e.how.trim()?``:`Describe how this payment will work.`}var ua=(e,t)=>t.filter(t=>e.pageIds.some(e=>ca(e,t))),da=(e,t)=>e.pageIds.some(e=>ca(e,t)),fa=(e,t)=>da(e,t)?e.pageIds.filter(e=>!ca(e,t)):[...e.pageIds,t.id],pa=(e,t)=>ua(e,t).length||e.pagesNote.trim()?``:`Tick the pages it goes on, or describe a page to add.`;function ma(e,t,n=ka()){if(!e.length)return`Describe what you sell first — the request is built from it.`;for(let t of e){let e=Xi(t).split(` — `)[0];if(!qi(t,n))return`Finish ${e} under What you sell.`;if(la(t))return`Say how ${e} works under How your payments work.`}for(let n of e){let e=Xi(n).split(` — `)[0];if(pa(n,t))return`Say where ${e} goes — tick its pages, or describe a page to add.`}return``}var ha={public:`anyone`,user:`signed-in users`,internal:`your team`,admin:`admins only`},ga=`Make everything match the rest of my app: style with the app's own theme styles so it looks right in light and dark. Do not pick your own colors. Build from the app's own pieces — import { SectionHeading, Card, Button } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button. Do not add a dropdown, a filter, a picker or a switch I did not ask for. If something I asked for needs a dropdown, it is CustomSelect from the same import (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser's own <select>, which ignores my theme. Everything must be readable: an icon or word on a button takes the button's own text color — give it no color of its own, so there is never a dark icon on a colored button — and nothing anywhere is light on light or dark on dark. If the page opens with a hero, make it the full height of the first screen (min-h-screen on that one section — never a fixed height, never overflow hidden), add visual elements that give it wow factor, and end it where the next section begins: the rest of the page comes after it, never inside it. The design should be minimal, modern and clean.`,_a=`This page is a screen inside my app, not a page of my website: it opens for somebody already signed in, under the heading and the menu the app draws itself, inside the app's own panel. So no full-height hero, no marketing sections, and no page heading, menu, background or wrapper of your own — begin with the thing the page is for.`,va=`Anything I have not decided — what the buyer is asked first, what they see after paying, what a plan unlocks, the section titles, the words on the buttons, the layout — decide yourself and build it finished; do not stop to ask me.`,ya="Read the sales on it with the app's own useSales() from 'your-ai-workflow-firebase-os' — it returns { loading, charges, subscriptions, error } live from my Stripe account: who paid, for what, when, and each subscription's current status. Show `error` when it is set. Design the list however fits; never write Stripe code, a backend or an export of your own for it. This page never sells — no <PayButton> on it.",ba=[`A new page is made the app's way and no other: a page for anyone is one file src/your-ai-workflow-firebase-os/configs/somethingPage.config.ts exporting somethingPageConfig with route (its one web address, starting with /), pageName, pageTitle and form ('' for none); a page for signed-in users, my team or admins only is src/your-ai-workflow-firebase-os/configs/somethingTab.config.ts exporting somethingTabConfig with tabName, iconName, route, pageType ('user', 'internal' or 'admin'), tabTitle, template 'none' and form ''. Each page then gets ONE content file src/your-ai-workflow-firebase-os/microcomponents/SomethingContent.tsx with a default export, and its two lines in src/your-ai-workflow-firebase-os/microcomponents/registry.ts (import SomethingContent from './SomethingContent'; registerMicrocomponent('something', SomethingContent);). One page, one address, one config — never a second config for the same page, never a page written to Firestore, never a route or router of your own, never an edit to src/App.tsx or src/main.tsx.`,`A form — when my words ask for one — is one file src/your-ai-workflow-firebase-os/configs/somethingForm.config.ts exporting somethingFormConfig with systemName 'something' (the file name without Form, all lowercase), formType 'public' for anyone or 'private' for signed-in people, title, buttonName, submitText and typed fields (text, email, tel, textarea, number, date, select with options, checkbox, currency, file), shown with <ContactPopup formId='something' /> — isInline to build it into the page. Never build a form out of your own inputs; its entries would never reach my Inbox.`,`Pages connect with <Link to='/address'> from react-router-dom, or a Button that navigates there — never a router, a route or a web address of your own. A page for my team or admins never reads a pub_ or user_ page's data by hand, and a page for anyone never names a mem_, admin_ or user_ collection.`,`Every one of these pages appears on my Pages screen on its own, where I can rename it, move it, hide it or delete it — nothing to register anywhere else.`];function xa(e){let t=e.audience||`public`,n=ia(t),r=ha[t]||`anyone`,i=[`For the page at ${e.path}${e.title?` (${e.title})`:``}, which is for ${r}:`];if(e.id===`home`)i.push(`It is my home page and it is one file: src/your-ai-workflow-firebase-os/Home.tsx — change that one file. Keep its named export exactly as it is: export function Home. Never create a HomeContent.tsx, and do not create a page, a web address or a settings file for it.`);else if(e.id===`dashboard`)i.push(`It is my dashboard — the screen a signed-in person lands on — and its content is one file: src/your-ai-workflow-firebase-os/microcomponents/DashboardContent.tsx, with a default export. If it does not exist yet, write it and add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import DashboardContent from './DashboardContent'; and registerMicrocomponent('dashboard', DashboardContent); — never remove another page's lines from that file. It draws inside the dashboard's own panel, under the welcome heading and the menu, so write no page heading, menu or page wrapper of your own.`);else if(e.id===`contact`||e.id===`support`){let t=e.id===`contact`?`Contact`:`Support`;i.push(`It ships with my app and has its own form — do not create a page or a form for it, and do not change the questions its form asks. Its content is one file: src/your-ai-workflow-firebase-os/microcomponents/${t}Content.tsx, with a default export. If it does not exist yet, write it and add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import ${t}Content from './${t}Content'; and registerMicrocomponent('${e.id}', ${t}Content); — never remove another page's lines from that file. Keep showing its form with <ContactPopup formId='${e.id}' />.`)}else{let n=e.config||{},r=Ai(String(n.contentKey||n.tabName||n.pageName||n.pageId||e.title||``))||`Page`,a=r.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();i.push(`It already exists and is already in the menu — do not create a page, a web address or a settings file for it. Its content is one file: src/your-ai-workflow-firebase-os/microcomponents/${r}Content.tsx, with a default export. If that file does not exist yet, write it and add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import ${r}Content from './${r}Content'; and registerMicrocomponent('${a}', ${r}Content); — never remove another page's lines from that file. If it already exists, change it in place and keep everything on it my words do not mention.`),t!==`public`&&i.push(_a);let o=String(n.form||``).trim();o&&o!==`__new__`&&i.push(`The page already has a form, '${o}' — show it with <ContactPopup formId='${o}' /> and never remake it; add a question to it where it is defined if the payment needs one.`)}let a=String(e.brief??e.config?.brief??``).trim();return a&&i.push(`The page is for: ${a}`),n&&i.push(ya),i}var Sa=e=>`${e.path}${e.title?` (${e.title})`:``}`;function Ca(e,t,n=ka()){let r=[`Build ${e.length===1?`my payment`:`my payments`} into my app. ${$i}`],i=[],a=!1;for(let o of e){let e=ua(o,t);for(let t of e)i.includes(t)||i.push(t);let s=e.filter(e=>!ia(e.audience)),c=s.length===1?s[0].path:``;r.push(...ra(o,c,n));let l=Yi(o);e.length&&r.push(`${l} goes on ${e.length===1?`this page`:`these pages`} of mine: ${e.map(Sa).join(`, `)}.`);let u=o.pagesNote.trim();u&&(a=!0,r.push(`Here is where ${l} goes and what should appear for it, in my words: ${u}`))}if(i.length){r.push(`Here are the pages of mine this touches — every one of them already exists:`);for(let e of i)r.push(...xa(e))}return a?r.push(`If my words name a page that does not exist yet, add it. ${ba[0]}`,...ba.slice(1)):r.push(`If the payments need a page my words do not name, make it the app's way. ${ba[0]}`),r.push(ga,va),r.push(`Build all of it in one turn. Do not touch any page this request does not name, and never write Stripe, checkout, billing or email code of your own — the app has all of it.`),r.join(`
|
|
19
|
-
`)}var wa=[],Ta=!1,Ea=e=>{wa=e},Da=()=>wa,Oa=e=>{Ta=e},ka=()=>Ta;function Aa(e){let t=[];for(let n of e)if(n.kind===`subscription`)for(let e of n.plans)for(let[r,i]of[[`monthly`,e.monthly],[`yearly`,e.yearly]]){if(!i.on)continue;let a=i.priceId.trim(),o=i.livePriceId.trim();Wi(o)&&Wi(a)&&a!==o&&t.push({product:n.name.trim()||`a subscription`,plan:e.name.trim()||`its plan`,word:r,from:a,to:o})}return t}function ja(e=Da()){let t=Aa(e),n=[`My Stripe account has switched from test mode to live mode. I have already replaced the keys in Secrets — do not touch any keys or write any Stripe code of your own.`];return t.length?n.push(`In my pages, every <PayButton> with a priceId still carries a test price id. Swap each one for its live id and change nothing else about the button:`,...t.map(e=>`For ${e.product}, ${e.plan} (${e.word}): replace '${e.from}' with '${e.to}'.`),`Buttons that use amount={…} instead of a priceId need no change.`):n.push(`No price id in my pages needs to change — buttons that use amount={…} never had one.`),n.push(`Then rebuild the app so it runs with the live keys and ids.`),n.join(`
|
|
20
|
-
`)}var Ma=[{id:`home`,title:`Home`,path:`/`,audience:`public`},{id:`contact`,title:`Contact`,path:`/contact`,audience:`public`},{id:`dashboard`,title:`Dashboard`,path:`/dashboard`,audience:`user`},{id:`support`,title:`Support`,path:`/support`,audience:`user`}],Na=new Set([`home`,`drive`,`assets`,`contact`,`guide`,`templates`,`setup`,`support`,`theme`,`page_order`,`tab_order`]),Pa={public:0,user:1,internal:2,admin:3},Fa=(e,t)=>{let n=String(e||``).trim();return n?n.startsWith(`/`)?n:`/${n}`:`/${t}`},Ia=e=>new Set((Array.isArray(e?.order)?e.order:[]).filter(e=>e&&typeof e==`object`&&e.removed).map(e=>String(e.id)));function La(e,n,r,i,a=b()){let o=[...Ma];for(let{id:t,data:n}of e)Na.has(t)||o.push({id:t,title:String(n?.pageName||n?.title||t),path:Fa(n?.route,t),brief:String(n?.brief||``),config:n,audience:`public`});for(let{id:e,data:r}of n)Na.has(e)||o.push({id:e,title:String(r?.tabName||r?.title||e),path:Fa(r?.route,e),brief:String(r?.brief||``),config:r,audience:t._a(r?.pageType)});for(let[e,n]of a){if(Na.has(e)||o.some(t=>t.id===e))continue;let a=!!n.isPublic;if((a?r:i).has(e))continue;let s=n.config||{},c=Fa(s.route,e);o.some(e=>e.path===c)||o.push({id:e,title:String(a?s.pageName||s.pageTitle||s.title||e:s.tabName||s.tabTitle||s.title||e),path:c,brief:String(s.brief||``),config:s,audience:a?`public`:t._a(s.pageType)})}return o.sort((e,t)=>(Pa[e.audience||`public`]??9)-(Pa[t.audience||`public`]??9)||e.title.localeCompare(t.title))}function Ra(){let[e,n]=(0,r.useState)(null),[i,a]=(0,r.useState)(null),[s,c]=(0,r.useState)(new Set),[l,u]=(0,r.useState)(new Set);return(0,r.useEffect)(()=>{let e=e=>{let t=[];return e.forEach(e=>t.push({id:e.id,data:e.data()})),t},r=[(0,o.onSnapshot)((0,o.collection)(t.Da,`sys_pages`),t=>n(e(t)),()=>n([])),(0,o.onSnapshot)((0,o.collection)(t.Da,`sys_tabs`),t=>a(e(t)),()=>a([])),(0,o.onSnapshot)((0,o.doc)(t.Da,`sys_configs`,`page_order`),e=>c(Ia(e.exists()?e.data():null)),()=>{}),(0,o.onSnapshot)((0,o.doc)(t.Da,`sys_configs`,`tab_order`),e=>u(Ia(e.exists()?e.data():null)),()=>{})];return()=>r.forEach(e=>e())},[]),e===null||i===null?null:La(e,i,s,l)}var za=new Set(`login.register.reset-password.verify.payment-complete.payment-cancelled.guide.templates.board.table.calendar.drive.inline_form.popup_form.users.inbox.payments.schedule.my-calendar.my-bookings.email.submissions.requests.assets.theme.pages.forms.settings.profile.billing.dashboard.setup.publish`.split(`.`)),Ba=e=>za.has(String(e||``).replace(/^\/+/,``).split(`/`)[0].toLowerCase()),Va=e=>{let t=String(e||``).replace(/^\/+/,``);return Ba(t)?`The app already uses /${t} for a screen of its own.`:`Another page already lives at /${t}.`},Ha=`fbos_records_`,Ua=(e,t)=>`${Ha}${t||`guest`}_${e}`;function Wa(e,t){try{let n=localStorage.getItem(Ua(e,t));return n?JSON.parse(n):null}catch{return null}}function Ga(e,t,n){try{localStorage.setItem(Ua(e,t),JSON.stringify(n))}catch{}}function Ka(e){try{let t=`_${e}`,n=[];for(let e=0;e<localStorage.length;e++){let r=localStorage.key(e)||``;r.startsWith(Ha)&&r.endsWith(t)&&n.push(r)}n.forEach(e=>localStorage.removeItem(e))}catch{}}var qa=`Could not reach the server. Check your connection and try again.`;async function Ja(e,n,r=!1){try{let i=r?await t.Ea?.currentUser?.getIdToken().catch(()=>null):null,a=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,...i?{Authorization:`Bearer ${i}`}:{}},body:JSON.stringify(n)}),o=await a.json().catch(()=>({}));return!a.ok||o?.success===!1?typeof o?.error==`string`&&o.error||`The email could not be sent.`:null}catch{return qa}}function Ya(e,t={}){return Ja(`/api/email/notify`,{template:e,data:t})}function Xa(e,t,n,r={}){return Ja(`/api/email/send`,{template:e,collection:t,docId:n,data:r},!0)}function Za(e,t,n,r={}){return Ja(`/api/email/compose`,{to:e,subject:t,message:n,...r},!0)}async function Qa(){try{let e=await(await fetch(`/api/email/status`)).json();return{configured:e?.configured===!0&&e?.enabled!==!1,from:e?.from??null,error:null}}catch{return{configured:!1,from:null,error:qa}}}var $a=`sys_bookingpages`,eo=(e,t=``,n=``)=>({id:e,title:t,intro:``,photo:``,schedules:[],enabled:!0,memberId:n,createdAt:Date.now()}),to=e=>e.normalize(`NFKD`).replace(/[\u0300-\u036f]/g,``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,48);function no(e,t){let n=to(e)||`page`;if(!t.includes(n))return n;for(let e=2;;e++){let r=`${n}-${e}`;if(!t.includes(r))return r}}var ro=e=>`/meet/${e}`;function io(e,t){let n=t&&typeof t==`object`?t:{};return{id:e,title:String(n.title||``),intro:String(n.intro||``),photo:String(n.photo||``),schedules:Array.isArray(n.schedules)?n.schedules.filter(e=>typeof e==`string`||typeof e==`number`).map(String).filter(Boolean):[],enabled:n.enabled!==!1,memberId:String(n.memberId||``),createdAt:Number(n.createdAt)||0}}var ao=(e,t,n)=>n?e:e.filter(e=>!!t&&e.memberId===t),oo=(e,t)=>e.schedules.map(e=>t.find(t=>t.id===e)).filter(e=>!!e),so=(e,n)=>oo(e,n).filter(t.Wt),co=(e,t)=>({...e,schedules:e.schedules.includes(t)?e.schedules.filter(e=>e!==t):[...e.schedules,t]});function lo(e,n){if(!e.title.trim())return`Give the page a name — usually the name of whoever it is for.`;if(!e.schedules.length)return`Tick at least one meeting to offer on this page.`;if(!so(e,n).length){let r=oo(e,n);return r.length?`${t.Mn(r[0])} is not taking bookings — switch it on above, or tick a different meeting.`:`The meetings picked for this page no longer exist — tick one that does.`}return``}var uo=e=>e.title.trim()||`Booking page`;function fo(){let[e,n]=(0,r.useState)({loading:!0,pages:[]});return(0,r.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(t.Da,$a),e=>{let t=[];e.forEach(e=>t.push(io(e.id,e.data()))),t.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)||e.id.localeCompare(t.id)),n({loading:!1,pages:t})},()=>n({loading:!1,pages:[]}));return()=>e()},[]),e}async function po(e){try{let{id:n,...r}=e;return await(0,o.setDoc)((0,o.doc)(t.Da,$a,n),{...r,updatedAt:Date.now()}),null}catch(e){return console.error(`Could not save the booking page`,e),`The page could not be saved — it is saved by whoever it belongs to, so make sure you are signed in as them or as an admin, and try again.`}}async function mo(e){try{return await(0,o.deleteDoc)((0,o.doc)(t.Da,$a,e)),null}catch(e){return console.error(`Could not remove the booking page`,e),`It could not be removed — a page is removed by whoever it belongs to, or by an admin.`}}async function ho(e,n){if(e===n.id)return po(n);let r=await po(n);if(r)return r;try{await(0,o.deleteDoc)((0,o.doc)(t.Da,$a,e))}catch(e){return console.error(`Could not remove the old booking page`,e),`The page moved, but its old address is still live — remove it and try again.`}return null}var go=(e,n)=>[...e.map(e=>({path:t.Qt(e.id),id:e.id,kind:`link`,title:t.In(e)})),...n.map(e=>({path:ro(e.id),id:e.id,kind:`page`,title:uo(e)}))],_o=[],vo=e=>{_o=e},yo=()=>_o,bo=e=>(Array.isArray(e?.bookingLinks)?e.bookingLinks:[]).filter(e=>typeof e==`string`).map(e=>e.trim()).filter(Boolean),xo=e=>String(e?.bookingLinksNote||``).trim(),So=(e,t)=>e.includes(t)?e.filter(e=>e!==t):[...e,t],Co=(e,t=yo())=>bo(e).map(e=>t.find(t=>t.path===e)).filter(e=>!!e),wo=`Never build a calendar, a time picker, a list of free times, a booking form or a schedule question because of one of those links, and never make a bookings collection of your own — the page each one opens already does all of that, inside my app. What the link says and where it sits on the page are yours to decide from my words. If my words ask for it to open in a pop-up, a panel or a window of its own rather than as a page, show that same address inside an overlay on this page — an <iframe> of it filling a dialog, with a close button — and still build no part of the booking yourself.`;function To(e,t=yo(),n){let r=Co(e,t).filter(e=>!n||n.includes(e.path));if(!r.length)return[];let i=r.map(e=>e.kind===`link`?`Put a link on this page to ${e.title} — my app's own booking page for that meeting, at ${e.path}. Link to that exact address with bookingPath('${e.id}') from 'your-ai-workflow-firebase-os'; it opens the booking page my app already has and the visitor books there.`:`Put a link on this page to ${e.title} — the booking page I made on my Schedule screen, at ${e.path}, which offers every meeting on it. Link to that exact address with meetPath('${e.id}') from 'your-ai-workflow-firebase-os'; it opens the page my app already has and the visitor books there.`);i.push(wo);let a=xo(e);return a&&i.push(`Here is where those links should sit on this page and how they should open: ${a}`),i}var Eo=(e,t=yo())=>{let n=t.find(t=>t.path===e);return`This page no longer links to ${n?n.title:`the booking page`} at ${e} — take that link off the page, and leave the booking page itself as it is.`},Do=e=>`${t.In(e)} · ${t.Bn(e.slotMinutes)}`,Oo=e=>{let n=t.in(e);return n?`${t.pn(e)} · ${n}`:t.pn(e)};function ko({schedules:e,selected:n,onPick:a,placeholder:o=`Pick a schedule`,mode:s=`meetings`}){let[l,u]=(0,r.useState)(!1),d=s===`hours`,f=e=>d?t.pn(e):t.In(e),p=e=>d?Oo(e):Do(e),m=e=>d?t.gn(e):t.Wt(e),h=e=>d?t.hn(e)?`Unfinished on the Schedule screen`:``:e.enabled?t.Nn(e)?`Unfinished on the Schedule screen`:``:`Turned off on the Schedule screen`;if(e.length===0)return(0,i.jsxs)(`p`,{className:t.$,children:[d?`No hours yet`:`No schedule yet`,` — add `,d?`a week`:`one`,` on the`,` `,(0,i.jsx)(c.Link,{to:`/schedule`,className:`text-accent font-bold hover:underline`,children:`Schedule screen`}),` first.`]});let g=n.map(t=>e.find(e=>e.id===t)).filter(e=>!!e);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsxs)(`div`,{className:`w-full min-h-11 flex items-center gap-2 px-3 py-1.5 rounded-[var(--input-radius,0.75rem)] border bg-[var(--panel-bg)] transition-all duration-300 console-field ${l?`border-accent`:`border-[var(--panel-border)] hover:border-accent/40`}`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-wrap items-center gap-1.5`,children:[g.length===0&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>u(e=>!e),className:`text-[14px] text-foreground/35 text-left cursor-pointer`,children:o}),g.map(e=>(0,i.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 h-7 pl-2.5 pr-1.5 rounded-lg bg-accent/10 border border-accent/20 text-[12.5px] font-semibold text-foreground max-w-full`,children:[(0,i.jsx)(`span`,{className:`truncate`,children:f(e)}),(0,i.jsx)(`button`,{type:`button`,"aria-label":`Remove ${f(e)}`,onClick:()=>a(e.id),className:`w-4 h-4 rounded-md flex items-center justify-center text-foreground/50 hover:text-red-500 hover:bg-red-500/10 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})})]},e.id))]}),(0,i.jsx)(`button`,{type:`button`,"aria-label":l?`Close the list of schedules`:`Open the list of schedules`,"aria-expanded":l,onClick:()=>u(e=>!e),className:`w-8 h-8 shrink-0 rounded-lg flex items-center justify-center text-foreground/40 hover:text-foreground hover:bg-foreground/[0.05] transition-colors cursor-pointer`,children:(0,i.jsx)(t.Ri,{className:`w-4 h-4 transition-transform ${l?`rotate-180`:``}`})})]}),l&&(0,i.jsx)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60 px-2 py-1.5`,role:`listbox`,"aria-label":`Schedules`,"aria-multiselectable":!0,children:e.map(e=>{let r=n.includes(e.id),o=h(e);return(0,i.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":r,"aria-label":f(e),onClick:()=>a(e.id),className:`w-full flex items-center gap-2.5 px-2 py-2 text-left cursor-pointer rounded-xl hover:bg-foreground/[0.04] transition-colors ${m(e)?``:`opacity-70`}`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${r?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:r&&(0,i.jsx)(t.zi,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate min-w-0`,children:p(e)}),o&&(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 whitespace-nowrap shrink-0 max-sm:hidden`,children:o})]},e.id)})}),(0,i.jsx)(`span`,{className:t.$,children:d?`One person’s hours each — picking a second week of theirs replaces the first.`:`One schedule per person — picking a second one of theirs replaces the first.`})]})}var Ao=!1,jo=e=>{Ao=e},Mo=()=>Ao,No=!1,Po=e=>{No=e},Fo=()=>No,Io=[{id:`home`,title:`Home`,path:`/`,type:`public`,isSystem:!0,enabled:!0},{id:`contact`,title:`Contact`,path:`/contact`,type:`public`,isSystem:!0,enabled:!0},{id:`guide`,title:`Guide`,path:`/guide`,type:`public`,isSystem:!0,enabled:!0},{id:`templates`,title:`Templates`,path:`/templates`,type:`public`,isSystem:!0,enabled:!0},{id:`dashboard`,title:`Dashboard`,path:`/dashboard`,type:`user`,isSystem:!0,enabled:!0},{id:`support`,title:`Support`,path:`/support`,type:`user`,isSystem:!0,enabled:!0},{id:`profile`,title:`Profile`,path:`/profile`,type:`user`,isSystem:!0,enabled:!0},{id:`payments`,title:`Payments`,path:`/payments`,type:`admin`,isSystem:!0,enabled:!0},{id:`schedule`,title:`Schedule`,path:`/schedule`,type:`admin`,isSystem:!0,enabled:!0},{id:`email`,title:`Email`,path:`/email`,type:`admin`,isSystem:!0,enabled:!0},{id:`assets`,title:`Assets`,path:`/assets`,type:`admin`,isSystem:!0,enabled:!0}],Lo=new Set([`home`,`dashboard`,`profile`]),Ro=e=>[...e,...Io.filter(t=>!e.some(e=>e.id===t.id))],zo={public:`Anyone`,user:`Members`,internal:`Your team`,admin:`Admins only`},Bo={public:`Website Pages`,tabs:`Tabs`},Vo=[{value:`user`,label:`Members`},{value:`internal`,label:`Your team`},{value:`admin`,label:`Admins only`}],Ho=e=>{let n=t.wa(e),r=n.filter(t.ma);if(!r.length)return[];let i=r.map(e=>_t(e)).join(` or `),a=t.xa(e);return a?[`This page is only for the people I have marked ${i}: the app turns everybody else away at the address itself, so never write a guard, a redirect or a sign-in check of your own on it.`,`Whatever everybody marked ${i} SHARES on this page — one list they all read, add to and edit — goes in collections whose names begin role_${a}_: role_${a}_projects, role_${a}_notes, whatever it needs. My security rules open those to the people marked ${i}, to my admins, and to nobody else, and every one of them reads and writes the SAME records there.`,`Whatever belongs to ONE of them and the others must not see — their own documents, their own answers — stays in the ordinary user_ collections, where each person only ever reads the records that carry their own uid — the ones they added, and the ones my admins put there for them. Nothing anybody marked ${i} has to read may sit in a mem_, admin_ or pub_ collection: mem_ and admin_ answer them with a permission error, and pub_ is the open internet.`]:[`${n.includes(`user`)?`This page is for the people I have marked ${i} as well as everybody else who signs in.`:n.includes(`internal`)?`This page is for the people I have marked ${i} and for my team, and for nobody else who signs in.`:`This page is only for the people I have marked ${i}, and for nobody else who signs in.`} The app decides who may open it — never write a guard, a redirect or a sign-in check of your own on it.`,`Its data stays in the ordinary user_ collections, where each person only ever reads the records that carry their own uid — the ones they added, or ones my admins put there for them. So nothing on this page is shared between the people who can open it: two of them on the same page see two different lists. Never write a query that reads other people's records here — it is refused, not empty. If what I described needs ONE list they all share, say so and tell me the page has to be kept for a single role instead.`]},Uo=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),Wo=e=>{let t=e.map(e=>String(e.name||``).trim()).filter(Boolean).map(Uo);return[{key:`admin`,re:/\b(admins?|administrators?|only i|only me|just me|myself|nobody but me)\b/gi},{key:`team`,re:/\b(my team|the team|our team|team members?|teammates?|staff|colleagues?|internal(?: users?| members?| people| staff)?)\b/gi},...t.length?[{key:`role`,re:RegExp(`\\b(${t.join(`|`)})s?\\b`,`gi`)}]:[],{key:`named`,re:/\b(clients?|customers?|suppliers?|vendors?|partners?|patients?|students?|tenants?|contractors?|subscribers?)\b/gi},{key:`guest`,re:/\b(guests?|visitors?|the public|anyone not signed in)\b/gi},{key:`member`,re:/\b(members?|free users?|signed[- ]in (?:users?|people|visitors?))\b/gi}]},Go=(e,t=gt())=>{let n=` ${String(e||``)} `,r=[];for(let e of Wo(t)){let t=n;n=n.replace(e.re,` `),n!==t&&r.push(e.key)}return r},Ko=/\b(only|cannot|can not|can'?t|must not|should ?n[o’']?t|not allowed|no access|hidden from|kept from|never sees?|does ?n[o’']?t see|do not see|read[ -]only|view only)\b/i,qo=/[^.!?;\n]+/g,Jo=(e,t=gt())=>{let n=String(e||``);return n.trim()?Go(n,t).length>1?!0:(n.match(qo)||[]).some(e=>Go(e,t).length>0&&Ko.test(e)):!1},Yo=/\b(assign(?:ed|s|ing|ment|ments)?|allocated|responsible for|each of (?:my|our|the) (?:team|staff|people|users)|their own records?)\b/i,Xo=`Then show each person only the sections that are theirs: read const { userRole } = useAuth() from 'your-ai-workflow-firebase-os' — 'admin' is one of my admins, 'internal' is my team, a role of my own arrives as that role's own plain word, and anything else is an ordinary member. Leave a section OUT of the page for somebody it is not for rather than rendering it: a section that reads a collection that person may not read answers with a permission error, and a permission error is never an empty list — never draw it as “nothing here yet”.`,Zo=`Only the groups my words actually name, and only INSIDE the page: never invent a group or a role word of your own, never add a check for anybody I did not mention, and never guard the page itself, redirect anyone or test whether they are signed in — who may open this page is my app’s decision and it is already made.`,Qo=`Anything one group must not see is its OWN document in one of those collections, never a field sitting beside what they do see: whoever may read a document reads every field of it. And where my words say a group may look at something without changing it, or may remove a record without editing it, build them exactly those buttons and leave the others out of their view.`,$o=[`Where my words say each of my team sees only what is assigned to them, those records go in a user_ collection with the assignee’s own uid on every document — my rules then show each of them their own and nobody else’s, and a colleague cannot so much as list them. Read them back with a query on that uid, never by fetching the collection and filtering afterwards.`,`Handing a record to somebody else is an ADMIN’s doing: only an admin may write a document carrying another person’s uid, so put the assigning where an admin does it, and never build a team member a button that assigns a record to a colleague — it answers with a permission error.`],es=(e,n,r=String(n?.brief||``),i=!1)=>{if(!Us(e,n))return[];let a=t._a(n?.pageType);if(a===`admin`)return[];let o=gt();if(!i&&!Jo(r,o))return[];let s=a===`internal`,c=s?``:t.xa(n),l=c?_t(c,o):``,u=[`What I say about this page gives different people different things to see on it. Build that by WHERE each thing is kept, before anything else: ${c?`what everybody marked ${l} shares in role_${c}_ collections and what belongs to one of them in user_ collections, as above, and — the third space — what only my admins may ever see, in admin_ collections`:`${s?`what my whole team works on stays in mem_ collections, `:``}what only my admins may ever see goes in admin_ collections, and what belongs to ONE person alone goes in user_ collections with that person’s own uid on every document`}. My security rules hold those apart by themselves, so a thing kept in the right place is really kept from everybody else — a section merely hidden in the code is not kept from anybody, because the database is still open to them.`,`My admins read every document in all of those collections, so where my words give my admins the whole list it is the same query with nobody’s uid on it — never a second copy of the records kept somewhere else.`];return!s&&!c&&!t.wa(n).some(t.ma)&&u.push(`There is no space on this page that every member shares: a list they could all read would have to be a pub_ one, open to the whole internet. So keep to per-person records unless my words ask for something I would not mind a stranger reading.`),!s&&t.wa(n).includes(`internal`)&&u.push(`My team can open this page too, but on it they are like everybody else who signs in: each of them reads only the records that carry their own uid, never anybody else’s — only my admins read everybody’s. Where my words give my team other people’s records, build that for my admins alone and tell me my team cannot have it on this page.`),u.push(Xo,Zo,Qo),s&&Yo.test(r)&&u.push(...$o),c&&Go(r,o).includes(`team`)&&u.push(`One thing this page cannot do: the people I have marked internal do not read role_${c}_ collections at all — only the people marked ${l} and my admins do. So anything my TEAM has to see belongs on a team page of its own rather than here, and on this page “my team” means my admins.`),u},ts=e=>{if(!e?.pageType)return[];let n=e=>e===`user`?0:e===`internal`?1:e===`admin`?3:2,r=[...new Set([...t.la(e),`admin`])].sort((e,t)=>n(e)-n(t));return r.length>1?r:[]},ns=(e,t)=>e===`user`?`Members`:e===`internal`?`Your team`:e===`admin`?`You and your admins`:_t(e,t),rs={user:`See and change only what they added themselves.`,internal:`See every job and move it along, but never delete one.`,admin:`Everything — and only we see what each job was charged.`,role:`See their own projects and the shared price list, and add notes — never delete anything.`},is=e=>{let t=e?.canDo&&typeof e.canDo==`object`?e.canDo:{},n={};for(let r of[...ts(e)].sort()){let e=String(t[r]??``).trim();e&&(n[r]=e)}return n},as=e=>e===`user`?`Members (everybody who signs in)`:e===`internal`?`My team`:e===`admin`?`Me and my admins`:`The people I have marked ${_t(e)}`,os=`What each of them may do on this page, in my own words — build each group exactly the sections, and the add, change and delete buttons, its line gives it. A group I say nothing about here is yours to decide:`,ss=`What each of them may do on this page has changed. This is the whole of it now, in place of what I said before — build each group exactly the sections, and the add, change and delete buttons, its line gives it:`,cs=(e,t=os)=>{let n=is(e),r=ts(e).filter(e=>n[e]);return r.length?[t,...r.map(e=>`${as(e)}: ${n[e]}`)]:[]},ls=(e,n=[])=>{let r=`Optional — for each, what they see here and what they can add, change or delete. Whatever you skip, your assistant decides.`;if(t._a(e?.pageType)!==`user`)return r;let i=t.xa(e);if(i)return`Only the people you have marked ${_t(i,n)} and your admins can open this page — mark them on your Users screen. ${r}`;let a=t.wa(e),o=a.filter(t.ma);return o.length?`${o.map(e=>_t(e,n)).join(` and `)} ${o.length>1?`are`:`is`} ticked alongside another audience, so this page cannot hold a list they all share — everybody who opens it keeps only what they added themselves. For one shared list, tick a single role and nothing else. ${r}`:a.includes(`internal`)?`Your team opens this page too, but here each of them keeps only their own records, like any member — only you and your admins see everybody's. For one list your whole team shares, tick Your team alone. ${r}`:r},us=e=>e.draft?`draft`:e.hidden?`hidden`:`live`,ds={draft:`Draft`,live:`Live`,hidden:`Hidden`},fs={draft:`Nothing is saved yet. Give it a name and the page is created.`,live:`This page is live at its web address and listed in the menu.`,hidden:`This page still exists at its web address, but it is out of the menu.`},ps=e=>(e||``).trim().toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9_-]/g,``),ms=e=>String(e||``).replace(/^\/+/,``).replace(/[^a-zA-Z0-9_-]/g,`_`).toLowerCase();function hs(e){let n=ps(e.address);if(!n)throw Error(`A page needs a web address.`);let r=ms(`/`+n),i=e.type===`public`,a={form:e.form||``,formFields:e.formFields||``,formButton:e.formButton||``,formSpot:e.formSpot||``,formWish:e.formWish||``};e.images?.length&&(a.images=e.images.filter(e=>e.url).map(e=>({url:e.url,where:e.where||``})),a.imageNotes=e.imageNotes||``),e.booking?.schedules?.length&&(a.booking={schedules:e.booking.schedules,party:t.Wn(e.booking),ask:e.booking.ask||``,how:e.booking.how||``});let o=i?{route:`/`+n,pageName:e.name,pageTitle:e.name,...a,brief:e.about,contentKey:r}:{route:`/`+n,tabName:e.name,tabTitle:e.name,iconName:e.iconName||``,template:Cs.some(t=>t.value===e.template)?e.template:`none`,...a,brief:e.about,pageType:e.type,contentKey:r};return o.form===`__new__`&&(o.form=zc(o),o.formIsNew=!0),{id:r,config:o,isPublic:i}}async function gs(e){let{id:n,config:r,isPublic:i}=hs(e);await(0,o.setDoc)((0,o.doc)(t.Da,i?`sys_pages`:`sys_tabs`,n),r);let a=i?`page_order`:`tab_order`,s=await(0,o.getDoc)((0,o.doc)(t.Da,`sys_configs`,a)),c=(s.exists()?s.data()?.order:null)||[];return c.some(e=>(typeof e==`string`?e:String(e?.id))===n)||await(0,o.setDoc)((0,o.doc)(t.Da,`sys_configs`,a),{order:[...c,{id:n,hidden:!1}]}),n}var _s=(e,t,n,r)=>{let i=e.findIndex(e=>e.id===t);if(i===-1)return null;let a=r&&e[0]?.id===r?1:0,o=n===`up`?Math.max(a,i-1):Math.min(e.length-1,i+1);if(o===i||o<a)return null;let s=[...e],[c]=s.splice(i,1);return s.splice(o,0,c),s},vs=()=>Object.fromEntries(b()),ys=(e,n=!1)=>{let r={};for(let[i,a]of Object.entries(vs())){let o=!!a.isPublic;if(o!==e)continue;let s=a.config||{};!n&&s.enabled===!1||(r[i]={id:i,title:o?s.pageName||s.pageTitle||s.title||i:s.tabName||s.tabTitle||s.title||i,path:s.route?s.route.startsWith(`/`)?s.route:`/`+s.route:`/`+i,type:o?`public`:t._a(s.pageType),isSystem:!1,enabled:s.enabled!==!1,fromFile:!0})}return r};function bs({roles:e,picked:n,onChange:a,onCreateRole:o,busy:s}){let[c,l]=(0,r.useState)(!1),[u,d]=(0,r.useState)(``),[f,p]=(0,r.useState)(``),[m,h]=(0,r.useState)(!1),g=[...Vo,...e.map(e=>({value:e.id,label:e.name}))],_=e=>{let t=n.includes(e)?n.filter(t=>t!==e):[...n,e];t.length&&a(t)},v=async()=>{let r=vt(u,e);if(r){p(r);return}h(!0);try{let e=await o(u.trim());a([...n.filter(t.ma),e.id]),d(``),l(!1),p(``)}catch(e){p(e?.message||`The role could not be saved. Try again.`)}h(!1)};return(0,i.jsx)(`div`,{className:`shrink-0 min-w-0 max-w-[14rem]`,onClick:e=>e.stopPropagation(),children:(0,i.jsx)(t.sr,{multiple:!0,compact:!0,portal:!0,direction:`auto`,className:`console-select`,ariaLabel:`Who can open this page`,values:n,options:g,onChange:_,footer:(0,i.jsx)(`div`,{className:`mt-1 pt-1 border-t border-[var(--panel-border)]/60`,children:c?(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 p-2`,children:[(0,i.jsx)(`input`,{autoFocus:!0,value:u,disabled:m,placeholder:`Client`,"aria-label":`Name the role`,onChange:e=>{d(e.target.value),f&&p(``)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),v()),e.key===`Escape`&&(e.preventDefault(),l(!1),p(``))},className:t.et}),f&&(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:f}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(t.Q,{onClick:v,disabled:m,children:m?`Adding…`:`Add role`}),(0,i.jsx)(t.Q,{onClick:()=>{l(!1),p(``)},children:`Cancel`})]})]}):(0,i.jsxs)(`div`,{role:`option`,"aria-selected":!1,onClick:()=>l(!0),className:`flex items-center gap-2 px-3 py-2.5 text-[13px] font-semibold text-accent hover:bg-foreground/5 cursor-pointer`,style:{borderRadius:`calc(var(--input-radius, 0.75rem) - 0.25rem)`},children:[(0,i.jsx)(t.Ur,{className:`w-3.5 h-3.5 shrink-0`}),`Custom role…`]})}),disabled:s,placeholder:`Pick who`})})}var xs=`Add it here — a name and what you would like to see on it — then copy the sentence for your assistant.`,Ss=`Add it here, then copy the sentence for your assistant.`,Cs=[{value:`none`,label:`From scratch`},{value:`board`,label:`Board`},{value:`table`,label:`Table`},{value:`calendar`,label:`Calendar`},{value:`drive`,label:`Files`}],ws=[`board`,`table`,`calendar`,`drive`],Ts={board:{is:`a board`,keeps:`its board frame and the card editor that is already in it`,open:`actions.openInlineEditor(columnId)`},table:{is:`a table`,keeps:`its table frame and the row and column controls that are already in it`,open:`actions.addRow()`},calendar:{is:`a calendar`,keeps:`its calendar frame — the month heading, Today, and the arrows — and the add-event form that is already in it`,open:`actions.openAddModal()`},drive:{is:`a file library`,keeps:`its file frame and the upload box that is already in it`,open:`openUploadModal()`}},Es=e=>{let t=Ts[e];return t?`This page already works as ${t.is} and it stays one: it keeps ${t.keeps}, already styled to match my app. Design only what fills it, and open the one that is already there with ${t.open}. Never build your own add, edit or upload form on this page — one exists, and yours will not match.`:``},Ds=e=>Ye(e,1)[0]||``,Os=(e,t)=>t?.contentKey||t?.tabName||t?.pageName||t?.pageId||e.title,ks=(e,t)=>`src/your-ai-workflow-firebase-os/microcomponents/${Ai(Os(e,t))||`Page`}Content.tsx`,As=(e,t)=>{let n=String(t?.route||``).trim();return n?n.startsWith(`/`)?n:`/`+n:e.path||``},js=(e,n,r=[])=>As(e,n).replace(/^\/+/,``)?String(n?.brief||``).trim()?Bc(n)?`Say what the forms should ask for, and this sentence is ready to copy.`:Kc(n)||ol(n,r)||t.Jt(n,t.bn(),t.yn()):`Say what you would like to see on this page, and this sentence is ready to copy.`:`Give this page a name and it will be created — then this sentence is ready to copy.`,Ms=e=>{let t=e=>e.map(e=>({url:String(e?.url||``).trim(),where:String(e?.where||``).trim()})).filter(e=>e.url);if(Array.isArray(e?.images))return t(e.images);let n=String(e?.imageUrl||``).trim();return n?[{url:n,where:String(e?.imageWhere||``).trim()}]:[]},Ns=e=>Array.isArray(e?.images)?e.images.map(e=>({url:String(e?.url||``),where:String(e?.where||``)})):Ms(e),Ps=e=>String(e?.imageNotes||``).trim(),Fs=e=>{let t=Ms(e);if(!t.length)return[];if(t.some(({where:e})=>e))return t.map(({url:e,where:t})=>t?`Use this picture of mine on the page: ${e} — where it goes: ${t}. Keep its proportions and give it a short description for screen readers. Do not swap it for a placeholder or a picture of your own.`:`Use this picture of mine on the page: ${e} — put it where it works best in your design, keep its proportions, and give it a short description for screen readers. Do not swap it for a placeholder or a picture of your own.`);let n=t.map(({url:e},t)=>`${t+1}: ${e}`).join(`; `),r=Ps(e);return[`Use these pictures of mine on the page, numbered the way I refer to them — ${n}. Keep their proportions, give each a short description for screen readers, and never swap one for a placeholder or a picture of your own.`,r?`Here is how the pictures go: ${r}`:`Put each picture where it works best in your design.`]},Is=e=>{if(!Array.isArray(e?.imagesSent))return[];let t=new Set(e.imagesSent.map(String));return Ms(e).filter(({url:e})=>!t.has(e))},Ls=e=>{let t=Is(e);if(!t.length)return[];let n=Ms(e),r=t.map(e=>`${n.findIndex(t=>t.url===e.url)+1}: ${e.url}`).join(`; `),i=Ps(e);return[`I have added ${t.length===1?`a picture`:`pictures`} to the page's gallery, numbered the way I refer to them — ${r}. Use ${t.length===1?`it`:`them`} on the page: keep the proportions, give each a short description for screen readers, and never swap one for a placeholder or a picture of your own.`,i?`Here is how the pictures go: ${i}`:`Put each where it works best in your design, unless my words below say where.`]},Rs=e=>Array.isArray(e?.imagesSent)?Ls(e):Fs(e),zs=e=>!e||typeof e!=`object`?!1:Object.entries(e).some(([e,t])=>e===`sent`||e===`imagesSent`?!1:Array.isArray(t)?t.length>0:t&&typeof t==`object`?Object.keys(t).length>0:String(t??``).trim()!==``),Bs=`Make it match the rest of my app: style with the app’s own theme styles so it looks right in light and dark. Do not pick your own colors. Build it from the app’s own pieces — import { SectionHeading, Card, Button } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button — so nothing gets a look of its own. Do not add a dropdown, a filter, a picker or a switch I did not ask for. If something I asked for needs a dropdown, it is CustomSelect from the same import (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme. Everything must be readable: an icon or word on a button takes the button’s own text color — give it no color of its own, so there is never a dark icon on a colored button — and nothing anywhere is light on light or dark on dark. The design should be minimal, modern and clean and match the app.`,Vs=`Keep it matching the rest of my app: style with the app’s own theme styles so it looks right in light and dark. Do not pick your own colors. Anything new you draw uses the app’s own pieces — import { SectionHeading, Card, Button } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button. Do not add a dropdown, a filter, a picker or a switch I did not ask for. If something I asked for needs a dropdown, it is CustomSelect from the same import (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme. Everything must be readable: an icon or word on a button takes the button’s own text color — give it no color of its own, so there is never a dark icon on a colored button — and nothing anywhere is light on light or dark on dark.`,Hs=`If the page opens with a hero, make it the full height of the first screen (min-h-screen on that one section — never a fixed height, never overflow hidden), add visual elements that give it wow factor, and end it where the next section begins: the rest of the page comes after it, never inside it.`,Us=(e,t)=>e?.type?e.type!==`public`:!!t?.pageType,Ws=[`Everything below the page heading is yours to design however you like — one clean column of sections using the full width. Never stack panels inside panels, never let sections overlap, and when the content grows tall let the page scroll.`,Hs],Gs=`This page is a screen INSIDE my app, not a page of my website: it opens for somebody who has already signed in, under the heading and the menu the app draws itself, inside the app’s own panel. So it never opens like a landing page — no full-height hero, no headline selling my app to a visitor, no marketing sections, and no page heading, menu, background or wrapper of your own. Begin with the thing the page is FOR, at the top, where somebody who came to use it will reach it without scrolling; anything explaining it goes after that, short. Below that the design is yours: one clean column of sections across the full width, never a panel inside a panel, never sections that overlap, and when it grows tall let it scroll.`,Ks=(e,t,n=[])=>{let r=As(e,t),i=String(t?.tabName||t?.pageName||``).trim(),a=i===`New page`?``:i,o=String(t?.template||``),s=String(t?.form||``).trim(),c=String(t?.brief||``).trim(),l=t?.pageType?`private`:`public`,u=Ai(Os(e,t))||`Page`,d=u.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase(),f=[`My app already has a page${a?` called ${a}`:``} at ${r}. It is already made and it is already in the menu — do not create a page, a web address or a settings file for it, and do not edit any other file.`,`Write one file: ${ks(e,t)}, with a default export. That file is what the page shows.`,`Then add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts so the app loads your file: import ${u}Content from './${u}Content'; and registerMicrocomponent('${d}', ${u}Content); — registerMicrocomponent is imported there from 'your-ai-workflow-firebase-os'. Never remove another page's lines from that file.`,Bs,...Us(e,t)?[Gs]:Ws,qs];f.push(...Ho(t));let p=cs(t);f.push(...es(e,t,[c,...p].join(`
|
|
21
|
-
`),p.length>0)),f.push(...p),ws.includes(o)&&f.push(Es(o));let m=sc(t);return m?f.push(...lc(t,l)):s?f.push(...uc(t,s)):rc(c)&&f.push(ic(t,l)),f.push(...dc(t,m)),f.push(...ac(t,l)),f.push(...To(t)),f.push(...qc(t)),f.push(...$c(e,t)),f.push(...Fs(t)),f.push(`Here is what I would like on it: ${c||`___`}`),f.push(...fl(t,n)),f.join(`
|
|
22
|
-
`)},qs=`Anything I have not decided below — the section titles, the words on the buttons, the layout, where the pictures and the form go — decide yourself and build it finished; do not stop to ask me.`,Js=/^\s*(name|page name|address|web address|route|url|heading|title|forms?)\s*(?::|\s[-–—]\s)\s*(.*)$/i,Ys=e=>{let t={name:``,address:``,heading:``,rest:``},n=[];for(let r of String(e||``).split(`
|
|
23
|
-
`)){let e=r.match(Js),i=e?e[1].toLowerCase():``;if(!e||i===`form`||i===`forms`){n.push(r);continue}let a=e[2].trim();i===`name`||i===`page name`?t.name=a:i===`heading`||i===`title`?t.heading=a:t.address=a}return t.rest=n.join(`
|
|
24
|
-
`).trim(),t},Xs={public:{name:`Photos`,describe:`A gallery of my work, newest first, with a short line about me at the top and a Get in touch button at the bottom.`,form:`Ask for their name, email and what they need, at the bottom of the page under a Get in touch button. After they send it, thank them and say I answer within a day. And a second one at the top, Join the newsletter, that asks only for an email.`,payments:`A Book button under each session. After they pay, thank them here and say I will be in touch to set a time.`},user:{name:`My albums`,describe:`A private gallery with albums, where each person sees only their own. Use a camera icon in the menu.`,form:`A new album — its name and a line about it. After it is sent, open the album. And Report a problem — what went wrong, with a screenshot.`,payments:`A Pay button on each plan. After they pay, unlock the videos for them right here.`},internal:{name:`Clients`,describe:`A list of every client — name, what we are doing for them, the next step and its date — that anyone on the team can add to. Use a briefcase icon in the menu.`,form:`Add a client — their name, company and what they need. After it is sent, add them to the list. And Log a call — the client, the date and what was said.`,payments:`Every sale as a row — who, what, when — newest first, with the total this month at the top.`},admin:{name:`Invoices`,describe:`Every invoice — who, how much, paid or not — with totals per month at the top. Use a receipt icon in the menu.`,form:`Add an invoice — the client, the amount and the due date. After it is sent, add it to the list unpaid. And Record a payment — the invoice and the amount received.`,payments:`Every sale as a row — who, what, when — newest first, with the total this month at the top.`}},Zs={visitor:`For new clients to book an intro call. Explain what the session covers first, and say I will confirm by email.`,ask:`What they need help with, their phone number, and whether they have worked with us before.`,team:`Every booking as a row — who, with whom, when — soonest first.`},Qs={how:`Every booking made on this page appears there, newest first.`,newPage:`A page for my team with every booking made here — who, when, what for — newest first.`},$s=`Show the albums three to a row, put a search box above them, and take the prices off.`,ec=`Ask for a phone number too, and add a second form at the bottom, Join the newsletter, that asks only for an email.`,tc=e=>{let t=String(e||``).match(/\b(?:icon\s*(?::|is|of|should be|could be)?\s*(?:a|an|the)?\s*([a-z][a-z-]*)|(?:a|an|the)\s+([a-z][a-z-]*)\s+icon)\b/i),n=(t?.[1]||t?.[2]||``).toLowerCase();return!n||[`in`,`for`,`on`,`that`,`of`,`the`,`menu`].includes(n)?``:Ye(n,1)[0]||``},nc=e=>{let t=String(e||``).match(/^\s*(?:heading|title)\s*(?::|\s[-–—]\s)\s*(.+)$/im);return t?t[1].trim():``},rc=e=>/\bforms?\b/i.test(e),ic=(e,t)=>{let n=zc(e)||`page`;return`If my words below ask for a form, create it as one more file, src/your-ai-workflow-firebase-os/configs/${n}Form.config.ts, the way my app's instructions describe a form, with systemName '${n}' and formType '${t}', and show it on the page with <ContactPopup formId='${n}' /> — never build a form out of your own inputs. If they ask for more than one, each further form is one more file in that same shape, named after the page's id plus one lowercase word for what it is (${n}newsletterForm.config.ts, systemName '${n}newsletter'). If they name a form my app already has, show that one under its own id and do not make another. What each asks is in my words; where it goes and what its button says are yours to decide.`},ac=(e,n,r=String(e?.brief||``))=>{if(!t.Cn(r)||hl(e).schedules.length>0)return[];let i=t.yn().filter(t.Wt);if(!i.length)return[];let a=t.Sn(i);if(tl(e))return[`If my words below ask for bookings to be shown, this page is where my team follows the times people book with ${a}. ${t.Nt}`];let o=String(e?.form||``).trim()||zc(e)||`page`,s=i.length>1;return[`If my words below ask for booking, people book ${t.Ln(i)} on this page${s?` — whichever my words name, or all of them if I did not say`:``}; how long a booking lasts is set by the schedule, so never state or ask for a length. ${t.St}`,`The question goes in the page's form; if the page has none, create one as src/your-ai-workflow-firebase-os/configs/${o}Form.config.ts, the way my app's instructions describe a form, with systemName '${o}' and formType '${n}', asking their name and their email. Add exactly this question to it, copied as it is${s?`, keeping only the schedules my words name`:``}: ${t.Pn(i.map(e=>e.id))}`,...t.Yn(i)?[t.Jn()]:[],t.vt]},oc=e=>String(e?.formWish||``).trim(),sc=e=>String(e?.form||``)===`__new__`||!!e?.formIsNew||!String(e?.form||``).trim()&&!!oc(e),cc=e=>{let t=hc(e);return!!String(e?.form||``).trim()||sc(e)||!!t?.formWish||!!t?.form},lc=(e,t)=>{let n=String(e?.form||``),r=n!==`__new__`&&n||zc(e)||`page`,i=oc(e),a=String(e?.formFields||``).trim(),o=String(e?.formButton||``).trim(),s=String(e?.formSpot||``).trim();if(i)return[`The page needs the forms my words below describe — one, or several. If my words below name a form my app already has, show that one with <ContactPopup formId='…' /> under its own id and do not make another. Otherwise create the first as one more file, src/your-ai-workflow-firebase-os/configs/${r}Form.config.ts, the way my app's instructions describe a form, with systemName '${r}' and formType '${t}', and each further one as one more file in that same shape, named after the page's id plus one lowercase word for what it is (${r}newsletterForm.config.ts, systemName '${r}newsletter'). Show each on the page with <ContactPopup formId='…' /> under its own systemName — never build a form out of your own inputs. Where each goes on the page and what its button says are yours to decide.`,`Here is what the forms should ask, and what happens after: ${i}`];let c=[`The page needs a form of its own. Create it as one more file, src/your-ai-workflow-firebase-os/configs/${r}Form.config.ts, the way my app's instructions describe a form, with systemName '${r}' and formType '${t}'. It should ask for: ${a||`___`}`,`Show that form on the page with <ContactPopup formId='${r}' /> — never build a form out of your own inputs.`];return o&&c.push(`The form opens from a button that says ${o} — make that button part of the page's design, not an afterthought.`),s&&c.push(`Where the form belongs on the page: ${s}`),c},uc=(e,t,n=!1)=>{let r=n?[`The page already shows my form ${Lc(t)} with <ContactPopup formId='${t}' /> — keep showing it, and change how it works here as my words say. Never write a form by hand.`]:[`Show my form ${Lc(t)} on it with <ContactPopup formId='${t}' /> — never write a form by hand.`],i=oc(e),a=String(e?.formButton||``).trim(),o=String(e?.formSpot||``).trim();return i&&r.push(n?`Here is what should change about the form here: ${i}`:`Here is how the form should work on this page: ${i}`),a&&r.push(`The form opens from a button that says ${a} — make that button part of the page's design, not an afterthought.`),o&&r.push(`Where the form belongs on the page: ${o}`),r},dc=(e,n)=>{let r=tl(e),i=t.Xt(e,t.bn(),r,t.yn());if(!i.length||r)return i;let a=String(e?.form||``).trim();if(sc(e)||n)return i;let o=hc(e)?.formWish?zc(e)||`page`:``;if(a||o){let e=a||o;return[o&&!a?`The page already has its own form, src/your-ai-workflow-firebase-os/configs/${e}Form.config.ts — add the question to that form where it is defined (if the page has several and my words name one, to that one), keeping its systemName exactly as it is.`:`The page's form is '${e}' — add the question to that form where it is defined, keeping its id exactly '${e}'.`,...i]}let s=t.Dn(e)?.ask.trim()||``,c=`their name (text) and their email (email)`;return[...lc({...e,form:Rc,formFields:String(e?.formFields||``).trim()||(s?`${c}, and ${s}`:c)},e?.pageType?`private`:`public`),...i]},fc={formWish:``,form:``,booking:{schedules:[],party:`each`,ask:``,how:``},bookingLinks:[],bookingLinksNote:``,links:[],emails:[],paymentIds:[],paymentNote:``,roles:[],canDo:{},prefix:``},pc=e=>{let t={};if(!e||typeof e!=`object`)return t;for(let n of Object.keys(e).sort()){let r=String(e[n]??``).trim();r&&(t[n]=r)}return t},mc=(e,n)=>{let r=hl(n);return{formWish:oc(n),form:String(n?.form||``).trim(),booking:{schedules:r.schedules,party:r.party,ask:r.ask.trim(),how:r.how.trim()},bookingLinks:bo(n),bookingLinksNote:xo(n),links:oa(n).filter(e=>e.pageId).map(e=>({pageId:e.pageId,how:e.how.trim()})),emails:Gc(n).map(e=>({...e,what:e.what.trim()})),paymentIds:Xc(e,n).map(e=>e.id),paymentNote:Zc(n),roles:n?.pageType?t.wa(n):[],canDo:is(n),prefix:n?.pageType?t.va(n):``}},hc=e=>{let n=e?.sent;if(!n||typeof n!=`object`)return null;let r=hl({booking:n.booking});return{formWish:String(n.formWish||``).trim(),form:String(n.form||``).trim(),booking:{schedules:r.schedules,party:r.party,ask:r.ask.trim(),how:r.how.trim()},bookingLinks:bo(n),bookingLinksNote:xo(n),links:Array.isArray(n.links)?n.links.map(e=>({pageId:String(e?.pageId||``),how:String(e?.how||``).trim()})).filter(e=>e.pageId):[],emails:Gc({emails:n.emails}).map(e=>({...e,what:e.what.trim()})),paymentIds:Array.isArray(n.paymentIds)?n.paymentIds.map(String):[],paymentNote:String(n.paymentNote||``).trim(),roles:t.ca(n.roles),canDo:pc(n.canDo),prefix:String(n.prefix||``)}},gc=(e,t)=>JSON.stringify(e)===JSON.stringify(t),_c=e=>{let t=String(e?.form||``).trim();return t!==`__new__`&&t||zc(e)||`page`},vc=e=>(Vc.find(t=>t.id===e)?.label||`that email`).replace(/^./,e=>e.toLowerCase()),yc=(e,n,r,i)=>{let a=mc(e,n),o=n?.pageType?`private`:`public`,s=tl(n),c=[],l=!1,u=!1;if(a.form!==i.form||a.formWish&&a.formWish!==i.formWish){l=!0;let e=!!i.form||!!i.formWish;if(a.form||a.formWish)if(sc(n))if(e){let e=_c(n);c.push(`The page's own forms already exist as files — the first as src/your-ai-workflow-firebase-os/configs/${e}Form.config.ts with systemName '${e}', any further one named after the page's id plus one lowercase word for what it is. Change them where they are defined, keeping each systemName exactly as it is, and keep showing each on the page with <ContactPopup formId='…' />. A form my words add is one more file in that same shape, with formType '${o}'. Never build a form out of your own inputs.`,`Here is what should change about the forms: ${a.formWish}`)}else c.push(...lc(n,o)),u=!0;else a.form&&c.push(...uc(n,a.form,a.form===i.form));else c.push(`Take the form off this page: stop showing it here, and leave the form itself where it is defined.`)}gc(a.booking,i.booking)||(l=!0,a.booking.schedules.length?c.push(...dc(n,u)):c.push(s?`This page no longer follows bookings — take the list of bookings off it.`:`Take booking off this page: remove the 'schedule' question from its form and every trace of the picker. The schedules themselves stay on my Schedule screen.`));let d=a.bookingLinks.filter(e=>!i.bookingLinks.includes(e)),f=i.bookingLinks.filter(e=>!a.bookingLinks.includes(e)),p=a.bookingLinksNote!==i.bookingLinksNote&&a.bookingLinks.length>0;if(d.length||f.length||p){l=!0,d.length?c.push(...To(n,yo(),d)):p&&a.bookingLinksNote&&c.push(`Here is where the booking links on this page should sit now and how they should open: ${a.bookingLinksNote}`);for(let e of f)c.push(Eo(e))}let m=a.links.filter(e=>!i.links.some(t=>t.pageId===e.pageId&&t.how===e.how)),h=i.links.filter(e=>!a.links.some(t=>t.pageId===e.pageId));if(m.length||h.length){l=!0,m.length&&c.push(...fl(n,r,m.map(e=>e.pageId)));for(let e of h){let t=sa(e.pageId,r);t&&c.push(`This page is no longer linked to the page at ${t.path} — take that connection off this page, and leave that page as it is.`)}}let g=a.emails.filter(e=>!i.emails.some(t=>gc(t,e))),_=i.emails.filter(e=>!a.emails.some(t=>t.kind===e.kind));if(g.length||_.length){l=!0,c.push(...qc({...n,emails:g}));for(let e of _)c.push(`Stop the email this page sends to ${vc(e.kind)} — remove that call, and nothing else changes.`)}let v=i.roles.some(t.ma),y=a.roles.some(t.ma),b=!gc(a.roles,i.roles)&&(v||y),x=!!i.prefix&&!!a.prefix&&a.prefix!==i.prefix;(b||x)&&(l=!0,y&&b?c.push(...Ho(n)):x&&!(v&&b)?c.push(`Who can open this page has changed, and its records now belong in ${a.prefix} collections rather than ${i.prefix} ones — read and write those from here on. Whatever is already saved in the ${i.prefix} collections stays where it is; do not move it unless I ask.`):c.push(`This page is no longer kept for one of my own roles, so its data goes back to the ordinary ${t.va(n)} collections — read and write those from here on. Whatever is already saved in the role_ collections stays where it is; do not move it unless I ask.`)),!gc(a.canDo,i.canDo)&&Object.keys(a.canDo).length&&(l=!0,c.push(...cs(n,ss)));let S=Xc(e,n).filter(e=>!i.paymentIds.includes(e.id)),C=i.paymentIds.filter(e=>!a.paymentIds.includes(e)),w=a.paymentNote!==i.paymentNote&&a.paymentIds.length>0;if(S.length||C.length||w){l=!0,S.length?c.push(...$c(e,n,S)):w&&a.paymentNote&&c.push(`Here is what should appear for the payments on this page now: ${a.paymentNote}`);for(let e of C){let t=Da().find(t=>t.id===e);c.push(s?`This page no longer follows ${t?Yi(t):`that payment`} — take it off the page.`:`Take ${t?Yi(t):`that payment`} off this page — its Pay button goes, and nothing else changes.`)}}return{changed:l,lines:c}},bc=(e,n)=>Kc(e)||ol(e,n)||t.Jt(e,t.bn(),t.yn()),xc=(e,t={title:``,path:``},n=[],r=hc(e)??mc(t,e),i=String(e?.pageChange||``),a=Ls(e).length>0)=>bc(e,n)||(i.trim()||a||yc(t,e,n,r).changed?``:`Say what you would like changed on this page, and this sentence is ready to copy.`),Sc=(e,t,n=[])=>{let r=As(e,t),i=String(t?.tabName||t?.pageName||``).trim(),a=i===`New page`?``:i,o=String(t?.pageChange||``).trim(),s=t?.pageType?`private`:`public`,c=[`My app already has a page${a?` called ${a}`:``} at ${r}, and the file it shows already exists: ${ks(e,t)}.`,`Change that one file. Do not create a page, a web address, a settings file or a second content file, do not add or remove anything in registry.ts, and do not edit any other file — except the page's own form, where it is defined, when the change is about the form, and except what this request asks for by name below.`,Vs,...Us(e,t)?[Gs]:[Hs],`Keep everything on the page that I have not asked you to change.`],l=Es(String(t?.template||``));l&&c.push(l);let u=hc(t)??mc(e,t),d=yc(e,t,n,u).lines;c.push(...d),!cc(t)&&rc(o)&&c.push(ic(t,s));let f=!gc(is(t),u.canDo)&&Object.keys(is(t)).length>0;return c.push(...es(e,t,[o,...f?cs(t):[]].join(`
|
|
25
|
-
`),f)),c.push(...ac(t,s,o)),c.push(...Ls(t)),(o||!d.length)&&c.push(`Here is what I would like changed: ${o||`___`}`),c.join(`
|
|
26
|
-
`)},Cc={home:{title:`Change the home page`,ask:`What would you like on the home page?`,example:`A big heading that says Bright Studio, a photo of the shop under it, and a Get in touch button.`,changeAsk:`What would you like changed on the home page?`,changeExample:`Make the heading bigger, and put the Get in touch button under the photo.`,lead:[`My app already has a home page, and it is one file: src/your-ai-workflow-firebase-os/Home.tsx. Change that one file — do not create a page, a web address, a settings file or a HomeContent.tsx, and do not edit any other file except what this request asks for by name below.`,`Keep its named export exactly as it is: export function Home. Making it a default export breaks my site.`,Vs,Hs,`Keep every heading at the size it already has and keep the space at the top of the page as it is — a bigger title or moved spacing is how this page stops matching the rest of my app.`,`Keep everything on the page that I have not asked you to change.`]},contact:{title:`Change the contact page`,ask:`What would you like on the contact page?`,example:`A line saying we answer within a day, our opening hours, and the form under them.`,changeAsk:`What would you like changed on the contact page?`,changeExample:`Add a map under the opening hours, and say we are closed on Sundays.`,lead:[`My app already has a contact page at /contact and a contact form. Do not create a page, do not create a form, and do not change the questions the form asks unless this request says so by name below.`,`Change what the page shows by writing one file: src/your-ai-workflow-firebase-os/microcomponents/ContactContent.tsx, with a default export. Then add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import ContactContent from './ContactContent'; and registerMicrocomponent('contact', ContactContent); — never remove another page's lines from that file.`,`Show my form with <ContactPopup formId='contact' /> — add isInline to build it into the page instead of opening it as a pop-up. Never build a form out of your own inputs.`,Vs,`Keep everything on the page that I have not asked you to change.`]},dashboard:{title:`Change the dashboard`,ask:`What would you like on the dashboard?`,example:`Three boxes across the top: bookings today, bookings this week, and unread messages.`,changeAsk:`What would you like changed on the dashboard?`,changeExample:`Add a fourth box for sales this month, and list the latest five messages under the boxes.`,lead:[`My app already has a dashboard at /dashboard — the screen a signed-in person lands on. Do not create a page, a web address or a settings file for it, do not touch src/App.tsx, and do not edit any other file except what this request asks for by name below.`,`Fill it by writing one file: src/your-ai-workflow-firebase-os/microcomponents/DashboardContent.tsx, with a default export. Then add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import DashboardContent from './DashboardContent'; and registerMicrocomponent('dashboard', DashboardContent); — never remove another page's lines from that file.`,`It draws inside the dashboard’s own panel, under the welcome heading and the menu, so do not write a page heading, a menu or a page wrapper of your own.`,Vs]},support:{title:`Change the support page`,ask:`What would you like on the support page?`,example:`A short list of the questions we get asked most, above the form.`,changeAsk:`What would you like changed on the support page?`,changeExample:`Add a question about refunds to the list, and move the form above it.`,lead:[`My app already has a support page at /support and a support form. Do not create a page, do not create a form, and do not change the questions the form asks unless this request says so by name below.`,`Change what the page shows by writing one file: src/your-ai-workflow-firebase-os/microcomponents/SupportContent.tsx, with a default export. Then add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import SupportContent from './SupportContent'; and registerMicrocomponent('support', SupportContent); — never remove another page's lines from that file.`,`Show my form with <ContactPopup formId='support' /> — add isInline to build it into the page instead of opening it as a pop-up. Never build a form out of your own inputs.`,Vs,`Keep everything on the page that I have not asked you to change.`]}},wc=(e,t)=>{let n=Io.find(t=>t.id===e)?.type||`public`;return{...t||{},contentKey:e,...n===`public`?{}:{pageType:n},...e===`contact`||e===`support`?{form:e}:{}}},Tc=e=>{let t=Io.find(t=>t.id===e);return{id:e,title:t?.title||e,path:t?.path||`/${e}`}},Ec=(e,t,n=[])=>{let r=Cc[e];if(!r)return``;let i=Tc(e),a=wc(e,t),o=String(t?.pageWish||``).trim(),s=a.pageType?`private`:`public`,c=hc(a),l=yc(i,a,n,c??fc).lines;return!cc(a)&&rc(o)&&l.push(ic(a,s)),l.push(...ac(a,s,o)),l.push(...Rs(a)),(o||!l.length)&&l.push(`Here is what I would like ${c?`changed`:`on the page`}: ${o||`___`}`),[...r.lead,...l].join(`
|
|
27
|
-
`)},Dc=(e,t,n=[])=>{let r=wc(e,t);return xc(r,Tc(e),n,hc(r)??fc,String(t?.pageWish||``),Rs(r).length>0)},Oc=(e,t)=>{let n=e=>{let{_uiKey:t,pageType:n,route:r,contentKey:i,built:a,imagesSent:o,sent:s,...c}=e||{};return c},r=n(e),i=n(t),a=new Set([...Object.keys(r),...Object.keys(i)]),o=(e,t)=>e&&typeof e==`object`?JSON.stringify(e)===JSON.stringify(t):(e??``)===(t??``);for(let e of a)if(!o(r[e],i[e]))return!0;return!1},kc=(e,t)=>{let n=vs(),r=n[e.id]||(t?.contentKey?n[String(t.contentKey)]:void 0)||Object.entries(n).find(([t,n])=>{let r=n.config||{},i=r.route?r.route.startsWith(`/`)?r.route:`/`+r.route:`/`+t;return!!e.path&&i===e.path})?.[1];return r?r.config||{}:null},Ac=(e,n)=>{let{_uiKey:r,...i}=e||{};return{...i,...t.sa(n)}},jc=`w-6 h-5 rounded-md flex items-center justify-center text-foreground/35 hover:text-foreground hover:bg-foreground/[0.07] transition-colors cursor-pointer`,Mc=`max-sm:hidden sm:inline-flex items-center gap-1.5 text-[11px] font-semibold text-foreground/45 border border-[var(--panel-border)] bg-foreground/[0.02] px-2 py-[3px] rounded-full`,Nc={draft:`text-foreground/55 border-[var(--panel-border)] bg-foreground/[0.03]`,live:`text-emerald-500 border-emerald-500/25 bg-emerald-500/[0.07]`,hidden:`text-foreground/45 border-[var(--panel-border)]/70 bg-transparent`},Pc={draft:`bg-foreground/30`,live:`bg-emerald-500 shadow-[0_0_5px] shadow-emerald-500/60`,hidden:`bg-foreground/25`};function Fc({status:e}){return(0,i.jsxs)(`span`,{title:fs[e],className:`inline-flex items-center gap-1.5 text-[11px] font-semibold px-2.5 py-[3px] rounded-full border ${Nc[e]}`,children:[(0,i.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full shrink-0 ${Pc[e]}`}),ds[e]]})}var Ic=e=>{let t=typeof window<`u`?window.location.host:``;return t?`${t}${e}`:e},Lc=e=>e.replace(/[_-]+/g,` `).replace(/^./,e=>e.toUpperCase()),Rc=`__new__`,zc=e=>String(e?.contentKey||``).toLowerCase().replace(/-+/g,`_`),Bc=e=>sc(e)&&!oc(e)&&!String(e?.formFields||``).trim(),Vc=[{id:`notify`,label:`Let me know when something happens here`,ask:`What should I be told about?`,hint:`In your own words — you get an email each time it happens.`,placeholder:`Every new booking, with the name and the time they picked`,look:`notification`},{id:`confirm`,label:`Send the person a confirmation`,ask:`What should the confirmation say?`,hint:`Sent to whoever wrote in or booked, right after. It only reaches people who are signed in.`,placeholder:`Thanks, your booking is in — I will confirm the time within a day.`,look:`text`},{id:`send`,label:`Send emails from my account`,ask:`What should be sent, and to whom?`,hint:`Your team writes the email on this page and it goes out from your address — to a customer, a client, anyone.`,placeholder:`A message to a customer, picked from the list of people who booked, written on the spot`,look:`text`,team:!0}],Hc=e=>Vc.filter(t=>!t.team||ia(e)),Uc=[{value:`text`,label:`Simple text`},{value:`notification`,label:`Notification`}],Wc=e=>e.look===`text`||e.look===`notification`?e.look:Vc.find(t=>t.id===e.kind)?.look||`text`,Gc=e=>{let t=e?.emails;if(!Array.isArray(t))return[];let n={owner:`notify`,confirm:`confirm`};return t.map(e=>typeof e==`string`?{kind:n[e]||e,what:``}:{kind:String(e?.kind||``),what:String(e?.what||``),...e?.look===`text`||e?.look===`notification`?{look:e.look}:{}}).filter(e=>Vc.some(t=>t.id===e.kind))},Kc=e=>{if(!Mo())return``;for(let t of Gc(e))if(!t.what.trim())return`Say what the email should be about, and this sentence is ready to copy.`;return``},qc=e=>{if(!Mo())return[];let t=tl(e),n=[];for(let r of Gc(e)){let e=r.what.trim();if(!e)continue;let i=Wc(r)===`notification`;r.kind===`notify`?n.push(i?`Email me when something happens on this page, with the app's own emailOwner('heads_up', { title, summary, details }) right after it happens — title says what happened in a few words, summary one line under it, details an object of the facts worth seeing ({ Name: name, Time: slot } and the like). It arrives as a notification card in my app's own look. Never write email code of your own. Here is what I want to hear about: ${e}`:`Email me when something happens on this page, with the app's own emailOwner('heads_up', { title, summary, look: 'text' }) right after it happens — title says what happened in a few words, summary the details in plain sentences. It arrives as a simple text email in my app's own look. Never write email code of your own. Here is what I want to hear about: ${e}`):r.kind===`confirm`?n.push(i?`When a SIGNED-IN person sends something on this page, email them a confirmation with the app's own emailPerson('submission_received', collection, docId, { note, look: 'notification', details }) right after it saves, putting the words below in note and what they sent in details as an object ({ Date: date, Guests: guests } and the like). It arrives as a notification card in my app's own look. Skip it silently for someone who is not signed in — their saved record is not theirs to read. Here is what the confirmation should say: ${e}`:`When a SIGNED-IN person sends something on this page, email them a confirmation with the app's own emailPerson('submission_received', collection, docId, { note }) right after it saves, putting the words below in note. It arrives as a simple text email in my app's own look. Skip it silently for someone who is not signed in — their saved record is not theirs to read. Here is what the confirmation should say: ${e}`):r.kind===`send`&&t&&n.push(i?`This page lets my team send an email to anyone from the app. Build the address, subject and message fields from the app's own pieces and send with the app's own emailAnyone(to, subject, message, { look: 'notification', details }) — details an object of the facts the email is about ({ Order: order, Date: date } and the like), from fields on this page; it resolves to null when sent, or to a message to show; it only works for a signed-in team member or admin, which is who this page is for. It arrives as a notification card in my app's own look: the subject as its headline, the message under it, the details in a box. Never write email code of your own. Here is what should be sent, and to whom: ${e}`:`This page lets my team send an email to anyone from the app. Build the address, subject and message fields from the app's own pieces and send with the app's own emailAnyone(to, subject, message) — it resolves to null when sent, or to a message to show; it only works for a signed-in team member or admin, which is who this page is for. It arrives as a simple text email in my app's own look, so send the words as typed. Never write email code of your own. Here is what should be sent, and to whom: ${e}`)}return n},Jc=(e=Da())=>e.filter(e=>qi(e)),Yc=(e,t)=>({id:String(e.id||t?.contentKey||``),title:e.title,path:e.path,config:t}),Xc=(e,t,n=Da())=>{let r=Yc(e,t);return r.id?Jc(n).filter(e=>da(e,r)):[]},Zc=e=>String(e?.paymentNote||``).trim(),Qc=e=>{let t=e.map(Yi);return t.length<=1?t.join(``):`${t.slice(0,-1).join(`, `)} and ${t[t.length-1]}`},$c=(e,t,n)=>{if(!Fo())return[];let r=n??Xc(e,t);if(!r.length)return[];let i=[];if(tl(t))i.push(`This page is where my team follows what ${Qc(r)} sold. ${ya}`);else{i.push(`This page sells ${Qc(r)}. ${$i}`);for(let n of r)i.push(...ra(n,As(e,t)))}let a=Zc(t);return a&&i.push(`Here is what should appear for the payments on this page: ${a}`),i},el=(e,t=``)=>{let n=e.config,r=[],i=String(e.brief??n?.brief??``).trim();i&&r.push(`The page at ${e.path} is for: ${i}`);let a=String(t||``).trim(),o=a?`Here is what I would like on the page at ${e.path}: ${a}`:``,s=()=>o?[...r,o]:r;if(e.id===`home`)return r.push(`The home page is one file: src/your-ai-workflow-firebase-os/Home.tsx — put what I sell there by changing that one file. Keep its named export exactly as it is: export function Home. Never create a HomeContent.tsx, and do not edit any other file for it.`),s();if(e.id===`dashboard`)return r.push(`The dashboard's content is one file: src/your-ai-workflow-firebase-os/microcomponents/DashboardContent.tsx, with a default export. If it does not exist yet, write it and add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import DashboardContent from './DashboardContent'; and registerMicrocomponent('dashboard', DashboardContent); — never remove another page's lines from that file. It draws inside the dashboard's own panel, under the welcome heading and the menu, so do not write a page heading, a menu or a page wrapper of your own.`),s();if(!n)return s();let c={title:e.title,path:e.path},l=Ai(Os(c,n))||`Page`,u=l.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();r.push(`If it is empty, build it by writing one file: ${ks(c,n)}, with a default export, then add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import ${l}Content from './${l}Content'; and registerMicrocomponent('${u}', ${l}Content); — registerMicrocomponent is imported there from 'your-ai-workflow-firebase-os', and never remove another page's lines from that file. If it is already built, that file exists — change it, and leave registry.ts as it is.`);let d=String(n.template||``);ws.includes(d)&&r.push(Es(d));let f=String(n.form||``).trim(),p=sc(n);return p?(oc(n)||String(n.formFields||``).trim())&&r.push(...lc(n,n.pageType?`private`:`public`)):f&&r.push(...uc(n,f)),r.push(qs),r.push(...qc(n)),r.push(...Fs(n)),r.push(...dc(n,p)),r.push(...To(n)),s()},tl=e=>ia(t._a(e?.pageType)),nl=e=>cc(e),rl=(e,t)=>`On ${e}, do this exactly the way my app's instructions describe: while an admin has the page open, mirror each entry once into that page's own collection, keeping the source id on the copy — never read user_submissions or user_requests on a screen a non-admin can open. Mirror only the entries THIS page's form sent: my Inbox holds every form in my app, so skip any entry whose formId does not start with '${t}'. A time somebody booked is never in there at all — meetings come from useBookings() and nowhere else.`,il=(e,t)=>e.pageId?sa(e.pageId,t):void 0,al=(e,t)=>e.pageId?il(e,t)?e.how.trim()?``:`Say how the two pages connect, and this sentence is ready to copy.`:`The page this one linked to was deleted. Pick another, and this sentence is ready to copy.`:`Make or pick the page this one links to — or unlink it — and this sentence is ready to copy.`,ol=(e,t)=>{for(let n of oa(e)){let e=al(n,t);if(e)return e}return``},sl=e=>{switch(e){case`admin`:return{kind:`admin-only`,who:`only admins`};case`internal`:return{kind:`internal`,who:`only my team and admins`};case`user`:return{kind:`signed-in`,who:`only people who are signed in`};default:return{kind:`public`,who:`anyone`}}},cl={public:0,user:1,internal:2,admin:3},ll=e=>e?.pageType?t._a(e.pageType):`public`,ul=e=>({user:`user_`,internal:`mem_`,admin:`admin_`})[e]||`pub_`,dl=(e,t)=>{let n=ll(e),r=t.audience||`public`;if(cl[n]===cl[r])return[`They connect through the app's own database and nothing else: what this page saves is what the page at ${t.path} reads, live, from the same place. Never write a backend, an export or a copy of the data for it.`];let i=cl[n]>cl[r]?{path:`this page`,audience:n}:{path:`the page at ${t.path}`,audience:r},a=i.audience===n?{path:`the page at ${t.path}`,audience:r}:{path:`this page`,audience:n},o=ul(i.audience);return[`The two pages are for different people, so they cannot share one collection: a ${sl(a.audience).kind} page cannot read ${o} collections — the security rules answer with a permission error. Keep a public copy instead: ${i.path} saves to its own ${o} collection AND writes the same change to a pub_ copy on every add, edit and delete, under the same document id, and while it is open copies across any entry that has no copy yet; ${a.path} reads ONLY the pub_ copy. Put in the copy only what ${sl(a.audience).who} should see — never a person's name, email or message. Never name a mem_, admin_ or user_ collection in the code of ${a.path}, and never write a backend or an export for it.`]};function fl(e,n,r){let i=[],a=nl(e);for(let o of oa(e)){if(r&&!r.includes(o.pageId))continue;let s=il(o,n),c=o.how.trim();if(!s||!c)continue;let l=s.audience===`admin`,u=ia(s.audience),d=sl(s.audience);i.push(`This page is linked to the ${d.kind} page at ${s.path}, which ${d.who} can open. Build both pages of the link in this one request — this page and the one at ${s.path}. That page's web address and menu entry already exist — do not create a web address or a settings file for it, and do not change who can open it.`),i.push(`Here is how the two pages are linked: ${c}`),i.push(...dl(e,s));let f=t.xn(s.path,s.config,t.bn(),tl(e),t.yn());f&&i.push(f),a&&u&&!l&&i.push(`Entries from the form on this page land in the Inbox collections, which only admins may read. ${rl(s.path,_c(e))}`),i.push(`For the page at ${s.path}:`),i.push(...el(s))}return i.length&&i.push(`Do not touch any page this request does not name.`),i}var pl=(e,t,n,r)=>{let i=new Set([e.id]),a=String(t?.contentKey||``).trim();a&&i.add(a);let o=[];for(let t of n)t.id!==e.id&&oa(r[t.id]).some(e=>e.pageId&&i.has(e.pageId))&&o.push(t.title);return o};function ml({images:e,notes:n,onChange:r,onNotes:a,onBlur:o}){let s=e.filter(e=>e.url),c=e=>r(s.filter((t,n)=>n!==e));return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[s.length>0&&(0,i.jsx)(`div`,{className:`flex flex-wrap gap-2.5`,"aria-label":`Your pictures`,children:s.map((e,n)=>(0,i.jsxs)(`div`,{className:`relative w-20 h-20 rounded-xl overflow-hidden border border-[var(--panel-border)] bg-[var(--panel-bg)]`,children:[(0,i.jsx)(`img`,{src:e.url,alt:`Picture ${n+1}`,className:`w-full h-full object-cover`}),(0,i.jsx)(`span`,{"aria-hidden":!0,className:`absolute top-1 left-1 min-w-[20px] h-5 px-1.5 rounded-full bg-background/90 text-[11px] font-bold text-foreground flex items-center justify-center`,children:n+1}),(0,i.jsx)(`button`,{type:`button`,"aria-label":`Remove picture ${n+1}`,title:`Remove this picture`,onClick:()=>c(n),className:`absolute top-1 right-1 w-5 h-5 rounded-full bg-background/90 text-foreground/60 hover:text-red-500 flex items-center justify-center cursor-pointer transition-colors`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})})]},`${e.url}-${n}`))}),(0,i.jsx)(st,{label:s.length?`Add another picture`:`A picture for this page`,hint:s.length?void 0:`Optional — every picture you add gets a number, so you can say below where each one goes.`,value:``,onChange:e=>{e&&r([...s,{url:e,where:``}])},tips:s.length?void 0:ct}),s.length>0&&(0,i.jsx)(t.dt,{label:`How should the pictures be used?`,hint:`Optional — say it by number. Anything you leave out, your assistant decides.`,value:n,onChange:a,onBlur:o,placeholder:`1 across the top behind the heading, 2 and 3 side by side under it`})]})}var hl=e=>{let n=e?.booking&&typeof e.booking==`object`?e.booking:{};return{schedules:t.fn(t.Gn(n),t.bn(),t.yn()),party:t.Wn(n),ask:String(n.ask||``),how:String(n.how||``)}};function gl({title:e,hint:t,action:n,children:r}){return(0,i.jsxs)(`section`,{className:`flex flex-col gap-3 pt-4 border-t border-[var(--panel-border)]/50`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 ml-1`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0`,children:[(0,i.jsx)(`h4`,{className:`text-[13px] font-bold text-foreground/85 tracking-tight`,children:e}),t&&(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug max-sm:hidden`,children:t})]}),n]}),r]})}function _l({booking:e,team:n,schedules:r,onChange:a,onAsk:o,onHow:s,onBlur:c}){let l=e.schedules.length>0,u=t.Zt(e,r,t.yn()),d=!n&&t.Yn(u),f={each:`A visitor picks one of ${t.Sn(u)}, then one of that person’s own free times.`,all:`Only the times ${t.Sn(u)} are ALL free are offered, and one booking goes in every one of their calendars.`,choose:`The page offers both — the visitor chooses whether it is with one of ${t.Sn(u)} or all of them, then picks a time.`};return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(ko,{mode:`hours`,schedules:r,selected:e.schedules,onPick:n=>a({...e,schedules:t.An(e.schedules,n,r)}),placeholder:n?`Pick whose hours your team follows here`:`Pick whose hours this page is built on`}),d&&(0,i.jsx)(t.ct,{label:`If people book here, who is it with?`,hint:f[e.party],value:e.party,onChange:t=>a({...e,party:t||`each`}),options:t.yt,allowEmpty:!1}),l&&(0,i.jsx)(t.dt,{label:n?`What should your team see here?`:`How will these hours be used on this page?`,hint:n?`Every booking, who, when — or a rota, a shift board, who is in on Thursday.`:`A rota, who is free on Thursday, a page people book time on — anything built on those hours. The times come from the week itself and change with it, so say who it is for, what they read first, and what happens after.`,value:e.how,onChange:s,onBlur:c,placeholder:n?Zs.team:Zs.visitor}),l&&!n&&(0,i.jsx)(t.dt,{label:`If people book time here, what should they be asked?`,hint:`Optional — leave it empty and nothing is booked on this page unless your words above ask for it. In your own words, not fields: their name and their email are always taken, and a visitor already signed in is never asked for them.`,value:e.ask,onChange:o,onBlur:c,placeholder:Zs.ask})]})}function vl({targets:e,attached:n,note:r,onToggle:a,onNote:o,onBlur:s}){return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60 px-2 py-1.5`,role:`group`,"aria-label":`Booking links on this page`,children:e.map(e=>{let r=n.includes(e.path);return(0,i.jsxs)(`button`,{type:`button`,role:`checkbox`,"aria-checked":r,"aria-label":`${e.title} — ${e.path}`,onClick:()=>a(e.path),className:`w-full flex items-center gap-2.5 px-2 py-2 text-left cursor-pointer rounded-xl hover:bg-foreground/[0.04] transition-colors`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${r?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:r&&(0,i.jsx)(t.zi,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,i.jsxs)(`span`,{className:`flex-1 min-w-0 flex flex-col`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate`,children:e.title}),(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 truncate`,children:e.path})]})]},e.path)})}),n.length>0&&(0,i.jsx)(t.dt,{label:`Where should it sit on the page, and how should it open?`,hint:`Optional — the booking page itself is already made; this is only what leads to it here.`,value:r,onChange:o,onBlur:s,placeholder:`A button under the opening hours that says Book time with me, and it opens in a pop-up over the page.`})]})}function yl({products:e,ticked:n,team:r,note:a,onToggle:o,onNote:s,onBlur:l}){return e.length?(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60 px-2 py-1.5`,role:`group`,"aria-label":`Payments on this page`,children:e.map(e=>{let r=n.includes(e.id);return(0,i.jsxs)(`button`,{type:`button`,role:`checkbox`,"aria-checked":r,"aria-label":Xi(e),onClick:()=>o(e),className:`w-full flex items-center gap-2.5 px-2 py-2 text-left cursor-pointer rounded-xl hover:bg-foreground/[0.04] transition-colors`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${r?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:r&&(0,i.jsx)(t.zi,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate min-w-0`,children:Xi(e)})]},e.id)})}),n.length>0&&(0,i.jsx)(t.dt,{label:r?`What should your team see here?`:`How will paying work here?`,hint:r?`Every sale, who, what, when — laid out the way your team reads it.`:`The prices and the buttons come from the Payments screen — say where the button sits, what surrounds it, and what happens after they pay.`,value:a,onChange:s,onBlur:l,placeholder:r?Xs.internal.payments:Xs.public.payments})]}):(0,i.jsxs)(`p`,{className:t.$,children:[`Nothing to sell yet — describe what you sell on the`,` `,(0,i.jsx)(c.Link,{to:`/payments`,className:`text-accent font-bold hover:underline`,children:`Payments screen`}),` first.`]})}function bl({emails:e,audience:n,onChange:a,onBlur:o}){let s=Hc(n),c=s.map(e=>({value:e.id,label:e.label})),[l,u]=(0,r.useState)(!1),d=e.length?l?[...e,{kind:``,what:``}]:e:[{kind:``,what:``}],f=(e,t)=>{u(!1),a(d.map((n,r)=>r===e?{kind:t,what:n.what}:n).filter(e=>!!e.kind),!0)},p=(e,t)=>a(d.map((n,r)=>r===e?{...n,what:t}:n).filter(e=>!!e.kind),!1),m=(e,t)=>a(d.map((n,r)=>r===e?{...n,look:t}:n).filter(e=>!!e.kind),!0),h=!l&&e.length>0&&e.length<s.length;return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[d.map((e,n)=>{let r=s.find(t=>t.id===e.kind),a=c.filter(t=>t.value===e.kind||!d.some(e=>e.kind===t.value));return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5`,children:[(0,i.jsx)(t.ct,{label:n===0?`Would you like to add emails to this page?`:`Another email`,value:e.kind,onChange:e=>f(n,e),options:a,placeholder:`No`}),r&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.dt,{label:r.ask,hint:r.hint,value:e.what,onChange:e=>p(n,e),onBlur:o,placeholder:r.placeholder}),(0,i.jsx)(t.ct,{label:`How should it look?`,hint:`Simple text reads like a note: a greeting, your words, a sign-off. Notification is a card: a headline, a line under it and the facts in a box. Both carry your logo, name and colours from the Theme screen.`,value:Wc(e),onChange:e=>m(n,e),options:Uc,allowEmpty:!1})]})]},n)}),h&&(0,i.jsx)(`div`,{className:`flex`,children:(0,i.jsx)(t.Q,{icon:t.Ur,onClick:()=>u(!0),children:`Another email`})})]})}var xl=`__new_linked_page__`,Sl=t.aa.map(e=>({value:e,label:zo[e]})),Cl=e=>ps(e.address)||ps(e.name),wl=(e,t,n)=>{let r=Cl(e);return!(!e.name.trim()||!r||n(r)||!t.trim()||e.form===`__new__`&&!e.formFields.trim())},Tl=(e,t=``)=>{let n=Sl.some(t=>t.value===e.type)?e.type:`internal`;return{name:e.name.trim(),address:Cl(e),type:n,about:e.about.trim()||t.trim(),iconName:e.iconName||(n===`public`?``:tc(e.about)||Ds(e.name)),template:e.template,form:e.form,formFields:e.formFields.trim(),formButton:e.formButton.trim(),formSpot:e.formSpot.trim(),formWish:e.formWish.trim(),images:e.images,imageNotes:e.imageNotes.trim(),booking:e.booking}};function El({draft:e,taken:n,schedules:a,onEdit:o,onSave:s,onBlur:c}){let[l,u]=(0,r.useState)(``),d=Sl.some(t=>t.value===e.type)?e.type:`internal`,f=ia(d),p=Xs[d],m=Cl(e),h=()=>e.name.trim()?!m||n(m)?(u(m?`${Va(m)} Pick a different name.`:`Use a name with a letter or a number in it.`),!1):(u(``),!0):(u(`Give the new page a name, for example Bookings`),!1);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-4`,children:[(0,i.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4`,children:[(0,i.jsx)(t.ft,{label:`Name of the new page`,hint:m?`It will live at /${m}.`:`What it is called in the menu.`,value:e.name,onChange:e=>{o({name:e}),l&&u(``)},onBlur:()=>{h(),c()},error:l,placeholder:`Bookings`}),(0,i.jsx)(t.ct,{label:`Who can open it`,hint:`Anyone is your public website. Members is everybody who registers; Your team is everyone you have marked internal, plus admins.`,value:d,onChange:e=>s({type:e}),options:Sl,allowEmpty:!1})]}),(0,i.jsx)(t.dt,{label:`What is on the new page?`,hint:`In your own words. Whatever you skip, your assistant decides.`,value:e.about,onChange:e=>o({about:e}),onBlur:c,placeholder:Qs.newPage}),(0,i.jsx)(t.Z,{label:`Its pictures`,children:(0,i.jsx)(ml,{images:e.images,notes:e.imageNotes,onChange:e=>s({images:e}),onNotes:e=>o({imageNotes:e}),onBlur:c})}),(0,i.jsx)(t.dt,{label:`Its forms`,hint:`Optional — as many as you like: what each asks, where it sits and what happens after. Or name forms you already have.`,value:e.formWish,onChange:e=>o({formWish:e}),onBlur:c,placeholder:p.form}),(0,i.jsx)(t.Z,{label:`Schedules on it`,hint:f?`Optional — whose hours the team follows there.`:`Optional — whose working hours it is built on, one person each.`,children:(0,i.jsx)(_l,{booking:e.booking,team:f,schedules:a,onChange:e=>s({booking:e}),onAsk:t=>o({booking:{...e.booking,ask:t}}),onHow:t=>o({booking:{...e.booking,how:t}}),onBlur:c})})]})}function Dl({link:e,links:n,index:a,targets:o,self:s,schedules:c,onPatch:l,onBlur:u,onRemove:d,taken:f,onCreatePage:p}){let[m,h]=(0,r.useState)(!1),[g,_]=(0,r.useState)(``),v=il(e,o),y=o.filter(e=>!ca(s.id,e)&&!(s.contentKey&&ca(s.contentKey,e))&&(e.id===v?.id||!n.some((t,n)=>n!==a&&il(t,o)?.id===e.id))),b=e.pageId?v?.id||e.pageId:e.draft?xl:``,x=e=>{l(e===`__new_linked_page__`?{pageId:``,draft:aa()}:{pageId:e,draft:void 0},!0)},S=async()=>{if(e.draft){h(!0),_(``);try{l({pageId:await p(Tl(e.draft,e.how)),draft:void 0},!0)}catch(e){console.error(`Failed to create the linked page:`,e),_(`The page could not be created. Check its web address and try again.`)}h(!1)}},C=!!e.draft&&wl(e.draft,e.how,f),w=v?.title||e.draft&&e.draft.name.trim()||(e.draft?`A new page`:`A linked page`);return(0,i.jsxs)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 px-4 pt-3 pb-1`,children:[(0,i.jsx)(`span`,{className:`flex-1 min-w-0 text-[13px] font-semibold text-foreground/75 truncate`,children:w}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Unlink ${w}`,onClick:d,children:`Unlink`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 px-4 pb-4 pt-2`,children:[(0,i.jsx)(t.ct,{label:`Which page is it linked to?`,hint:b?void 0:`One of your pages — or a new one, made right here.`,value:b,onChange:x,options:[{value:xl,label:`+ A new page, made right here`},...y.map(e=>({value:e.id,label:`${e.title} — ${e.path}`}))],placeholder:`Pick a page`}),!!e.pageId&&!v&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500`,children:`The page this one linked to was deleted. Pick another, or unlink it.`}),e.draft&&(0,i.jsx)(El,{draft:e.draft,taken:f,schedules:c,onEdit:t=>l({draft:{...e.draft,...t}},!1),onSave:t=>l({draft:{...e.draft,...t}},!0),onBlur:u}),(!!v||!!e.draft)&&(0,i.jsx)(t.dt,{label:`How are the two pages linked?`,hint:`In your own words — what made here should show up there, and what happens after. It goes into the sentence below.`,value:e.how,onChange:e=>l({how:e},!1),onBlur:u,placeholder:Qs.how}),!!g&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500`,children:g}),e.draft&&(0,i.jsx)(`div`,{className:`flex pt-1`,children:(0,i.jsx)(t.Q,{icon:t.Ur,busy:m,disabled:!C,onClick:S,children:`Create and link it`})})]})]})}function Ol({links:e,targets:n,self:r,schedules:a,onChange:o,onBlur:s,taken:c,onCreatePage:l}){let u=(t,n,r)=>o(e.map((e,r)=>{if(r!==t)return e;let i={...e,...n};return i.draft||delete i.draft,i}),r),d=t=>o(e.filter((e,n)=>n!==t),!0),f=()=>o([...e,{pageId:``,how:``}],!0),p=e.every(e=>!!il(e,n));return e.length?(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.map((t,o)=>(0,i.jsx)(Dl,{link:t,links:e,index:o,targets:n,self:r,schedules:a,onPatch:(e,t)=>u(o,e,t),onBlur:s,onRemove:()=>d(o),taken:c,onCreatePage:l},o)),p&&(0,i.jsx)(`div`,{className:`flex`,children:(0,i.jsx)(t.Q,{icon:t.Ur,onClick:f,children:`Link another page`})})]}):(0,i.jsx)(`div`,{className:`flex`,children:(0,i.jsx)(t.Q,{icon:t.Ur,onClick:f,title:`Another of your pages that shows what happens here — usually one only your team can open`,children:`Link a page`})})}var kl=[`pageType`,`roles`,`alsoTeam`],Al=e=>Object.fromEntries(kl.filter(t=>e&&t in e).map(t=>[t,e[t]]));function jl({page:e,config:n,saving:a,onSave:o,addressTaken:s,actions:c,footer:l,isNew:u,quick:d,system:f,linkTargets:p,onCreateLinkedPage:m,products:h,onTogglePayment:g,customRoles:_,onCreateRole:v}){let y=e.type===`public`,b=ia(e.type),x=y?`pageName`:`tabName`,S=y?`pageTitle`:`tabTitle`,C=Xs[e.type],[w,T]=(0,r.useState)(()=>({...n||{}})),[E,D]=(0,r.useState)(``),[O,k]=(0,r.useState)(``),A=ps(String(w.route??``).replace(/^\/+/,``)),[j,M]=(0,r.useState)(A),N=(e,t)=>T(n=>({...n,[e]:t})),P=t=>{let r={...n||{},...w,...Al(n),...t};!d&&!f&&!r.sent&&(r.sent=mc(e,n||{})),delete r._uiKey,T(e=>({...e,...t,...r.sent&&!e.sent?{sent:r.sent}:{}})),o(r)},F=e=>{(n||{})[e]!==w[e]&&P({[e]:w[e]})},I=String(w[x]??``).trim(),L=ps(j)||ps(I),R=()=>{if(!I){D(`Give the page a name — ${C.name}`);return}if(!L){D(`Use a name with a letter or a number in it.`);return}let t=A||L;if(!A&&s(e.id,t)){D(`${Va(t)} Pick a different name or address.`);return}D(``);let r={[x]:I},i=String(w[S]??``).trim();(!i||i===String(n?.[x]??``).trim())&&(r[S]=I),!y&&!String(w.iconName??``).trim()&&(r.iconName=tc(String(w.brief??``))||Ds(I)),A||(r.route=`/`+t,M(t)),Object.keys(r).some(e=>(n||{})[e]!==r[e])?P(r):T(e=>({...e,...r}))},z=()=>{let t=ps(j);if(!j.trim()){M(A),k(``);return}if(!t){k(`Use an address with a letter or a number in it.`);return}if(M(t),t===A){k(``);return}if(s(e.id,t)){k(`${Va(t)} Pick a different address.`);return}k(``),A&&P({route:`/`+t})},B=()=>{let e=String(w.brief??``),t={brief:e},r=nc(e);if(r&&(t[S]=r),!y){let n=String(w.iconName??``).trim(),r=tc(e)||(n?``:Ds(String(w[x]??``)));r&&r!==n&&(t.iconName=r)}Object.keys(t).some(e=>(n||{})[e]!==t[e])&&P(t)},V=String(w.pageChange??``),H=Ys(V),U=ps(H.address)||A,W=()=>{if(H.address&&!ps(H.address)){D(`Use an address with a letter or a number in it.`);return}if(U!==A&&s(e.id,U)){D(`${Va(U)} Pick a different address.`);return}D(``);let t={pageChange:V};if(H.name&&(t[x]=H.name),H.heading&&(t[S]=H.heading),U!==A&&(t.route=`/`+U),!y){let e=String(w.iconName??``).trim(),n=tc(V);n&&n!==e&&(t.iconName=n)}Object.keys(t).some(e=>(n||{})[e]!==t[e])?P(t):T(e=>({...e,...t}))},G=d?A||L:U,ee=f?{...n||{},...w}:{...n||{},...w,...Al(n),...d?{}:{pageChange:H.rest,...H.name?{[x]:H.name}:{},...H.heading?{[S]:H.heading}:{}},route:G?`/`+G:``,contentKey:n?.contentKey||G||void 0},K=t.bn(),q=hl(w),J=yo(),Y=bo(w),te=oa(w),ne=Xc({id:e.id,title:e.title,path:e.path},w,h).map(e=>e.id),re=!!f&&(e.id===`contact`||e.id===`support`),X=hc(n),Z=f?!!X:!d,Q=re||!!X?.formWish||!!X?.form||Z&&!!(oc(n)||String(n?.form||``).trim()),ie=re?{label:Z?`What would you like changed about the ${e.title.toLowerCase()} form here?`:`How should the ${e.title.toLowerCase()} form work here?`,hint:Z?`Optional — in your own words. Anything you do not mention stays as it is.`:`This page has its form already — say where it sits and what happens after someone sends it.`,placeholder:Z?`Ask for their phone number too, and move it under the opening hours.`:`Build it into the page under our opening hours, and after sending say we answer within a day.`}:Z&&Q?{label:`What would you like changed about the forms?`,hint:`Optional — in your own words; anything you do not mention stays as it is. One more form is described here too.`,placeholder:ec}:{label:`What forms should the page have, and what does each ask?`,hint:`Optional — as many as you like, one after the other: what each asks, where it sits and what happens after. Every answer lands in your Inbox. Or name forms you already have.`,placeholder:C.form},ae=(0,i.jsx)(ml,{images:Ns(w),notes:String(w.imageNotes??``),onChange:e=>{if(d||f){P({images:e});return}let t=Ns(w).map(e=>e.url).filter(Boolean);P({images:e,imagesSent:Array.isArray(w.imagesSent)?w.imagesSent:t})},onNotes:e=>N(`imageNotes`,e),onBlur:()=>F(`imageNotes`)}),oe=(0,i.jsxs)(i.Fragment,{children:[l?.(ee),(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 pt-2 border-t border-[var(--panel-border)]/60`,children:[(0,i.jsx)(t.it,{saving:a}),(0,i.jsx)(`div`,{className:`flex flex-wrap items-center gap-2 ml-auto`,children:c})]})]}),se=f?(0,i.jsx)(t.dt,{label:f.ask,hint:`In your own words. Everything you do not mention stays as it is.`,value:String(w.pageWish??``),onChange:e=>N(`pageWish`,e),onBlur:()=>F(`pageWish`),placeholder:f.example}):d?(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 sm:gap-4`,children:[(0,i.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4`,children:[(0,i.jsx)(t.ft,{label:`Name`,hint:u?`The page is created the moment you leave this box.`:void 0,value:String(w[x]??``),onChange:e=>{N(x,e),E&&D(``)},onBlur:R,error:E,placeholder:C.name}),(0,i.jsx)(t.ft,{label:`Web address`,hint:u?`Made from the name unless you write one.`:void 0,prefix:`/`,value:j,onChange:e=>{M(e),O&&k(``)},onBlur:z,error:O,placeholder:ps(I)||ps(C.name)})]}),(0,i.jsx)(t.dt,{label:`What is on the page?`,hint:y?`In your own words — what it shows, what it says, what people do there. Whatever you skip, your assistant decides.`:`In your own words — what it shows, what people do there, and the icon it gets in the menu. Whatever you skip, your assistant decides.`,value:String(w.brief??``),onChange:e=>N(`brief`,e),onBlur:B,placeholder:C.describe})]}):(0,i.jsx)(t.dt,{label:`What would you like changed?`,hint:`In your own words — anything you do not mention stays as it is. To rename or move the page, add a line of its own: Name: Gallery, Address: /gallery or Heading: Our gallery.`,value:V,onChange:e=>{N(`pageChange`,e),E&&D(``)},onBlur:W,error:E,placeholder:$s}),ce={...w,...Al(n)},le=ts(ce),ue=()=>{JSON.stringify(n?.canDo||{})!==JSON.stringify(w.canDo||{})&&P({canDo:w.canDo||{}})};return(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-5`,children:[se,!f&&le.length>0&&(0,i.jsx)(gl,{title:`Who can do what`,hint:ls(ce,_),children:le.map(e=>(0,i.jsx)(t.dt,{label:ns(e,_),value:String(w.canDo?.[e]??``),onChange:t=>T(n=>({...n,canDo:{...n.canDo||{},[e]:t}})),onBlur:ue,placeholder:rs[t.ma(e)?`role`:e]},e))}),(0,i.jsx)(gl,{title:`Pictures`,hint:`Optional — upload each one; it gets a number you can refer to.`,children:ae}),(0,i.jsx)(gl,{title:`Forms`,hint:ie.hint,children:(0,i.jsx)(t.dt,{label:ie.label,value:String(w.formWish??``),onChange:e=>N(`formWish`,e),onBlur:()=>F(`formWish`),placeholder:ie.placeholder})}),(0,i.jsx)(gl,{title:`Schedules`,hint:b?`Optional — whose hours your team follows here. Weeks are kept on the Schedule screen.`:`Optional — whose working hours this page is built on, one person each. Then say what it does with them: a rota, who is in on Thursday, or a page people book time on.`,children:(0,i.jsx)(_l,{booking:q,team:b,schedules:K,onChange:e=>P({booking:e}),onAsk:e=>N(`booking`,{...q,ask:e}),onHow:e=>N(`booking`,{...q,how:e}),onBlur:()=>F(`booking`)})}),J.length>0&&(0,i.jsx)(gl,{title:`Booking links`,hint:`Optional — a booking link or booking page you already made. That exact one opens; nothing is rebuilt.`,children:(0,i.jsx)(vl,{targets:J,attached:Y,note:String(w.bookingLinksNote??``),onToggle:e=>P({bookingLinks:So(Y,e)}),onNote:e=>N(`bookingLinksNote`,e),onBlur:()=>F(`bookingLinksNote`)})}),m&&(0,i.jsx)(gl,{title:`Linked pages`,hint:`Optional — another of your pages that shows what happens here, usually one only your team can open. One copy of the sentence builds both.`,children:(0,i.jsx)(Ol,{links:te,targets:p,self:{id:e.id,contentKey:String(n?.contentKey||(d?G:``)||``)},schedules:K,taken:e=>s(`__new_linked_page__`,e),onCreatePage:m,onChange:(e,t)=>t?P({links:e}):N(`links`,e),onBlur:()=>F(`links`)})}),Mo()&&(0,i.jsx)(gl,{title:`Emails`,hint:`Optional — what this page should email, and what about. Receipts and sale alerts are switched on the payment itself, on the Payments screen.`,children:(0,i.jsx)(bl,{emails:Gc(w),audience:e.type,onChange:(e,t)=>t?P({emails:e}):N(`emails`,e),onBlur:()=>F(`emails`)})}),Fo()&&!u&&g&&(0,i.jsx)(gl,{title:`Payments`,hint:b?`Optional — tick the payments your team follows here: who paid, for what, when.`:`Optional — tick what is sold on this page. The prices and the buttons come from the Payments screen.`,children:(0,i.jsx)(yl,{products:h,ticked:ne,team:b,note:String(w.paymentNote??``),onToggle:g,onNote:e=>N(`paymentNote`,e),onBlur:()=>F(`paymentNote`)})}),oe]})}function Ml(){let{userRole:e}=t.na(),n=(0,c.useLocation)(),[a,s]=(0,r.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_pages`);if(e)return Ro(JSON.parse(e))}}catch{}return Io}),[l,u]=(0,r.useState)(()=>{try{return sessionStorage.getItem(`fbos_pages_expandedId`)||null}catch{return null}}),d=(0,r.useRef)(l),[f,p]=(0,r.useState)(null),m=e=>{let t=typeof window<`u`?window.location.origin:``;navigator.clipboard?.writeText(`${t}${e.path}`),p(e.id),setTimeout(()=>p(null),2e3)},[h,g]=(0,r.useState)(!1),[_,v]=(0,r.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_page_configs`);if(e)return JSON.parse(e)}}catch{}return{}}),[y,b]=(0,r.useState)({}),[x,S]=(0,r.useState)(()=>{try{let e=localStorage.getItem(`fbos_swr_page_briefs`);if(e)return JSON.parse(e)}catch{}return{}}),C=(0,r.useRef)(x);(0,r.useEffect)(()=>{C.current=x},[x]),(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(t.Da,`sys_configs`,`page_briefs`),e=>{let t=e.exists()?e.data():{};S(t);try{localStorage.setItem(`fbos_swr_page_briefs`,JSON.stringify(t))}catch{}},()=>{}),[]);let{schedules:w}=t._(),{pages:T}=fo();vo(go(w,T)),(0,r.useEffect)(()=>{let e=!1;return Qa().then(t=>{e||jo(t.configured)}),()=>{e=!0}},[]);let[E,D]=(0,r.useState)(()=>Da());(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.collection)(t.Da,ji),e=>{let t=[];e.forEach(e=>{e.id!==`_settings`&&t.push(Ui(e.id,e.data()))}),t.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)),Ea(t),D(t)},()=>{}),[]),Po(Y().configured);let O=wt(),k=e=>yt(e),A=async(e,n)=>{let r={...C.current[e]||{},...n};S(t=>({...t,[e]:r})),b(t=>({...t,[e]:!0}));try{await(0,o.setDoc)((0,o.doc)(t.Da,`sys_configs`,`page_briefs`),{[e]:r},{merge:!0})}catch(e){console.error(`Could not save the page answers`,e)}b(t=>({...t,[e]:!1}))},[j,M]=(0,r.useState)({}),N=e=>M(t=>({...t,[e]:(t[e]||0)+1})),[P,F]=(0,r.useState)({}),[I,L]=(0,r.useState)(null),[R,z]=(0,r.useState)(null),[B,V]=(0,r.useState)(!1),H=(0,r.useRef)(null);(0,r.useEffect)(()=>{function e(e){H.current&&!H.current.contains(e.target)&&g(!1)}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let[U,W]=(0,r.useState)(new Set),[G,ee]=(0,r.useState)(new Set),[K,q]=(0,r.useState)([]),[J,te]=(0,r.useState)([]),ne=e=>(e||[]).map(e=>typeof e==`string`?{id:e,hidden:!1}:{id:String(e.id),hidden:!!e.hidden,...e.removed?{removed:!0}:{}});(0,r.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.doc)(t.Da,`sys_configs`,`page_order`),e=>{let t=ne(e.exists()&&e.data().order||[]);q(t),W(new Set(t.filter(e=>e.hidden).map(e=>e.id)))}),n=(0,o.onSnapshot)((0,o.doc)(t.Da,`sys_configs`,`tab_order`),e=>{let t=ne(e.exists()&&e.data().order||[]);te(t),ee(new Set(t.filter(e=>e.hidden).map(e=>e.id)))});return()=>{e(),n()}},[]),(0,r.useEffect)(()=>{let e=n.pathname.split(`/pages/`)[1]?.split(`/`)[0];e&&!l&&a.some(t=>t.id===e)&&u(e)},[n.pathname,a]),(0,r.useEffect)(()=>{d.current=l;try{l?sessionStorage.setItem(`fbos_pages_expandedId`,l):sessionStorage.removeItem(`fbos_pages_expandedId`)}catch{}},[l]);let re=(0,r.useRef)(null);(0,r.useEffect)(()=>{let e=re.current;if(!e)return;try{let t=sessionStorage.getItem(`fbos_pages_scrollY`);t&&(e.scrollTop=parseInt(t,10))}catch{}let t=()=>{try{sessionStorage.setItem(`fbos_pages_scrollY`,String(e.scrollTop))}catch{}};return e.addEventListener(`scroll`,t,{passive:!0}),()=>e.removeEventListener(`scroll`,t)},[]),(0,r.useEffect)(()=>{(async()=>{try{let[e,n]=await Promise.all([(0,o.getDocs)((0,o.collection)(t.Da,`sys_pages`)),(0,o.getDocs)((0,o.collection)(t.Da,`sys_tabs`))]),r=[`home`,`drive`,`assets`,`contact`,`guide`,`templates`,`setup`,`support`,`theme`,`page_order`,`tab_order`],i=[],a={};e.forEach(e=>{if(!r.includes(e.id)){let t=e.data();i.push({id:e.id,title:t.pageName||t.title||e.id,path:t.route||`/`+e.id,type:`public`,isSystem:!1,enabled:t.enabled!==!1}),a[e.id]=t}}),n.forEach(e=>{if(!r.includes(e.id)){let n=e.data(),r=t._a(n.pageType);i.push({id:e.id,title:n.tabName||n.title||e.id,path:n.route||`/`+e.id,type:r,isSystem:!1,enabled:n.enabled!==!1}),a[e.id]=n}});let c=vs(),l={...ys(!0,!0),...ys(!1,!0)};for(let[e,t]of Object.entries(l)){if(a[e])continue;let n=i.find(e=>e.path===t.path);if(n){n.fromFile=!0;continue}i.push(t),a[e]=c[e]?.config||{}}s(e=>{let t=Ro(e.filter(e=>(e.isSystem||e.id.startsWith(`draft_`))&&e.id!==`drive`)),n=i.filter(e=>!t.some(t=>t.id===e.id)),r=[...t,...n];return typeof window<`u`&&localStorage.setItem(`fbos_swr_pages`,JSON.stringify(r)),r}),v(e=>{let t={...e,...a};return typeof window<`u`&&localStorage.setItem(`fbos_swr_page_configs`,JSON.stringify(t)),t})}catch(e){console.error(`Error loading custom pages`,e)}})()},[]);let X=async(e,n,r)=>{if(n.route&&!n.route.startsWith(`/`)&&(n.route=`/`+n.route),!String(n.route||``).replace(/^\/+/,``).trim()){v(t=>({...t,[e]:n}));return}let i=a.find(t=>t.id===e),c=r||i?.type||n.pageType||(e.startsWith(`pub_`)?`public`:void 0),l=c===`public`?`sys_pages`:`sys_tabs`;c&&c!==`public`?n.pageType=c:delete n.pageType;let f=Object.fromEntries(Object.entries(n).filter(([e,t])=>t!==void 0)),p=n.route?ms(n.route):e;f.contentKey||=p,n={...n,contentKey:f.contentKey},f.form===`__new__`&&(f.form=zc(f),f.formIsNew=!0,n={...n,form:f.form,formIsNew:!0}),b(t=>({...t,[e]:!0,[p]:!0}));try{if(p!==e&&p.trim()!==``&&p!==`draft`){try{let{deleteDoc:n}=await import(`firebase/firestore`);await n((0,o.doc)(t.Da,l,e))}catch{}await(0,o.setDoc)((0,o.doc)(t.Da,l,p),f),s(t=>t.map(t=>t.id===e?{...t,id:p,_uiKey:t._uiKey||e,path:n.route,title:n.pageName||n.tabName||n.title||t.title}:t)),d.current===e&&(u(p),window.history.replaceState(null,``,`/pages/${p}`)),v(t=>{let r={...t};return r[p]=n,delete r[e],r});let r=c===`public`,i=r?`page_order`:`tab_order`,a=r?K:J;if(!a.some(e=>e.id===p)){let n=[...a.filter(t=>t.id!==e),{id:p,hidden:!1}];try{await(0,o.setDoc)((0,o.doc)(t.Da,`sys_configs`,i),{order:n})}catch(e){console.error(`Failed to update tab order:`,e)}}}else await(0,o.setDoc)((0,o.doc)(t.Da,l,e),f),v(t=>({...t,[e]:n})),s(t=>t.map(t=>t.id===e?{...t,path:n.route||t.path,title:n.pageName||n.tabName||n.title||t.title}:t))}catch(t){console.error(`Failed to save ${e} config:`,t)}finally{setTimeout(()=>{b(t=>({...t,[e]:!1,[p]:!1}))},500)}},Z=e=>{let t=`draft_`+Math.floor(Math.random()*1e5),n={id:t,title:`New page`,path:``,type:e,isSystem:!1,enabled:!0},r=e===`public`?{route:``,pageName:``,pageTitle:``,form:``,formWish:``,brief:``,imageNotes:``}:{route:``,tabName:``,tabTitle:``,iconName:``,template:`none`,form:``,formWish:``,brief:``,imageNotes:``,pageType:e};s(e=>[...e,n]),v(e=>({...e,[t]:r})),u(t),g(!1),setTimeout(()=>{document.getElementById(`page-${t}`)?.scrollIntoView?.({behavior:`smooth`,block:`center`})},100)},Q=e=>e.id.startsWith(`draft_`);if(e!==`admin`)return(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:(0,i.jsx)(Ci,{})});let ie=async(e,n,r)=>{let i=r===`public`,c=i?`page_order`:`tab_order`,l=i?K:J,u=(i?U:G).has(e);s(a.map(t=>t.id===e?{...t,enabled:u}:t));let d=[...l],f=d.findIndex(t=>t.id===e);f===-1?d.push({id:e,hidden:!0}):d[f]={...d[f],hidden:!u},await(0,o.setDoc)((0,o.doc)(t.Da,`sys_configs`,c),{order:d})},ae=e=>!!e.fromFile&&(e.type===`public`?K:J).some(t=>t.id===e.id&&t.removed),oe=async(e,n)=>{let r=_[e.id],i=t.sa(n);if(gc(t.la(r||{pageType:e.type}),t.la(i)))return;let a=e.type;if(s(t=>t.map(t=>t.id===e.id?{...t,type:i.pageType}:t)),Q(e)){v(t=>({...t,[e.id]:{...t[e.id]||{},...i}}));return}b(t=>({...t,[e.id]:!0}));let c=Ac(r,n);(e.fromFile||r?.built)&&r&&!r.sent&&(c.sent=mc(e,r));try{await(0,o.setDoc)((0,o.doc)(t.Da,`sys_tabs`,e.id),c,{merge:!0}),v(t=>t[e.id]?{...t,[e.id]:{...t[e.id],...i,...c.sent?{sent:c.sent}:{}}}:t)}catch(t){console.error(`Failed to change who can open ${e.id}:`,t),s(t=>t.map(t=>t.id===e.id?{...t,type:a}:t))}finally{b(t=>({...t,[e.id]:!1}))}},se=(e,t)=>{if(!t){if(Q({id:e})){s(t=>t.filter(t=>t.id!==e)),v(t=>{let n={...t};return delete n[e],n}),l===e&&u(null);return}L(e)}},ce=async()=>{if(I){V(!0);try{let{deleteDoc:e,collection:n,getDocs:r,doc:i,getDoc:o,query:c,where:d}=await import(`firebase/firestore`),{ref:f,deleteObject:p}=await import(`firebase/storage`),m=a.find(e=>e.id===I),h=m?.type===`public`?`sys_pages`:`sys_tabs`;if(h===`sys_tabs`&&m){let a=_[I];if(!a)try{let e=await o(i(t.Da,`sys_tabs`,I));e.exists()&&(a=e.data())}catch{}let s=(a?.tabName||a?.pageId||I).toLowerCase().replace(/[^a-z0-9]+/g,`_`),l=t.xa(a),u=l?`role_${l}_${s}_records`:``,m=[`admin_${s}_records`,`mem_${s}_records`,`user_${s}_records`,...u?[u]:[]],h={[`admin_${s}_records`]:{prefix:`admin_files`,driveCollection:`admin_files`},[`mem_${s}_records`]:{prefix:`mem_files`,driveCollection:`mem_files`},[`user_${s}_records`]:{prefix:`user_files`,driveCollection:`user_files`},...u?{[u]:{prefix:`role_${l}_files`,driveCollection:`role_${l}_files`}}:{}},g=[];for(let i of m)g.push((async()=>{try{let a=await r(n(t.Da,i)),o=h[i],s=[];for(let i of a.docs){let a=i.data();a.recordType===`file`&&a.downloadURL&&o&&s.push((async()=>{try{let i=`${o.prefix}%2F`,s=a.downloadURL.split(i)[1]?.split(`?`)[0];s&&await p(f(t.ka,`${o.prefix}/${decodeURIComponent(s)}`)).catch(()=>{});let l=await r(c(n(t.Da,o.driveCollection),d(`downloadURL`,`==`,a.downloadURL)));await Promise.all(l.docs.map(t=>e(t.ref)))}catch(e){console.error(`Error deleting storage file:`,e)}})())}await Promise.all(s),await Promise.all(a.docs.map(t=>e(t.ref))),Ka(i)}catch(e){console.error(`Error cleaning up collection ${i}:`,e)}})());for(let i of[`admin_files`,`mem_files`,`user_files`])g.push((async()=>{try{let a=await r(c(n(t.Da,i),d(`sourceTab`,`==`,s)));await Promise.all(a.docs.map(async n=>{let r=n.data();if(r.downloadURL)try{let e=`${i}%2F`,n=r.downloadURL.split(e)[1]?.split(`?`)[0];n&&await p(f(t.ka,`${i}/${decodeURIComponent(n)}`)).catch(()=>{})}catch{}await e(n.ref)}))}catch{}})());await Promise.all(g)}await e(i(t.Da,h,I));let g=h===`sys_pages`?`page_order`:`tab_order`,v=h===`sys_pages`?K:J,{setDoc:y}=await import(`firebase/firestore`),b=m?.fromFile?[...v.filter(e=>e.id!==I),{id:I,hidden:!0,removed:!0}]:v.filter(e=>e.id!==I);await y(i(t.Da,`sys_configs`,g),{order:b}),s(e=>e.filter(e=>e.id!==I)),l===I&&u(null)}catch(e){console.error(`Error deleting page:`,e)}V(!1),L(null)}},le=async(e,n)=>{if(e.isSystem)return;let r=e.type===`public`,i=r?`page_order`:`tab_order`,s=[...r?K:J];a.filter(e=>e.type===`public`===r&&!e.isSystem&&!s.some(t=>t.id===e.id)).forEach(e=>s.push({id:e.id,hidden:!1}));let c=_s(s,e.id,n,r?`home`:void 0);if(c){r?q(c):te(c);try{await(0,o.setDoc)((0,o.doc)(t.Da,`sys_configs`,i),{order:c})}catch(e){console.error(`Failed to reorder pages:`,e)}}},ue=(e,t)=>{if(Ba(t))return!0;let n=t.replace(/[^a-zA-Z0-9_-]/g,`_`).toLowerCase();return a.some(r=>{if(r.id===e)return!1;let i=String(_[r.id]?.route??r.path??``).replace(/^\/+/,``).toLowerCase();return i!==``&&i===t||r.id===n})},de=e=>e===`admin`?Oi:e===`internal`?ki:e===`public`?Ei:Di,fe=async()=>{let e=a.find(e=>e.id===R);if(!e){z(null);return}F(t=>({...t,[e.id]:!0}));let n=_[e.id]||{};if(e.isSystem){try{await(0,o.setDoc)((0,o.doc)(t.Da,`sys_configs`,`page_briefs`),{[e.id]:(0,o.deleteField)()},{merge:!0}),S(t=>{let n={...t};return delete n[e.id],n}),N(e.id)}catch(e){console.error(`Failed to clear the page answers`,e)}F(t=>({...t,[e.id]:!1})),z(null);return}let r=kc(e,n);if(r)try{await(0,o.deleteDoc)((0,o.doc)(t.Da,e.type===`public`?`sys_pages`:`sys_tabs`,e.id)),v(t=>({...t,[e.id]:r})),s(t=>t.map(t=>t.id===e.id?{...t,fromFile:!0,title:r.pageName||r.tabName||r.pageTitle||r.tabTitle||r.title||t.title,path:r.route?r.route.startsWith(`/`)?r.route:`/`+r.route:t.path}:t))}catch(e){console.error(`Failed to reset the page`,e)}else await X(e.id,{...de(e.type),...n.contentKey?{contentKey:n.contentKey}:{}});F(t=>({...t,[e.id]:!1})),z(null)},pe=[...Ma.map(e=>({...e,config:wc(e.id,x[e.id])})),...a.filter(e=>!e.isSystem&&!Q(e)&&!ae(e)).map(e=>({id:e.id,title:e.title,path:e.path,brief:String(_[e.id]?.brief||``),config:_[e.id],audience:e.type}))],me=async e=>{let{id:t,config:n,isPublic:r}=hs(e);return await gs(e),s(r=>r.some(e=>e.id===t)?r:[...r,{id:t,title:e.name,path:n.route,type:e.type,isSystem:!1,enabled:!0}]),v(e=>({...e,[t]:n})),(r?q:te)(e=>e.some(e=>e.id===t)?e:[...e,{id:t,hidden:!1}]),t},he=Jc(E),ge=async(e,n)=>{let r=e.isSystem?wc(e.id,C.current[e.id]):_[e.id],i={id:e.id,title:e.title,path:e.path,config:r};!e.isSystem&&r&&(r.built||e.fromFile)&&!r.sent&&X(e.id,{...r,sent:mc(i,r)});let a={...n,pageIds:fa(n,i)},s=E.map(e=>e.id===n.id?a:e);Ea(s),D(s);try{await(0,o.setDoc)((0,o.doc)(t.Da,ji,n.id),{pageIds:a.pageIds},{merge:!0})}catch(e){console.error(`Could not save which pages the payment goes on`,e)}},_e=e=>{for(let t of oa(e)){if(!t.pageId)continue;let e=a.find(e=>!e.isSystem&&!Q(e)&&(e.id===t.pageId||String(_[e.id]?.contentKey||``)===t.pageId)),n=e?_[e.id]:void 0;!e||!n||n.built||e.fromFile||X(e.id,{...n,built:!0,formWish:``,imagesSent:Ms(n).map(e=>e.url),sent:mc(e,n)})}},ve=[{id:`public`,title:Bo.public,icon:t.mi,description:`On your website and in the site menu — open to everyone, signed in or not.`,filter:e=>e.type===`public`,defaultType:`public`},{id:`tabs`,title:Bo.tabs,icon:t.ei,description:`In the dashboard, behind sign-in. Who opens each one — Members, your team, admins, or a role of your own — is set on its own row.`,filter:e=>e.type!==`public`,defaultType:`user`}];return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(Ce,{children:`Your Pages`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/pages`]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsxs)(`div`,{className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background`,children:[(0,i.jsxs)(`div`,{className:`flex items-start justify-between gap-3 sm:gap-6 mb-4 pb-4 md:mb-6 md:pb-6 border-b border-[var(--panel-border)]/50 relative z-10 shrink-0 px-4 pt-4 sm:px-6 sm:pt-6 md:px-10 md:pt-10`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`div`,{className:`flex items-center min-h-[40px]`,children:(0,i.jsx)(`h2`,{className:`text-lg md:text-xl font-extrabold text-foreground tracking-tight leading-tight truncate`,children:`Your pages`})}),(0,i.jsxs)(`p`,{className:`text-[12.5px] md:text-[14px] font-medium text-foreground/60 leading-relaxed max-w-3xl`,children:[(0,i.jsx)(`span`,{className:`md:hidden`,children:`Add a page, say what goes on it, paste the sentence into your assistant.`}),(0,i.jsx)(`span`,{className:`max-md:hidden`,children:`Add a page here, say what you would like on it, and copy the sentence it writes into your assistant's chat. Renaming, reordering, hiding and deleting all happen right here.`})]})]}),(0,i.jsx)(`div`,{className:`relative z-50 shrink-0 flex items-center gap-1`,children:(0,i.jsxs)(`div`,{className:`relative`,children:[(0,i.jsx)(t.cr,{variant:`secondary`,onClick:()=>g(!h),className:`w-10 h-10 p-0 border-transparent bg-transparent hover:bg-foreground/5 rounded-xl flex items-center justify-center shrink-0 transition-colors group cursor-pointer`,title:`Add a page`,children:(0,i.jsx)(t.Ur,{className:`w-4 h-4 text-foreground/60 group-hover:text-foreground transition-colors`})}),(0,i.jsx)(t.pr,{children:h&&(0,i.jsxs)(t.fr.div,{ref:H,initial:{opacity:0,y:10,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:10,scale:.95},className:`absolute top-full mt-2 right-0 w-56 glass-popover border border-[var(--panel-border)] rounded-2xl p-2 z-50 flex flex-col gap-1`,children:[(0,i.jsx)(`span`,{className:`px-3 pt-1 pb-2 text-[10px] font-bold uppercase tracking-widest text-foreground/40`,children:`Add a page to`}),ve.map(e=>(0,i.jsx)(`button`,{onClick:()=>Z(e.defaultType),className:`text-left px-3 py-2 text-[13px] font-bold text-foreground/70 hover:text-foreground hover:bg-foreground/5 rounded-lg transition-colors cursor-pointer`,children:e.title},e.id))]})})]})})]}),(0,i.jsx)(`div`,{ref:re,className:`px-4 sm:px-6 md:px-10 pb-6 md:pb-10 flex flex-col pt-6 sm:pt-7 md:pt-9 gap-4 overflow-y-auto relative min-h-[400px]`,children:ve.map((e,n)=>{let r=a.filter(e.filter).filter(e=>!ae(e)),o=e.id===`public`?K:J,s=r.sort((e,t)=>{if(e.id===`home`)return-1;if(t.id===`home`)return 1;let n=o.findIndex(t=>t.id===e.id),r=o.findIndex(e=>e.id===t.id);return n===-1&&r===-1?0:n===-1?1:r===-1?-1:n-r}),d=e.icon,p=e=>e.type===`public`?U.has(e.id):G.has(e.id),h=s.filter(e=>!p(e)),g=s.filter(e=>p(e)),b=(n,r)=>{let o=n.isSystem?Cc[n.id]:void 0,s=l===n.id,d=Q(n),p=us({draft:d,hidden:r}),h=!n.isSystem||!!o,g=!n.isSystem&&!d&&(!!n.fromFile||!!_[n.id]?.built),b=n.isSystem?[]:pl(n,_[n.id],a,_),S=()=>{u(n.id),window.history.replaceState(null,``,`/pages/${n.id}`)},w=()=>{u(null),window.history.replaceState(null,``,`/pages`)},T=e=>{if(n.isSystem){let e=C.current[n.id]||{};A(n.id,{pageWish:``,formWish:``,imagesSent:Ms(e).map(e=>e.url),sent:mc(n,wc(n.id,e))}),_e(e),N(n.id);return}let t=_[n.id];if(t){let r=Ms(t).map(e=>e.url),i=mc(n,t),a=e===`build`?{...t,built:!0,formWish:``,imagesSent:r,sent:i}:{...t,pageChange:``,formWish:``,imagesSent:r,sent:i};v(e=>({...e,[n.id]:a})),X(n.id,a),_e(t)}N(n.id)},E=()=>{let e=_[n.id];if(!e)return;let t={...e,built:!0,formWish:``,imagesSent:Ms(e).map(e=>e.url),sent:mc(n,e)};v(e=>({...e,[n.id]:t})),X(n.id,t),N(n.id)};return(0,i.jsxs)(`div`,{id:`page-${n.id}`,onClick:()=>{h&&(s?w():S())},className:`group flex flex-col p-3.5 sm:py-4 sm:px-5 glass-panel border transition-all rounded-2xl hover:shadow-sm ${h?`cursor-pointer hover:border-accent/40`:``} ${r?`opacity-60 bg-foreground/[0.01] border-[var(--panel-border)]/50`:`border-transparent hover:border-[var(--panel-border)]`}`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between w-full gap-2 sm:gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 flex-1 min-w-0`,children:[!n.isSystem&&!d&&(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex flex-col shrink-0`,onClick:e=>e.stopPropagation(),children:[(0,i.jsx)(`button`,{type:`button`,title:`Move up`,"aria-label":`Move ${n.title} up`,onClick:()=>le(n,`up`),className:jc,children:(0,i.jsx)(t.Fi,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`button`,{type:`button`,title:`Move down`,"aria-label":`Move ${n.title} down`,onClick:()=>le(n,`down`),className:jc,children:(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5`})})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,i.jsx)(`h3`,{className:`text-[14.5px] font-bold text-foreground tracking-tight truncate`,children:n.title}),!n.isSystem&&(0,i.jsx)(Fc,{status:p}),n.fromFile&&(0,i.jsxs)(`span`,{className:Mc,title:`Your assistant wrote this one as a file. Delete hides it and gives you the sentence that removes its files.`,children:[(0,i.jsx)(t._i,{className:`w-3 h-3`}),` Written as a file`]}),b.length>0&&(0,i.jsxs)(`span`,{className:Mc,title:`This page shows what happens on ${b.join(`, `)}.`,children:[(0,i.jsx)(t.ii,{className:`w-3 h-3`}),` Linked to `,b.join(`, `)]})]}),d&&(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 truncate`,children:`Not saved yet — give it a name`})]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2 shrink-0`,children:[!n.isSystem&&n.type!==`public`&&(0,i.jsx)(`div`,{className:`max-sm:hidden min-w-0`,children:(0,i.jsx)(bs,{roles:O,picked:t.la(_[n.id]||{pageType:n.type}),busy:y[n.id],onChange:e=>oe(n,e),onCreateRole:k})}),!Lo.has(n.id)&&!d&&(0,i.jsx)(t.Q,{icon:r?t.vi:t.yi,compact:!0,title:r?`Show this page`:`Hide this page`,onClick:e=>{e.stopPropagation(),ie(n.id,n.isSystem,n.type)},children:r?`Show`:`Hide`}),h?(0,i.jsx)(`div`,{className:`p-1.5 transition-transform duration-300 text-foreground/40 shrink-0 ${s?`rotate-180`:``}`,children:(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5`})}):(0,i.jsx)(`div`,{className:`w-[24px] shrink-0`})]})]}),n.path&&s&&(0,i.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 mt-1.5`,onClick:e=>e.stopPropagation(),children:[(0,i.jsx)(c.Link,{to:n.path,className:`text-[12px] font-medium text-foreground/45 truncate underline decoration-foreground/20 underline-offset-2 hover:text-accent hover:decoration-accent transition-colors`,title:`Open this page`,children:Ic(n.path)}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>m(n),title:`Copy this link`,"aria-label":`Copy the link to ${n.title}`,className:`shrink-0 w-6 h-6 rounded-md flex items-center justify-center text-foreground/35 hover:text-foreground hover:bg-foreground/[0.07] transition-colors cursor-pointer`,children:f===n.id?(0,i.jsx)(t.zi,{className:`w-3.5 h-3.5 text-accent`}):(0,i.jsx)(t.Ti,{className:`w-3.5 h-3.5`})})]}),(0,i.jsxs)(t.pr,{children:[s&&o&&(0,i.jsx)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden mt-4 pt-4 border-t border-[var(--panel-border)]/50 pb-1`,onClick:e=>e.stopPropagation(),children:(0,i.jsx)(jl,{page:n,config:x[n.id],saving:y[n.id],system:hc(x[n.id])?{ask:o.changeAsk,example:o.changeExample}:{ask:o.ask,example:o.example},onSave:e=>A(n.id,e),addressTaken:ue,linkTargets:pe,onCreateLinkedPage:me,products:he,onTogglePayment:e=>ge(n,e),customRoles:O,onCreateRole:k,footer:e=>(0,i.jsx)(it,{compact:!0,title:o.title,prompt:Ec(n.id,e,pe),locked:!!Dc(n.id,e,pe),onCopied:()=>T(`change`)}),actions:zs(x[n.id])?(0,i.jsx)(t.Q,{icon:t.Rr,tone:`danger`,compact:!0,title:`Start again`,busy:P[n.id],onClick:()=>z(n.id),children:`Reset`}):null},`${n.id}:${j[n.id]||0}`)}),s&&!n.isSystem&&_[n.id]&&(0,i.jsxs)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden mt-4 pt-4 border-t border-[var(--panel-border)]/50 pb-1`,onClick:e=>e.stopPropagation(),children:[!d&&(0,i.jsxs)(`div`,{className:`sm:hidden flex items-center justify-between gap-3 mb-5`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-semibold text-foreground/55`,children:`Spot in the menu`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,i.jsx)(t.Q,{icon:t.Ji,title:`Move up`,onClick:()=>le(n,`up`),children:`Up`}),(0,i.jsx)(t.Q,{icon:t.Qi,title:`Move down`,onClick:()=>le(n,`down`),children:`Down`})]})]}),!n.isSystem&&n.type!==`public`&&(0,i.jsxs)(`div`,{className:`sm:hidden flex items-center justify-between gap-3 mb-5`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-semibold text-foreground/55 shrink-0`,children:`Who can open this page`}),(0,i.jsx)(bs,{roles:O,picked:t.la(_[n.id]||{pageType:n.type}),busy:y[n.id],onChange:e=>oe(n,e),onCreateRole:k})]}),(0,i.jsx)(jl,{page:n,config:_[n.id],saving:y[n.id],isNew:d,quick:!g,onSave:e=>X(n.id,e),addressTaken:ue,linkTargets:pe,onCreateLinkedPage:me,products:he,onTogglePayment:e=>ge(n,e),customRoles:O,onCreateRole:k,footer:e=>g?(0,i.jsx)(it,{compact:!0,title:`Copy this to change the page`,prompt:Sc(n,e,pe),locked:!!xc(e,n,pe),onCopied:()=>T(`change`)}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(it,{compact:!0,title:`Then copy this into your assistant’s chat`,description:d?void 0:`This one builds the page from scratch. Once it is copied, this row asks only what to change.`,prompt:Ks(n,e,pe),locked:!!js(n,e,pe),onCopied:()=>T(`build`)}),!d&&(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-1`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/50`,children:`Already built this page with your assistant?`}),(0,i.jsx)(t.Q,{icon:t.yr,compact:!0,title:`This page is built — just change it`,onClick:E,children:`Just change it`})]})]}),actions:(0,i.jsxs)(i.Fragment,{children:[Oc(_[n.id],kc(n,_[n.id])??de(n.type))&&(0,i.jsx)(t.Q,{icon:t.Rr,tone:`danger`,compact:!0,title:`Reset this page`,busy:P[n.id],onClick:()=>z(n.id),children:`Reset`}),!n.isSystem&&(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Delete this page`,onClick:()=>se(n.id,n.isSystem),children:`Delete`})]})},`${n._uiKey||n.id}:${j[n.id]||0}`)]})]})]},`${e.id}-${n._uiKey||n.id}`)};return(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex flex-col relative`,children:(0,i.jsx)(t.at,{icon:d,title:e.title,description:e.description,children:s.length===0?(0,i.jsxs)(`div`,{className:`flex flex-col items-start sm:flex-row sm:items-center gap-3 rounded-2xl border border-dashed border-[var(--panel-border)] px-5 py-4`,children:[(0,i.jsx)(t.Q,{icon:t.Ur,onClick:()=>Z(e.defaultType),children:`Add a page`}),(0,i.jsxs)(`p`,{className:`text-[12.5px] text-foreground/55 font-medium leading-relaxed`,children:[(0,i.jsx)(`span`,{className:`sm:hidden`,children:Ss}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:xs})]})]}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[h.map(e=>b(e,!1)),(0,i.jsx)(`div`,{className:`flex items-center rounded-2xl border border-dashed border-[var(--panel-border)] px-5 py-3`,children:(0,i.jsx)(t.Q,{icon:t.Ur,onClick:()=>Z(e.defaultType),children:`Add a page`})}),g.length>0&&(0,i.jsxs)(`details`,{className:`mt-4 group/details`,children:[(0,i.jsxs)(`summary`,{className:`text-[11px] font-bold uppercase tracking-wider text-foreground/40 cursor-pointer list-none flex items-center gap-2 select-none hover:text-foreground/70 transition-colors w-fit pb-1 ml-1 outline-none`,children:[(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 group-open/details:-rotate-180 transition-transform`}),`Hidden pages (`,g.length,`)`]}),(0,i.jsx)(`div`,{className:`flex flex-col gap-4 mt-4`,children:g.map(e=>b(e,!0))})]})]})})},e.id)})})]})]}),(0,i.jsx)(Ve,{isOpen:!!I,onCancel:()=>L(null),onConfirm:ce,title:`Delete this page?`,message:`The page and everything saved on it will be gone for good. This cannot be undone.`,confirmText:`Delete page`,isProcessing:B}),(0,i.jsx)(Ve,{isOpen:!!R,onCancel:()=>z(null),onConfirm:fe,title:a.find(e=>e.id===R)?.isSystem?`Start this page again?`:`Reset this page?`,message:(()=>{let e=a.find(e=>e.id===R);return e?.isSystem?`What you have written about this page is cleared, and the pictures you added with it, so you can describe it again from scratch. The page itself stays as your assistant last built it.`:e&&kc(e,_[e.id])?`Its settings go back to how your assistant built the page, and what you wrote about it is cleared. What people have saved on the page is kept.`:`Its name, heading, web address, icon and form go back to how they started, and what you wrote about it is cleared. What people have saved on the page is kept.`})(),confirmText:a.find(e=>e.id===R)?.isSystem?`Start again`:`Reset page`,isProcessing:!!R&&!!P[R]})]})}var Nl=new Set([`contact`,`support`]),Pl=[{value:`text`,label:`Short text`},{value:`textarea`,label:`Long text`},{value:`email`,label:`Email`},{value:`tel`,label:`Phone`},{value:`number`,label:`Number`},{value:`date`,label:`Date`},{value:`currency`,label:`Money`},{value:`checkbox`,label:`Yes-no`},{value:`select`,label:`Choose one`},{value:`file`,label:`File upload`}],Fl={value:`schedule`,label:`A time to book`},Il={age:`Age`},Ll=e=>[...Pl,Fl].find(t=>t.value===e)?.label||Il[e||``]||`Short text`,Rl=(e,t=!1)=>{let n=t||e===`schedule`?[...Pl,Fl]:Pl;return n.some(t=>t.value===e)||!e?n:[...n,{value:e,label:Ll(e)}]},zl=(e,n)=>{let r=t.Gn(e).map(e=>{let r=n.find(t=>t.id===e);return r?t.In(r):``}).filter(Boolean);return r.length?r.join(`, `):`nothing picked yet`},Bl={public:`Anyone`,private:`Signed-in users`},Vl=e=>(e||``).toLowerCase().trim().replace(/[^a-z0-9]+/g,`_`).replace(/^_+|_+$/g,``),Hl=(e,t)=>{if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}_${n}`);)n++;return`${e}_${n}`},Ul=(e,t,n)=>{if(!(!e.name||e.name===Vl(e.label||``)))return e.name;let r=Vl(t);return r?Hl(r,n.filter(t=>t!==e).map(e=>e.name)):``},Wl=()=>({name:``,type:`text`,label:``,placeholder:``,required:!1}),Gl={firstForm:`Forms are made with their pages — add a page on the Pages screen and pick A new form made for this page. Every form then shows up here.`};function Kl({choices:e,onChange:n}){return(0,i.jsx)(t.Z,{label:`Choices`,hint:`The options people pick from.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.length===0&&(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/40 font-medium px-1`,children:`No choices yet — add the first one.`}),e.map((r,a)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`text`,value:r,"aria-label":`Choice ${a+1}`,placeholder:`e.g. Under 1,000`,onChange:t=>n(e.map((e,n)=>n===a?t.target.value:e)),className:t.et}),(0,i.jsx)(t.Q,{icon:t._r,tone:`danger`,title:`Remove choice ${a+1}`,onClick:()=>n(e.filter((e,t)=>t!==a)),children:`Remove`})]},a)),(0,i.jsx)(`div`,{children:(0,i.jsx)(t.Q,{icon:t.Ur,onClick:()=>n([...e,``]),children:`Add choice`})})]})})}function ql(){let{userRole:e}=t.na(),n=(0,c.useNavigate)(),a=t.Na(),s=()=>{let e=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},n={...t.dr,contact:a?.defaultConfigs?.contactForm||t.dr.contact,support:a?.defaultConfigs?.supportForm||t.dr.support};for(let[t,r]of Object.entries(e))n[t]=r;return n},[l,u]=(0,r.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_forms`);if(e)return JSON.parse(e)}let e={...t.dr,contact:a?.defaultConfigs?.contactForm||t.dr.contact,support:a?.defaultConfigs?.supportForm||t.dr.support},n=(typeof window<`u`?window.__FBOS_FORMS__:null)||{};for(let[t,r]of Object.entries(n))e[t]=r;let r={};for(let[t,n]of Object.entries(e)){let e=JSON.parse(JSON.stringify(n));e._uiKey=Math.random().toString(36).substring(7),r[t]=e}return r}catch{return{}}}),[d,f]=(0,r.useState)(()=>!(typeof window<`u`&&localStorage.getItem(`fbos_swr_forms`))),[p,m]=(0,r.useState)({}),[h,g]=(0,r.useState)(null),[_,v]=(0,r.useState)(new Set),y=Be(),{schedules:b}=t._(),[x,S]=(0,r.useState)({}),[C,w]=(0,r.useState)(null),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)({}),k=(0,r.useRef)({}),A=(e,t)=>{k.current={...k.current,[e]:t},O(k.current)};(0,r.useEffect)(()=>{j()},[]);let j=async()=>{try{f(!0);let e=await(0,o.getDocs)((0,o.collection)(t.Da,`sys_forms`)),n={},r=new Set;e.forEach(e=>{if(e.id!==`pubForm`&&e.id!==`userForm`){let t=e.data();t._uiKey=l[e.id]?._uiKey||t._uiKey||Math.random().toString(36).substring(7),n[e.id]=t,r.add(e.id)}}),v(r);try{await(0,o.deleteDoc)((0,o.doc)(t.Da,`sys_forms`,`pubForm`)),await(0,o.deleteDoc)((0,o.doc)(t.Da,`sys_forms`,`userForm`))}catch{}let i=s();for(let[e,t]of Object.entries(i))if(!n[e]){let r={...t};r._uiKey=l[e]?._uiKey||Math.random().toString(36).substring(7),n[e]=r}else if(n[e]._uiKey=l[e]?._uiKey||n[e]._uiKey||Math.random().toString(36).substring(7),!n[e].fields||n[e].fields.length===0){let t=i[e];n[e].fields=t.fields||[]}let a={};for(let e of Object.keys(i))n[e]&&(a[e]=n[e]);for(let e of Object.keys(n))a[e]||(a[e]=n[e]);let c=window.location.pathname.split(`/forms/`)[1]?.split(`/`)[0];c&&a[c]&&S({[c]:!0}),k.current={},O({}),u(a),typeof window<`u`&&localStorage.setItem(`fbos_swr_forms`,JSON.stringify(a))}catch(e){console.error(`Failed to load forms:`,e)}finally{f(!1)}},M=async(e,n)=>{let r={...n};l[e]?._uiKey&&(r._uiKey=l[e]._uiKey),delete r.submitPage,e===`contact`?(r.systemName=`contact`,r.formType=`public`):e===`support`&&(r.systemName=`support`,r.formType=`private`);let i=r.systemName||e;if(i!==e&&i.trim()!==``){u(t=>{let n={};for(let a of Object.keys(t))a===e?n[i]=r:n[a]=t[a];return n}),x[e]&&S(t=>{let n={};for(let r of Object.keys(t))r===e?n[i]=t[r]:n[r]=t[r];return n}),m(e=>({...e,[i]:!0}));try{await(0,o.setDoc)((0,o.doc)(t.Da,`sys_forms`,i),r),await(0,o.deleteDoc)((0,o.doc)(t.Da,`sys_forms`,e)),localStorage.setItem(`fbos_custom_form_${i}`,`true`),localStorage.removeItem(`fbos_custom_form_${e}`),localStorage.setItem(`fbos_form_${i}`,JSON.stringify(r)),localStorage.removeItem(`fbos_form_${e}`)}catch(e){console.error(`Failed to migrate form map ID:`,e)}finally{setTimeout(()=>{m(e=>({...e,[i]:!1}))},500)}}else{u(t=>({...t,[e]:r})),m(t=>({...t,[e]:!0}));try{await(0,o.setDoc)((0,o.doc)(t.Da,`sys_forms`,e),r),localStorage.setItem(`fbos_custom_form_${e}`,`true`),localStorage.setItem(`fbos_form_${e}`,JSON.stringify(r))}catch(e){console.error(`Failed to save form:`,e)}finally{setTimeout(()=>{m(t=>({...t,[e]:!1}))},500)}}},N=(e,t,n)=>A(e,{...t,...n}),P=(e,t,n)=>{let r={...t,...n};A(e,r),M(e,r)},F=e=>{let t=k.current[e];t&&M(e,t)},I=(e,t,n)=>P(e,t,{fields:n}),L=async e=>{if(!Nl.has(e)){E(!0);try{await(0,o.deleteDoc)((0,o.doc)(t.Da,`sys_forms`,e)),u(t=>{let n={...t};return delete n[e],n}),n(`/forms`)}catch(e){console.error(`Failed to delete form`,e)}finally{E(!1),w(null)}}},R=async e=>{if(!_.has(e)){w(null);return}E(!0);let n=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},r=Nl.has(e)||!!n[e]||!!a?.defaultConfigs?.[e]||!!a?.defaultConfigs?.[`${e}Form`];try{r?(m(t=>({...t,[e]:!0})),await(0,o.deleteDoc)((0,o.doc)(t.Da,`sys_forms`,e)),localStorage.removeItem(`fbos_form_${e}`),localStorage.removeItem(`fbos_custom_form_${e}`),await j(),setTimeout(()=>m(t=>({...t,[e]:!1})),500)):await M(e,s().contact||s().support)}catch(e){console.error(`Reset failed:`,e)}finally{E(!1),w(null)}};if(e!==`admin`)return(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:(0,i.jsx)(Ci,{})});let z=e=>{S(t=>{let n={...t,[e]:!t[e]};if(n[e])window.history.replaceState(null,``,`/forms/${e}`);else{let e=Object.keys(n).filter(e=>n[e]);e.length>0?window.history.replaceState(null,``,`/forms/${e[0]}`):window.history.replaceState(null,``,`/forms`)}return n})},B=Object.keys(x).find(e=>x[e]),V=(e,n,r,a,o)=>{let s=(t,r)=>{let i=o.map((e,n)=>n===a?{...e,...t}:e);r?I(e,n,i):N(e,n,{fields:i})},c=t=>{let i=t===`schedule`?{type:t,look:`compact`,schedules:[]}:t===`select`?{type:t,options:r.options||[]}:{type:t};I(e,n,o.map((e,n)=>{if(n!==a)return e;let r={...e,...i};return t!==`schedule`&&(delete r.members,delete r.schedules,delete r.look,delete r.together),r}))},l=t=>{let r=a+t;if(r<0||r>=o.length)return;let i=[...o];[i[a],i[r]]=[i[r],i[a]],I(e,n,i)},u=r.type!==`checkbox`&&r.type!==`select`&&r.type!==`date`&&r.type!==`file`&&r.type!==`schedule`;return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)] p-4 sm:p-5 flex flex-col gap-5`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-2 flex-wrap`,children:[(0,i.jsxs)(`span`,{className:`text-[13px] font-bold text-foreground`,children:[`Question `,a+1,r.type===`schedule`&&(0,i.jsxs)(`span`,{className:`font-medium text-foreground/50`,children:[` · A time to book — `,zl(r,b)]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,i.jsx)(t.Q,{icon:t.Ji,disabled:a===0,title:`Move up`,onClick:()=>l(-1),children:`Up`}),(0,i.jsx)(t.Q,{icon:t.Qi,disabled:a===o.length-1,title:`Move down`,onClick:()=>l(1),children:`Down`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,title:`Remove question ${a+1}`,onClick:()=>I(e,n,o.filter((e,t)=>t!==a)),children:`Remove`})]})]}),(0,i.jsx)(t.ft,{label:`Question`,hint:`What you are asking for, in the words the person will read.`,value:r.label||``,placeholder:`e.g. What is your budget?`,onChange:e=>s({label:e,name:Ul(r,e,o)},!1),onBlur:()=>F(e)}),(0,i.jsx)(t.ct,{label:`Kind of answer`,hint:`Sets the box people type into and what counts as a valid answer.`,value:r.type||`text`,options:Rl(r.type,b.length>0),allowEmpty:!1,onChange:c}),(0,i.jsx)(t.mt,{label:`Required`,hint:`On means the form cannot be sent until this is answered.`,hintWideOnly:!0,enabled:!!r.required,onChange:e=>s({required:e},!0)}),r.type===`select`&&(0,i.jsx)(Kl,{choices:r.options||[],onChange:e=>s({options:e},!0)}),r.type===`schedule`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.Z,{label:`What can be booked`,hint:`Pick a schedule from the Schedule screen — one per person. Visitors see the free times in their own time zone; nobody can take a time twice.`,error:t.Gn(r).length?void 0:`Pick at least one schedule`,children:(0,i.jsx)(ko,{schedules:b,selected:t.Gn(r),onPick:e=>{s({schedules:t.An(t.Gn(r),e,b)},!0)}})}),t.Yn(b.filter(e=>t.Gn(r).includes(e.id)))&&(0,i.jsx)(t.ct,{label:`Who is the booking with?`,hint:`One of them: the visitor picks a person, then one of that person's own times. All of them: only the times every one of them is free are offered, and one booking goes in all their calendars. Both: the visitor chooses.`,value:t.Wn(r),options:t.yt,allowEmpty:!1,onChange:e=>s({party:t.Wn({party:e}),together:e===`all`},!0)}),(0,i.jsx)(t.ct,{label:`How should the booking look?`,value:r.look||`compact`,options:t._t,allowEmpty:!1,onChange:e=>s({look:e===`calendar`?`calendar`:`compact`},!0)})]}),r.type===`file`&&(0,i.jsx)(t.ft,{label:`Words on the upload box`,hint:`What the box says before anything is picked. People can attach several files. Leave it empty for “Attach files”.`,value:r.placeholder||``,placeholder:`Attach files`,onChange:e=>s({placeholder:e},!1),onBlur:()=>F(e)}),r.type===`currency`&&(0,i.jsx)(t.ft,{label:`Currency symbol`,hint:`Shown inside the box, before the amount.`,value:r.currencySymbol||``,placeholder:`$`,onChange:e=>s({currencySymbol:e},!1),onBlur:()=>F(e)}),u&&(0,i.jsx)(t.ft,{label:`Example answer`,hint:`Faint grey text inside the box, to show people what you expect.`,value:r.placeholder||``,placeholder:`e.g. jane@example.com`,onChange:e=>s({placeholder:e},!1),onBlur:()=>F(e)})]},a)},H=(e,n)=>{let r=D[e]||n,a=Nl.has(e),o=r.formType||`public`,s=r.fields||[],c=_.has(e);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsxs)(t.at,{icon:t.Tr,title:`Basics`,description:`What people see at the top of this form and on its button.`,children:[(0,i.jsx)(t.ft,{label:`Form name`,hint:`The heading at the top of the form.`,value:r.title||``,placeholder:`e.g. Get in touch`,onChange:t=>N(e,r,{title:t}),onBlur:()=>F(e)}),(0,i.jsx)(t.ft,{label:`Button text`,hint:`The words on the button that sends the form.`,value:r.buttonName||r.submitText||``,placeholder:`e.g. Send message`,onChange:t=>N(e,r,{buttonName:t,submitText:t}),onBlur:()=>F(e)})]}),(0,i.jsx)(t.at,{icon:t.xr,title:`Who it is for`,description:`Who can fill this in, and where their answers land.`,children:(0,i.jsx)(t.ct,{label:`Who it is for`,hint:`Who can fill this in follows the page this form was made for, so it cannot change here. Changing it after answers arrive would file new answers under the wrong list in your Inbox.`,value:o,allowEmpty:!1,disabled:!0,options:[{value:`public`,label:`Anyone`},{value:`private`,label:`Signed-in users`}],onChange:t=>P(e,r,{formType:t})})}),(0,i.jsx)(t.at,{icon:t.Ir,title:`After sending`,description:`What happens the moment someone sends this form.`,children:(0,i.jsx)(t.ft,{label:`Where to send them next`,hint:`Leave this empty to show a thank-you message instead. Or give a web address, like /pricing, to take them there.`,value:r.redirectTo||``,placeholder:`/pricing`,onChange:t=>N(e,r,{redirectTo:t}),onBlur:()=>F(e)})}),(0,i.jsxs)(t.at,{icon:t.ni,title:`Questions`,description:`Everything this form asks for, in the order people answer it.`,actions:({open:n})=>(0,i.jsx)(t.Q,{icon:t.Ur,compact:!0,title:`Add a question`,onClick:()=>{n(),I(e,r,[...s,Wl()])},children:`Add question`}),children:[s.length===0?(0,i.jsx)(`p`,{className:`text-[12.5px] text-foreground/55 font-medium leading-relaxed`,children:`No questions yet. Add the first one with the button above.`}):s.map((t,n)=>V(e,r,t,n,s)),s.length>0&&(0,i.jsx)(`div`,{className:`flex justify-start`,children:(0,i.jsx)(t.Q,{icon:t.Ur,onClick:()=>I(e,r,[...s,Wl()]),children:`Add question`})})]}),(c||!a)&&(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 pt-1`,children:[c&&(0,i.jsx)(t.Q,{icon:t.Rr,tone:`danger`,compact:!0,title:`Reset this form`,onClick:()=>w({kind:`reset`,id:e}),children:`Reset this form`}),!a&&(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Delete this form`,onClick:()=>w({kind:`delete`,id:e}),children:`Delete this form`})]})]})};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(Ce,{children:`Forms`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/forms`,B?`/${B}`:``]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsxs)(`div`,{className:`flex flex-col glass-panel border-y sm:border border-[var(--panel-border)] rounded-none sm:rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background -mx-4 sm:mx-0`,children:[(0,i.jsx)(`div`,{className:`flex items-start justify-between gap-3 sm:gap-6 mb-4 pb-4 md:mb-4 md:pb-5 border-b border-[var(--panel-border)]/50 relative z-10 shrink-0 px-4 pt-5 sm:px-6 sm:pt-6 md:px-10 md:pt-8 bg-background/50`,children:(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-lg md:text-xl font-extrabold text-foreground tracking-tight leading-tight md:leading-7`,children:`Your forms`}),(0,i.jsxs)(`p`,{className:`text-[12.5px] md:text-[14px] font-medium text-foreground/60 mt-1 md:mt-2 leading-relaxed`,children:[(0,i.jsx)(`span`,{className:`md:hidden`,children:`Look a form over and touch it up. Answers arrive in your Inbox.`}),(0,i.jsx)(`span`,{className:`max-md:hidden`,children:`Look a form over and touch it up — its name, button text and questions. New forms are made on the Pages screen, with their page. Answers arrive in your Inbox.`})]})]})}),(0,i.jsx)(`div`,{className:`p-4 sm:p-6 md:px-8 md:pb-8 md:pt-3 flex flex-col gap-4 overflow-y-auto`,children:Object.keys(l).length===0&&!d?(0,i.jsx)(`div`,{className:`flex flex-col gap-4`,children:(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center gap-3 p-10 glass-panel rounded-3xl border border-[var(--panel-border)] border-dashed`,children:[(0,i.jsx)(t.Br,{className:`w-6 h-6 text-foreground/40`}),(0,i.jsx)(`p`,{className:`text-[13px] font-bold text-foreground/60`,children:`You have no forms yet.`}),(0,i.jsx)(`p`,{className:`text-[12.5px] text-foreground/55 font-medium leading-relaxed text-center max-w-md`,children:Gl.firstForm})]})}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsx)(t.pr,{children:Object.entries(l).map(([e,n])=>{let r=D[e]||n,a=x[e],o=p[e],s=(r.fields||[]).length;return(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},exit:{opacity:0,y:-12},transition:{duration:.35,ease:`easeOut`},onClick:()=>z(e),className:`group flex flex-col p-3 px-4 glass-panel border transition-all rounded-2xl hover:shadow-sm cursor-pointer hover:border-accent/40 ${a?`border-[var(--panel-border)] bg-background/50`:`border-transparent hover:border-[var(--panel-border)]`} flex-shrink-0 ${r.enabled===!1?`opacity-40 grayscale bg-foreground/[0.01] border-[var(--panel-border)]/50`:``}`,children:[(0,i.jsxs)(`div`,{className:`flex flex-row justify-between w-full gap-2 ${y?`items-start`:`items-center`}`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-1 min-w-0 flex-1 pr-2 sm:pr-4`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`h3`,{className:`text-[14px] font-bold text-foreground break-words ml-1 leading-snug`,children:r.title||`Untitled form`}),o&&(0,i.jsx)(t.ti,{className:`w-3 h-3 animate-spin text-accent ml-2 shrink-0`})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 mt-1.5 ml-1`,children:[(0,i.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-[11px] font-semibold px-2.5 py-[3px] rounded-full border shrink-0 ${r.formType===`private`?`text-blue-500 border-blue-500/25 bg-blue-500/[0.07]`:`text-emerald-500 border-emerald-500/25 bg-emerald-500/[0.07]`}`,children:[(0,i.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full shrink-0 ${r.formType===`private`?`bg-blue-500`:`bg-emerald-500`}`}),Bl[r.formType||`public`]]}),(0,i.jsx)(`span`,{className:`max-sm:hidden text-[11px] font-medium text-foreground/45`,children:s===1?`1 question`:`${s} questions`})]})]}),y?(0,i.jsxs)(`div`,{className:`flex items-center gap-0.5 shrink-0 -mt-0.5 -mr-1.5`,children:[(0,i.jsx)(`button`,{type:`button`,title:`Preview this form`,"aria-label":`Preview this form`,onClick:e=>{e.stopPropagation(),g(r)},className:`w-8 h-8 flex items-center justify-center rounded-lg text-foreground/40 hover:text-accent hover:bg-foreground/5 transition-colors cursor-pointer`,children:(0,i.jsx)(t.vi,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{type:`button`,title:a?`Close this form`:`Open this form`,"aria-label":a?`Close this form`:`Open this form`,"aria-expanded":a,onClick:t=>{t.stopPropagation(),z(e)},className:`w-8 h-8 flex items-center justify-center rounded-lg text-foreground/40 hover:text-accent hover:bg-foreground/5 transition-colors cursor-pointer`,children:(0,i.jsx)(t.Ri,{className:`w-4 h-4 transition-transform duration-300 ${a?`rotate-180`:``}`})})]}):(0,i.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,i.jsx)(t.Q,{icon:t.vi,title:`Preview this form`,onClick:e=>{e.stopPropagation(),g(r)},children:`Preview`}),(0,i.jsx)(`button`,{type:`button`,title:a?`Close this form`:`Open this form`,"aria-label":a?`Close this form`:`Open this form`,"aria-expanded":a,onClick:t=>{t.stopPropagation(),z(e)},className:`w-9 h-9 flex items-center justify-center rounded-[var(--btn-radius,0.75rem)] text-foreground/40 hover:text-accent hover:bg-foreground/[0.06] transition-colors cursor-pointer`,children:(0,i.jsx)(t.Ri,{className:`w-4 h-4 transition-transform duration-300 ${a?`rotate-180`:``}`})})]})]}),(0,i.jsx)(t.pr,{children:a&&(0,i.jsx)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden mt-4 pt-4 border-t border-[var(--panel-border)]/50`,onClick:e=>e.stopPropagation(),children:H(e,n)})})]},n._uiKey||e)})}),d&&(0,i.jsxs)(`div`,{className:`flex items-center justify-center gap-3 p-6 glass-panel rounded-2xl border border-[var(--panel-border)]/40 bg-foreground/[0.01] mt-2 animate-pulse`,children:[(0,i.jsx)(t.ti,{className:`w-4 h-4 animate-spin text-accent`}),(0,i.jsx)(`span`,{className:`text-[12px] font-bold text-foreground/50 tracking-wider uppercase select-none`,children:`Loading your forms`})]})]})})]})]}),(0,i.jsx)(Ve,{isOpen:!!C,onCancel:()=>w(null),onConfirm:()=>{C&&(C.kind===`delete`?L(C.id):R(C.id))},title:C?.kind===`reset`?`Reset this form`:`Delete this form`,message:C?.kind===`reset`?`Undo every change made to ${l[C.id]?.title||C.id} and put it back the way it shipped. Answers already collected are kept.`:`Permanently delete ${C?l[C.id]?.title||C.id:``}. This cannot be undone. Answers already collected are kept.`,confirmText:C?.kind===`reset`?`Reset form`:`Delete form`,isProcessing:T}),h&&(0,i.jsx)(t.t,{formConfig:h,onClose:()=>g(null)})]})}function Jl({product:e,live:n,open:r,onToggle:a,onChange:o,onProceed:s}){let c=t=>o({...e,...t});if(!qi(e,n))return(0,i.jsx)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] opacity-50`,"aria-disabled":`true`,children:(0,i.jsxs)(`div`,{className:`w-full flex items-center justify-between gap-3 px-4 py-3`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/60 truncate`,children:Xi(e)}),(0,i.jsx)(t.lt,{state:`off`,label:`Finish it above first`})]})});let l=la(e),u=e.kind===`subscription`;return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:a,"aria-expanded":r,className:`w-full flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Xi(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(t.lt,{state:l?`off`:`saved`,label:l?`Question left`:`Described`}),(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${r?`rotate-180`:``}`})]})]}),r&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.dt,{label:`How will this payment work?`,hint:u?`Start to finish, in your own words — what someone does, pays, and gets. Worth saying if you care: what they tell you before paying (never their email — Stripe asks for that), what each plan unlocks, and what happens the moment they subscribe. Whatever you skip, your assistant decides.`:`Start to finish, in your own words — what someone does, pays, and gets. Worth saying if you care: what they tell you before paying (never their email — Stripe asks for that) and what happens after they pay. Whatever you skip, your assistant decides.`,value:e.how,onChange:e=>c({how:e}),placeholder:u?`People pick a plan and pay, and their member area unlocks the same minute — Basic gets the videos, Pro gets the videos and a monthly call.`:`People pick a time, tell me their phone number and what they need, pay, and the booking is theirs — it appears under Bookings with the session they chose.`}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5`,children:[(0,i.jsx)(t.mt,{label:`Email the buyer a confirmation`,hint:`Needs email set up on this screen.`,hintWideOnly:!0,enabled:e.emailReceipt,onChange:e=>c({emailReceipt:e})}),(0,i.jsx)(t.mt,{label:`Email me when someone buys`,hint:`Needs email set up on this screen.`,hintWideOnly:!0,enabled:e.notifyOwner,onChange:e=>c({notifyOwner:e})})]}),(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:[l?(0,i.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:l}):(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Described — press Proceed to say where it goes.`}),l?(0,i.jsx)(`span`,{}):(0,i.jsx)(t.Q,{icon:t.Xi,onClick:s,children:`Proceed`})]})]})]})}function Yl({products:e,live:n,openId:r,onToggle:a,onChange:o,onProceed:s}){return e===null?(0,i.jsx)(`p`,{className:t.$,children:`Loading your payments…`}):e.length===0?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Nothing here yet. Describe what you sell in the card above — each payment you add appears here with one question: how it works, start to finish.`}):(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.map(e=>(0,i.jsx)(Jl,{product:e,live:n,open:r===e.id,onToggle:()=>a(e.id),onChange:o,onProceed:()=>s(e.id)},e.id))})}var Xl=[{audience:`public`,label:`Pages for anyone`},{audience:`user`,label:`Pages for signed-in users`},{audience:`internal`,label:`Pages for your team`},{audience:`admin`,label:`Pages for admins only`}];function Zl({row:e,on:n,onToggle:r}){return(0,i.jsxs)(`button`,{type:`button`,role:`checkbox`,"aria-checked":n,"aria-label":`${e.title} — ${e.path}`,onClick:r,className:`w-full flex items-center gap-2.5 px-2 py-2 text-left cursor-pointer rounded-xl hover:bg-foreground/[0.04] transition-colors`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${n?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:n&&(0,i.jsx)(t.zi,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate min-w-0`,children:e.title}),(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/40 truncate shrink-0`,children:e.path})]})}function Ql({product:e,pageRows:n,live:r,open:a,onToggle:o,onChange:s}){let l=t=>s({...e,...t});if(!(qi(e,r)&&!la(e)))return(0,i.jsx)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] opacity-50`,"aria-disabled":`true`,children:(0,i.jsxs)(`div`,{className:`w-full flex items-center justify-between gap-3 px-4 py-3`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/60 truncate`,children:Xi(e)}),(0,i.jsx)(t.lt,{state:`off`,label:`Describe it above first`})]})});let u=pa(e,n);return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:o,"aria-expanded":a,className:`w-full flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Xi(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(t.lt,{state:u?`off`:`saved`,label:u?`Where does it go?`:`Placed`}),(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${a?`rotate-180`:``}`})]})]}),a&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.Z,{label:`Which pages does it go on?`,hint:`Tick every page this payment touches — where it sells, and where your team sees what it sold.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[Xl.map(t=>{let r=n.filter(e=>(e.audience||`public`)===t.audience);return r.length?(0,i.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-widest text-foreground/40 px-1`,children:t.label}),(0,i.jsx)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60 px-2 py-1.5`,children:r.map(t=>(0,i.jsx)(Zl,{row:t,on:da(e,t),onToggle:()=>l({pageIds:fa(e,t)})},t.id))})]},t.audience):null}),(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Pages you make on the`,` `,(0,i.jsx)(c.Link,{to:`/pages`,className:`text-accent font-bold hover:underline`,children:`Pages screen`}),` `,`appear here on their own.`]})]})}),(0,i.jsx)(t.dt,{label:`What should appear there?`,hint:`Optional — where the button goes, what surrounds it, what your team sees. Or a page to add, and who will see it: anyone, signed-in users, your team, or admins only. Whatever you skip, your assistant decides.`,value:e.pagesNote,onChange:e=>l({pagesNote:e}),placeholder:`On the home page, a Book button under each call. On the Sales page, every booking as a row — who, what, when.`}),(0,i.jsx)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:u?(0,i.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:u}):(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Placed — the request under these carries it.`})})]})]})}function $l({products:e,pageRows:n,live:r,openId:a,onToggle:o,onChange:s}){if(e===null||n===null)return(0,i.jsx)(`p`,{className:t.$,children:`Loading your pages…`});if(e.length===0)return(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Nothing here yet. Each payment you describe above appears here with one question: which pages it goes on.`});let c=ma(e,n,r),l=c?``:Ca(e,n,r);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.map(e=>(0,i.jsx)(Ql,{product:e,pageRows:n,live:r,open:a===e.id,onToggle:()=>o(e.id),onChange:s},e.id))}),(0,i.jsx)(it,{title:`Copy this to wire everything in`,prompt:l,locked:l===``}),c?(0,i.jsx)(`span`,{className:t.$,children:c}):(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Ready — copy the request above into your assistant’s chat. Change any page later from its row on the Pages screen.`})]})}function eu({title:e,path:n,hint:a}){let[o,s]=(0,r.useState)(!1),c=t.Pt(n);return(0,i.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-2.5 rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)]`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/80 truncate`,children:e}),(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 truncate`,children:a||c})]}),(0,i.jsx)(t.Q,{icon:o?t.zi:t.Ti,compact:!0,title:`Copy the link to ${e}`,onClick:()=>{try{navigator.clipboard?.writeText(c)?.catch(()=>{})}catch{}s(!0),setTimeout(()=>s(!1),1500)},children:o?`Copied`:`Copy link`})]})}var tu=e=>ps(`pay-${Yi(e)}`)||`pay-${e.id}`,nu=e=>{let t=Li(e).map(e=>e.amount.trim()).filter(Boolean).join(` + `);return`${Yi(e)}${t?` — ${t}`:``}`};function ru(e,t,n){return[Ks(t,n),`This page is the page of my payment link for ${Yi(e)} — everyone I send ${t.path} to lands here and pays here.`,...ra(e,t.path)].join(`
|
|
28
|
-
`)}function iu({product:e,open:n,onToggle:a,onChange:o,onRemove:s,onCustomise:c}){let[l,u]=(0,r.useState)(!1),[d,f]=(0,r.useState)(!1),[p,m]=(0,r.useState)(``),[h,g]=(0,r.useState)(``),_=e.customPath.trim(),v=_?_.startsWith(`/`)?_:`/${_}`:t.kn(e.id);return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 pr-3`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:a,"aria-expanded":n,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:nu(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(t.lt,{state:_?`saved`:`off`,label:_?`Your own page`:`Ready-made page`}),(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${n?`rotate-180`:``}`})]})]}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove the link to ${Yi(e)}`,onClick:()=>u(!0),children:`Remove`})]}),(0,i.jsx)(Ve,{isOpen:l,title:`Remove the link to ${Yi(e)}?`,message:`Its link stops working, and it leaves What you sell and every schedule it was attached to.`,confirmText:`Yes, remove it`,cancelText:`Keep it`,onCancel:()=>u(!1),onConfirm:()=>{u(!1),s()}}),n&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.Z,{label:`The link`,hint:`Send it to anyone. The page wears your theme and your app's name.`,children:(0,i.jsx)(eu,{title:Yi(e),path:v})}),(0,i.jsx)(t.ft,{label:`What is it called?`,value:Li(e)[0]?.name||``,onChange:t=>o({...e,items:[{...Li(e)[0]||{amount:``},name:t},...Li(e).slice(1)]}),placeholder:`A one-hour session`}),(0,i.jsx)(t.dt,{label:`A line or two about it`,hint:`Optional — what the buyer gets. Shown on the page.`,value:e.description,onChange:t=>o({...e,description:t}),placeholder:`One hour together on whatever you are stuck on.`}),(0,i.jsx)(t.ft,{label:`The price`,value:Li(e)[0]?.amount||``,onChange:t=>o({...e,items:[{...Li(e)[0]||{name:``},amount:t},...Li(e).slice(1)]}),placeholder:`25`,error:Li(e)[0]?.amount.trim()&&Ri(Li(e)[0].amount)===null?`Just a number, like 25.`:void 0}),!_&&!d&&!p&&(0,i.jsx)(t.Q,{icon:t.yr,onClick:()=>f(!0),children:`Customise this page`}),(d||p)&&(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-4`,children:[(0,i.jsx)(t.dt,{label:`What would you like on the page?`,hint:`Describe the page in your own words — what it says, what it shows, how it feels. Your assistant builds it; whatever you skip, it decides.`,value:e.customNote,onChange:t=>o({...e,customNote:t}),placeholder:`A warm page about the session: who it is for, what we cover, two testimonials, then the Pay button.`,rows:3}),h&&(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:h}),p?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(it,{title:`Ask your assistant`,description:`The page exists on the Pages screen now. Paste this into your assistant's chat; once it has built the page, tick the switch below and the link goes there.`,prompt:p}),(0,i.jsx)(t.mt,{label:`The page is built — send people there`,hint:`Until this is on, the link opens the ready-made page.`,enabled:!!e.customPath.trim(),onChange:t=>o({...e,customPath:t?`/${tu(e)}`:``})})]}):(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(t.Q,{icon:t.yr,disabled:!e.customNote.trim(),onClick:async()=>{g(``);let e=await c();if(typeof e==`string`){g(e);return}m(e.prompt)},children:`Make the page`}),(0,i.jsx)(t.Q,{onClick:()=>{f(!1),g(``)},children:`Never mind`})]})]}),_&&!p&&(0,i.jsx)(t.mt,{label:`The page is built — send people there`,hint:`The link opens ${v}. Change the page from its row on the Pages screen. Turn this off to go back to the ready-made page.`,enabled:!0,onChange:t=>o({...e,customPath:t?e.customPath:``})})]})]})}function au({products:e,onChange:n,onRemove:a}){let[o,s]=(0,r.useState)(null),c=e.filter(e=>e.kind===`once`),l=()=>{let e={...Ii(`p_${Date.now().toString(36)}`),kind:`once`,items:[{name:``,amount:``}]};n(e),s(e.id)},u=async e=>{let t=tu(e),n=`Pay — ${Yi(e)}`,r={name:n,address:t,type:`public`,about:e.customNote.trim()};try{await gs(r)}catch(e){return console.error(`Could not make the page`,e),`The page could not be made — make sure you are signed in as an admin and try again.`}let{config:i}=hs(r),a={title:n,path:`/${t}`};return{path:a.path,prompt:ru(e,a,i)}};return(0,i.jsx)(t.at,{icon:t.ii,title:`Payment links`,description:`Every one-time payment has a page of its own you can send to anyone — a name, a line about it, a price.`,actions:({open:e})=>(0,i.jsx)(t.Q,{icon:t.Ur,title:`Add a payment link`,onClick:()=>{e(),l()},children:`Add a payment link`}),children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:c.length===0?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`No payment link yet. Add one here — it appears under What you sell too — or describe a one-time payment there and its link shows up here.`}):c.map(e=>(0,i.jsx)(iu,{product:e,open:o===e.id,onToggle:()=>s(o===e.id?null:e.id),onChange:n,onRemove:()=>a(e.id),onCustomise:()=>u(e)},e.id))})})}var ou=e=>e.trim()&&Ri(e)===null?`Just a number, like 25.`:void 0,su=e=>/^price_[A-Za-z0-9]+$/.test(e.trim());function cu({item:e,index:n,onChange:r,onRemove:a,removable:o}){let s=ou(e.amount);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`text`,value:e.name,onChange:t=>r({...e,name:t.target.value}),placeholder:n===0?`A one-hour call`:`A two-hour call`,"aria-label":`Thing ${n+1} — its name`,className:`${t.et} flex-1 min-w-0`}),(0,i.jsx)(`input`,{type:`text`,inputMode:`decimal`,value:e.amount,onChange:t=>r({...e,amount:t.target.value}),placeholder:`25`,"aria-label":`Thing ${n+1} — its price`,className:`${t.et} w-24! shrink-0 text-right ${s?`border-red-500/50`:``}`}),o&&(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${e.name.trim()||`thing ${n+1}`}`,onClick:a,children:`Remove`})]}),s&&(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:s})]})}function lu({plan:e,index:n,onChange:r,onRemove:a}){let o=t=>r({...e,...t});return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-4`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,i.jsxs)(`span`,{className:`text-[11px] font-bold uppercase tracking-widest text-foreground/40`,children:[`Plan `,n+1]}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove this plan`,onClick:a,children:`Remove plan`})]}),(0,i.jsx)(t.ft,{label:`What is this plan called?`,value:e.name,onChange:e=>o({name:e}),placeholder:`Basic`}),(0,i.jsx)(t.ft,{label:`One line about it`,hint:`Optional — what a buyer gets on this plan.`,value:e.description,onChange:e=>o({description:e}),placeholder:`Up to 3 projects and email support`}),[[`monthly`,`Billed monthly`,`a month`],[`yearly`,`Billed yearly`,`a year`]].map(([r,a,s])=>(0,i.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 ml-1`,children:a}),(0,i.jsx)(t.pt,{enabled:e[r].on,onChange:t=>o({[r]:{...e[r],on:t}}),label:`${a} — plan ${n+1}`})]}),e[r].on&&(0,i.jsx)(t.ft,{label:`The price ${s}`,hint:`Just the number — 25 charges 25 ${s} in your Stripe account's currency.`,value:e[r].amount,onChange:t=>o({[r]:{...e[r],amount:t}}),placeholder:r===`monthly`?`25`:`250`,error:ou(e[r].amount)})]},r))]})}function uu({product:e,plan:n,index:r,live:a,onChange:o}){let s=a?`livePriceId`:`priceId`,c=(e,t)=>({...e,[s]:t}),l=(!n.monthly.on||su(n.monthly[s]))&&(!n.yearly.on||su(n.yearly[s])),u=e=>o({...n,...e}),d=e=>e.trim()&&!su(e)?`A price id starts with price_ — copy it from the price you just made.`:void 0;return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:n.name.trim()||`Plan ${r+1}`}),(0,i.jsx)(t.lt,{state:l?`saved`:`off`,label:l?`Done`:a?`Waiting for its live ids`:`Waiting for its ids`})]}),(0,i.jsx)(`ol`,{className:`space-y-1.5 list-decimal list-inside text-[12.5px] font-medium text-foreground/60 leading-relaxed`,children:Zi(e,n,a).map((e,t)=>(0,i.jsx)(`li`,{children:e},t))}),n.monthly.on&&(0,i.jsx)(t.ft,{label:a?`Paste the live monthly price id`:`Paste the monthly price id`,value:n.monthly[s],onChange:e=>u({monthly:c(n.monthly,e)}),placeholder:`price_…`,error:d(n.monthly[s])}),n.yearly.on&&(0,i.jsx)(t.ft,{label:a?`Paste the live yearly price id`:`Paste the yearly price id`,value:n.yearly[s],onChange:e=>u({yearly:c(n.yearly,e)}),placeholder:`price_…`,error:d(n.yearly[s])}),a&&(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:`Your test ids are kept — switch back to test mode on this screen and they are exactly where you left them.`})]})}function du({product:e,open:n,live:a,onToggle:o,onChange:s,onRemove:c,onProceed:l}){let u=t=>s({...e,...t}),d=(t,n)=>u({plans:e.plans.map((e,r)=>r===t?n:e)}),f=qi(e,a),p=Ki(e,a),[m,h]=(0,r.useState)(!1),g=Yi(e);return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 pr-3`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:o,"aria-expanded":n,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Xi(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[e.kind&&(0,i.jsx)(t.lt,{state:f?`saved`:`off`,label:f?`Ready`:`In progress`}),(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${n?`rotate-180`:``}`})]})]}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${g}`,onClick:()=>h(!0),children:`Remove`})]}),(0,i.jsx)(Ve,{isOpen:m,title:`Remove ${g}?`,message:`Its answer under How your payments work and its pages under Wire it into your pages go with it, and the request stops carrying it.`,confirmText:`Yes, remove it`,cancelText:`Keep it`,onCancel:()=>h(!1),onConfirm:()=>{h(!1),c()}}),n&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.ct,{label:`How is it paid?`,value:e.kind,onChange:t=>u({kind:t===`once`||t===`subscription`?t:``,plans:t===`subscription`&&!e.plans.length?[Pi()]:e.plans,items:t===`once`&&!e.items.length?[Fi()]:e.items}),options:[{value:`once`,label:`Once — one payment`},{value:`subscription`,label:`A subscription that renews`}],placeholder:`Choose one`}),e.kind===`once`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.Z,{label:`What are you selling?`,hint:`Each thing with its price — just the number: 25 charges 25 in your Stripe account's currency. Nothing to make in Stripe for a one-off.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.items.map((t,n)=>(0,i.jsx)(cu,{item:t,index:n,onChange:t=>u({items:e.items.map((e,r)=>r===n?t:e)}),onRemove:()=>u({items:e.items.filter((e,t)=>t!==n)}),removable:e.items.length>1},n)),(0,i.jsx)(t.Q,{icon:t.Ur,className:`self-start`,onClick:()=>u({items:[...e.items,Fi()]}),children:`Add another`})]})}),e.items.length>1&&(0,i.jsx)(t.ft,{label:`What do you call this group?`,hint:`Optional — one word for the lot, the way you would say it: Calls, The shop.`,value:e.name,onChange:e=>u({name:e}),placeholder:`Calls`})]}),e.kind===`subscription`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.ft,{label:`What is the subscription called?`,value:e.name,onChange:e=>u({name:e}),placeholder:`Membership`}),(0,i.jsx)(t.dt,{label:`One line about it`,hint:`Optional — your assistant uses it on the page.`,value:e.description,onChange:e=>u({description:e}),placeholder:`Everything in the studio, every month.`}),(0,i.jsx)(t.Z,{label:`Its plans`,hint:`Each plan can be billed monthly, yearly, or both.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.plans.map((t,n)=>(0,i.jsx)(lu,{plan:t,index:n,onChange:e=>d(n,e),onRemove:()=>u({plans:e.plans.filter((e,t)=>t!==n)})},n)),(0,i.jsx)(t.Q,{icon:t.Ur,className:`self-start`,onClick:()=>u({plans:[...e.plans,Pi()]}),children:`Add a plan`})]})}),Ji(e)&&(0,i.jsx)(t.Z,{label:a?`Now make it in Stripe — live mode`:`Now make it in Stripe`,hint:a?`Live mode is a fresh Stripe catalogue: make each plan again with Test mode OFF, and paste the live ids it produces.`:`Five minutes in your Stripe dashboard. Each plan below says exactly what to do and takes the id it produces.`,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.plans.map((t,n)=>(0,i.jsx)(uu,{product:e,plan:t,index:n,live:a,onChange:e=>d(n,e)},n))})})]}),(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:[e.kind&&!f?(0,i.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:p}):e.kind?(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Ready — press Proceed to say how it works.`}):(0,i.jsx)(`span`,{}),f?(0,i.jsx)(t.Q,{icon:t.Xi,onClick:l,children:`Proceed`}):(0,i.jsx)(`span`,{})]})]})]})}function fu(){let[e,n]=(0,r.useState)(null),[a,s]=(0,r.useState)(!1),[c,l]=(0,r.useState)(null),[u,d]=(0,r.useState)(null),[f,p]=(0,r.useState)(null),[m,h]=(0,r.useState)(``),g=(0,r.useRef)(new Map),_=(0,r.useRef)(null),v=(0,r.useRef)(null),y=Ra();(0,r.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(t.Da,ji),e=>{let t=!!e.docs.find(e=>e.id===Mi)?.data()?.liveMode;if(s(t),Oa(t),g.current.size)return;let r=[];e.forEach(e=>{e.id!==`_settings`&&r.push(Ui(e.id,e.data()))}),r.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)),n(r)},()=>n([]));return()=>e()},[]);let b=e=>{let n=g.current.get(e.id);n&&clearTimeout(n),g.current.set(e.id,setTimeout(async()=>{g.current.delete(e.id);try{let{id:n,...r}=e;await(0,o.setDoc)((0,o.doc)(t.Da,ji,n),r)}catch(e){console.error(`Could not save the product`,e)}},600))},x=e=>{n(t=>{let n=t||[];return n.some(t=>t.id===e.id)?n.map(t=>t.id===e.id?e:t):[...n,e]}),b(e)},S=()=>{let e=Ii(`p_${Date.now().toString(36)}`);n(t=>[...t||[],e]),l(e.id),b(e)},C=async r=>{let i=g.current.get(r);i&&(clearTimeout(i),g.current.delete(r));let a=(e||[]).find(e=>e.id===r);h(``),n(e=>(e||[]).filter(e=>e.id!==r)),c===r&&l(null),u===r&&d(null),f===r&&p(null);try{await(0,o.deleteDoc)((0,o.doc)(t.Da,ji,r))}catch(e){console.error(`Could not remove the product`,e),a&&n(e=>{let t=e||[];return t.some(e=>e.id===r)?t:[...t,a].sort((e,t)=>(e.createdAt||0)-(t.createdAt||0))}),h(`It could not be removed — make sure you are signed in as an admin and try again.`)}},w=e=>{l(null),d(e),_.current?.scrollIntoView({behavior:`smooth`,block:`start`})};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.at,{icon:t.Pr,title:`What you sell`,description:`Things paid for once, each with a price; or a subscription with plans and their Stripe ids.`,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:e===null?(0,i.jsx)(`p`,{className:t.$,children:`Loading what you sell…`}):(0,i.jsxs)(i.Fragment,{children:[e.length===0&&(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug px-1`,children:`Nothing here yet. Describe what you sell once — things paid for once need nothing from Stripe, and a subscription walks you through Stripe step by step — then say how it works in the section below, and where it goes in the last.`}),e.map(e=>(0,i.jsx)(du,{product:e,open:c===e.id,live:a,onToggle:()=>l(c===e.id?null:e.id),onChange:x,onRemove:()=>C(e.id),onProceed:()=>w(e.id)},e.id)),!!m&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:m}),(0,i.jsx)(t.Q,{icon:t.Ur,className:`self-start`,onClick:S,children:`Add something you sell`})]})})}),(0,i.jsx)(`div`,{ref:_,children:(0,i.jsx)(t.at,{icon:t.vr,title:`How your payments work`,description:`One answer per payment: what someone does, pays, and gets. Which pages it goes on is the next card.`,children:(0,i.jsx)(Yl,{products:e,live:a,openId:u,onToggle:e=>d(u===e?null:e),onChange:x,onProceed:e=>{d(null),p(e),v.current?.scrollIntoView({behavior:`smooth`,block:`start`})}})})}),(0,i.jsx)(`div`,{ref:v,children:(0,i.jsx)(t.at,{icon:t.Wr,title:`Wire it into your pages`,description:`Each payment: tick the pages it goes on, say what should appear there — then copy one request that wires all of it.`,children:(0,i.jsx)($l,{products:e,pageRows:y,live:a,openId:f,onToggle:e=>p(f===e?null:e),onChange:x})})}),(0,i.jsx)(au,{products:e||[],onChange:x,onRemove:C})]})}var pu=r.default.createContext({}),mu=Object.defineProperty,hu=Object.getOwnPropertySymbols,gu=Object.prototype.hasOwnProperty,_u=Object.prototype.propertyIsEnumerable,vu=(e,t,n)=>t in e?mu(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,yu=(e,t)=>{for(var n in t||={})gu.call(t,n)&&vu(e,n,t[n]);if(hu)for(var n of hu(t))_u.call(t,n)&&vu(e,n,t[n]);return e},bu=(0,r.forwardRef)((e,t)=>{let n=yu(yu({},r.useContext(pu)),e);return r.createElement(`svg`,yu({width:`1.5em`,height:`1.5em`,viewBox:`0 0 24 24`,strokeWidth:1.5,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,color:`currentColor`,ref:t},n),r.createElement(`path`,{d:`M22 12C22 17.5228 17.5228 22 12 22C10.1786 22 8.47087 21.513 7 20.6622L2 21.5L2.83209 16C2.29689 14.7751 2 13.4222 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`}),r.createElement(`path`,{d:`M12.9604 13.8683L15.0399 13.4624L17 14.2149V16.0385C17 16.6449 16.4783 17.1073 15.8901 16.9783C14.3671 16.6444 11.5997 15.8043 9.67826 13.8683C7.84859 12.0248 7.22267 9.45734 7.01039 8.04128C6.92535 7.47406 7.3737 7 7.94306 7H9.83707L10.572 8.96888L10.1832 11.0701`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`}))}),xu=`aistudio`;function Su(){return xu}function Cu(){let[e,t]=(0,r.useState)(Su);return[e,(0,r.useCallback)(e=>{t(e)},[])]}var wu=`Set this project up for Your AI Firebase, and do only what is listed here.
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-DYteiM-1.cjs`),t=require(`./ContactPopup-CiOMamPP.cjs`),n=require(`./PhoneInputField-CkAv_5Lw.cjs`);let r=require(`react`);r=e.i(r,1);let i=require(`react/jsx-runtime`),a=require(`firebase/auth`),o=require(`firebase/firestore`),s=require(`firebase/storage`),c=require(`react-router-dom`),l=require(`react-dom`);var u=Object.assign({"./contactForm.config.ts":t.Pa,"./supportForm.config.ts":t.Ma}),d={};for(let e in u){let t=u[e];if(!t)continue;let n=null;for(let e in t)if(e.endsWith(`FormConfig`)||e.endsWith(`Config`)){n=t[e];break}if(!n&&t?.default&&(n=t.default),!n)continue;let r=e.replace(`./`,``).replace(`.config.ts`,``).replace(/Form$/,``).toLowerCase(),i={...n,systemName:n.systemName||r};d[r]=i,i.systemName&&(d[i.systemName]=i,d[i.systemName.toLowerCase()]=i)}if(typeof window<`u`){let e=window.__FBOS_FORMS__||{};window.__FBOS_FORMS__={...d,...e}}var f=Object.assign({}),p=Object.assign({}),m={};for(let e in f){let t=f[e];if(!t)continue;let n=null;for(let e in t)if(e.endsWith(`TabConfig`)||e.endsWith(`Config`)){n=t[e];break}if(!n&&t?.default&&(n=t.default),!n)continue;let r=e.replace(`./`,``).replace(`.config.ts`,``).replace(/Tab$/,``).toLowerCase(),i={config:{...n,pageId:n.pageId||r,tabName:n.tabName||n.title||r},isPublic:!1};m[r]=i,i.config.pageId&&(m[i.config.pageId]=i,m[i.config.pageId.toLowerCase()]=i)}for(let e in p){let t=p[e];if(!t)continue;let n=null;for(let e in t)if(e.endsWith(`PageConfig`)||e.endsWith(`Config`)){n=t[e];break}if(!n&&t?.default&&(n=t.default),!n)continue;let r=e.replace(`./`,``).replace(`.config.ts`,``).replace(/Page$/,``).toLowerCase(),i={config:{...n,pageId:n.pageId||r,pageName:n.pageName||n.title||r},isPublic:!0};m[r]=i,i.config.pageId&&(m[i.config.pageId]=i,m[i.config.pageId.toLowerCase()]=i)}if(typeof window<`u`){let e=window.__FBOS_PAGES__||{};window.__FBOS_PAGES__={...m,...e}}var h=()=>{document.querySelectorAll(`.fbos-content-slot style, .fbos-home-slot style`).forEach(e=>{e.disabled&&e.media===`not all`||(e.disabled=!0,e.media=`not all`,typeof console<`u`&&console.warn(`FirebaseOS: a <style> tag inside a content file is global CSS and was disabled — style with theme classes (bg-background, text-foreground, glass-panel, btn-primary) instead.`))})},g=e=>{for(let t=e;t;t=t.parentElement){if(t.classList.contains(`fbos-content-slot`)||t.classList.contains(`fbos-home-slot`))return!1;if(getComputedStyle(t).position===`fixed`)return!0}return!1},_=()=>{if(typeof window>`u`)return;let e=window.innerHeight*.6;document.querySelectorAll(`.fbos-content-slot *, .fbos-home-slot *`).forEach(t=>{if(!t.clientHeight||t.clientHeight<e||t.scrollHeight<=t.clientHeight+2)return;let n=getComputedStyle(t);n.overflowY!==`visible`&&(n.webkitLineClamp&&n.webkitLineClamp!==`none`||g(t)||(t.style.setProperty(`max-height`,`none`,`important`),t.style.setProperty(`height`,`auto`,`important`),t.scrollHeight>t.clientHeight+2&&t.style.setProperty(`overflow-y`,`visible`,`important`),typeof console<`u`&&console.warn(`FirebaseOS: a box in a content file was as tall as the screen and hid the rest of the page, which left the bottom unreachable on a phone — it was allowed to grow. Let the page be as long as it needs: no h-screen, max-h-screen or overflow-hidden around the whole page.`)))})},v=()=>{(0,r.useEffect)(()=>{if(typeof document>`u`||typeof MutationObserver>`u`)return;let e=()=>{h(),_()};e();let t=new MutationObserver(e);return t.observe(document.body,{childList:!0,subtree:!0}),window.addEventListener(`resize`,e),window.addEventListener(`orientationchange`,e),()=>{t.disconnect(),window.removeEventListener(`resize`,e),window.removeEventListener(`orientationchange`,e)}},[])};function y(){return(typeof window<`u`?window.__FBOS_PAGES__:null)||{}}function b(e=y()){let t=new Set,n=[];for(let[r,i]of Object.entries(e))!i||t.has(i)||(t.add(i),n.push([r,i]));return n}var x=`mem_notifications`;async function S(e){let{toUid:n,toRole:r,title:i,body:a,link:s}=e||{};if(!i||!n&&!r){console.warn(`notify(): needs a title and either toUid (one person) or toRole ('admin' | 'internal').`,e);return}if(r&&r!==`admin`&&r!==`internal`){console.warn(`notify(): toRole is 'admin' or 'internal' — the bell's notifications live in mem_, which only the team can read, so '${r}' would reach nobody. To reach one person, pass toUid with their uid.`,e);return}let c=t.Sa.currentUser;if(!c){console.warn(`notify(): nobody is signed in, so there is no one to send as.`);return}try{await(0,o.addDoc)((0,o.collection)(t.Ca,x),{...n?{toUid:n}:{toRole:r},title:i,body:a||``,link:s||``,uid:c.uid,fromName:c.displayName||c.email||``,createdAt:(0,o.serverTimestamp)()})}catch(e){console.warn(`notify(): the notification was not saved. If the sender is not on your team, re-paste your Firestore rules from /setup — sending from outside the team needs the mem_notifications line added in 1.14.21. A sender who is signed out, unverified or deactivated is refused whatever the rules say.`,e)}}var C=`user_notices`;async function w(e,n){let r=String(e||``).trim();if(!r||!n?.title){console.warn(`leaveNotice(): needs the uid of the person to tell and a title.`,n);return}try{await(0,o.addDoc)((0,o.collection)(t.Ca,C),{uid:r,kind:`notice`,title:n.title,body:n.body||``,link:n.link||``,fromName:t.Sa.currentUser?.displayName||t.Sa.currentUser?.email||``,createdAt:Date.now()})}catch(e){console.warn(`leaveNotice(): the notice was not saved — only an admin may leave one.`,e)}}async function T(e,t){for(let n of[...new Set(e.map(e=>String(e||``).trim()).filter(Boolean))])await w(n,t)}function E(e,n,r){if(n?.own===!0)return null;let i=n?.start?t.un(new Date(String(n.start)),r):``,a=t.Yt({scheduleName:n?.scheduleName,memberName:n?.memberName}),o=String(n?.cancelReason||``).trim(),s={id:`b_${e}`,groupKey:n?.entryId?`${n.entryId}__${String(n.start||``)}`:``,type:`booking`,link:`/my-bookings`};return n?.cancelled===!0?String(n.cancelledSide||``)===`booker`?null:{...s,title:`Booking cancelled`,subtitle:[a,i,o].filter(Boolean).join(` · `),time:typeof n.cancelledAt==`number`&&n.cancelledAt>0?n.cancelledAt:n.createdAt}:n?.pending!==!0&&typeof n?.acceptedAt==`number`&&n.acceptedAt>0?{...s,title:`Booking confirmed`,subtitle:[a,i].filter(Boolean).join(` · `),time:n.acceptedAt}:null}function D(e,t){let n=new Map;for(let t of e){let e=t.data()||{};if(e.own===!0)continue;let r=e.entryId?`${e.entryId}__${String(e.start||``)}`:t.id,i=n.get(r);i?i.push({id:t.id,data:e}):n.set(r,[{id:t.id,data:e}])}let r=[];for(let e of n.values()){let n=e.find(e=>e.data.cancelled===!0&&String(e.data.cancelledSide||``)!==`booker`&&String(e.data.cancelReason||``).trim())||e.find(e=>e.data.cancelled===!0);if(n){let e=E(n.id,n.data,t);e&&r.push(e);continue}if(e.every(e=>E(e.id,e.data,t)?.title===`Booking confirmed`)){let n=e.reduce((e,t)=>t.data.acceptedAt>e.data.acceptedAt?t:e),i=E(n.id,n.data,t);i&&r.push(i)}}return r}function O(){let[e,n]=(0,r.useState)(!1),[a,s]=(0,r.useState)([]),l=(0,r.useRef)(null),u=(0,r.useRef)(null),[d,f]=(0,r.useState)(null),p=(0,c.useNavigate)(),{user:m,userRole:h,roleConfirmed:g}=t.Qi(),_=h===`admin`,v=t.ca(h);(0,r.useEffect)(()=>{function e(e){l.current&&!l.current.contains(e.target)&&n(!1)}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let y=(0,r.useRef)({users:[],submissions:[],requests:[],direct:[],rolewide:[],bookings:[],booked:[],bookedByEmail:[],notices:[]}),b=(0,r.useRef)(!1);(0,r.useEffect)(()=>{b.current=!1},[m?.uid]);let S=(e,t)=>{y.current[e]=t;let n=y.current,r=new Set,i=[...n.users,...n.submissions,...n.requests,...n.direct,...n.rolewide,...n.bookings,...n.booked,...n.bookedByEmail,...n.notices].filter(e=>r.has(e.id)?!1:(r.add(e.id),!0));i.sort((e,t)=>{let n=e.time?.toDate?e.time.toDate().getTime():new Date(e.time).getTime();return((t.time?.toDate?t.time.toDate().getTime():new Date(t.time).getTime())||0)-(n||0)}),s(i.slice(0,8))},w=(e,t)=>{b.current||(b.current=!0,console.warn(`AdminNotifications: this account could not read one of the notification feeds, so that part of the bell is empty. Most of them are the team's alone, and every one of them asks for a verified address.`,t)),S(e,[])};(0,r.useEffect)(()=>{let e=[];if(g){if(_){let n=(0,o.query)((0,o.collection)(t.Ca,`user_profiles`),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(5));e.push((0,o.onSnapshot)(n,e=>{S(`users`,e.docs.map(e=>{let t=e.data();return{id:`u_${e.id}`,type:`user`,title:`New user registered`,subtitle:t.email||`Unknown`,time:t.createdAt,link:`/users/${e.id}`}}))},e=>w(`users`,e)));let r=(0,o.query)((0,o.collection)(t.Ca,`user_submissions`),(0,o.orderBy)(`submittedAt`,`desc`),(0,o.limit)(5));e.push((0,o.onSnapshot)(r,e=>{S(`submissions`,e.docs.filter(e=>e.data()?.formId!==`booking`&&!t.on(e.data()||{})).map(e=>{let t=e.data();return{id:`s_${e.id}`,type:`submission`,title:`New form submission`,subtitle:t.name||t.email||`Anonymous`,time:t.submittedAt,link:`/inbox?open=${encodeURIComponent(`anyone:${e.id}`)}`}}))},e=>w(`submissions`,e)));let i=(0,o.query)((0,o.collection)(t.Ca,`user_requests`),(0,o.orderBy)(`submittedAt`,`desc`),(0,o.limit)(5));e.push((0,o.onSnapshot)(i,e=>{S(`requests`,e.docs.map(e=>{let t=e.data();return{id:`r_${e.id}`,type:`request`,title:`New support request`,subtitle:t.name||t.submitterName||t.contactEmail||t.email||`Anonymous`,time:t.submittedAt,link:`/inbox?open=${encodeURIComponent(`signedIn:${e.id}`)}`}}))},e=>w(`requests`,e)))}else S(`users`,[]),S(`submissions`,[]),S(`requests`,[]);if(m?.uid&&(_||v)){let n=e=>{let n=e.data()||{};if(n.own===!0)return null;let r=n.cancelled===!0,i=String(n.cancelledSide||``)!==`booker`&&String(n.cancelledByUid||``)===(m?.uid||``);if(r&&i)return null;let a=n.start?t.un(new Date(String(n.start)),t.an()):``,o=t.cn({name:n.name}),s=String(n.cancelReason||``).trim();return{id:`b_${e.id}`,groupKey:n.entryId?`${n.entryId}__${String(n.start||``)}`:``,type:`booking`,title:r?`Booking cancelled`:n.pending===!0?`Booking to accept`:`New booking`,subtitle:[o,a,r?s:``].filter(Boolean).join(` · `),time:r&&typeof n.cancelledAt==`number`&&n.cancelledAt>0?n.cancelledAt:n.createdAt,link:`/schedule?open=${encodeURIComponent(e.id)}`}},r=e=>{let t=new Set,n=[];for(let r of e)if(r){if(r.groupKey){if(t.has(r.groupKey))continue;t.add(r.groupKey)}n.push(r)}return n},i=_?(0,o.query)((0,o.collection)(t.Ca,t.ht),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(5)):(0,o.query)((0,o.collection)(t.Ca,t.ht),(0,o.where)(`memberId`,`==`,m.uid));e.push((0,o.onSnapshot)(i,e=>S(`bookings`,r(e.docs.map(n))),e=>w(`bookings`,e)))}else S(`bookings`,[]);if(m?.uid){let n=t.an(),r=e=>D(e.docs,n),i=(0,o.query)((0,o.collection)(t.Ca,t.ht),(0,o.where)(`uid`,`==`,m.uid));e.push((0,o.onSnapshot)(i,e=>S(`booked`,r(e)),e=>w(`booked`,e)));let a=String(m.email||``).trim().toLowerCase();if(a){let n=(0,o.query)((0,o.collection)(t.Ca,t.ht),(0,o.where)(`email`,`==`,a));e.push((0,o.onSnapshot)(n,e=>S(`bookedByEmail`,r(e)),e=>w(`bookedByEmail`,e)))}else S(`bookedByEmail`,[])}else S(`booked`,[]),S(`bookedByEmail`,[]);if(m?.uid){let n=(0,o.query)((0,o.collection)(t.Ca,C),(0,o.where)(`uid`,`==`,m.uid)),r=e=>{let t=e.data()||{};return{id:`n_${e.id}`,type:`message`,title:String(t.title||`Notification`),subtitle:String(t.body||``),time:t.createdAt,link:typeof t.link==`string`&&t.link.startsWith(`/`)?t.link:void 0}};e.push((0,o.onSnapshot)(n,e=>{S(`notices`,e.docs.filter(e=>(e.data()||{}).kind===`notice`).map(r))},e=>w(`notices`,e)))}else S(`notices`,[]);if(m?.uid&&(_||v)){let n=e=>{let t=e.data();return{id:`m_${e.id}`,type:`message`,title:t.title||`Notification`,subtitle:t.body||t.fromName||``,time:t.createdAt,link:typeof t.link==`string`&&t.link.startsWith(`/`)?t.link:void 0}},r=(0,o.query)((0,o.collection)(t.Ca,x),(0,o.where)(`toUid`,`==`,m.uid));e.push((0,o.onSnapshot)(r,e=>S(`direct`,e.docs.map(n)),e=>w(`direct`,e)));let i=_?[`admin`,`internal`]:[`internal`],a=(0,o.query)((0,o.collection)(t.Ca,x),(0,o.where)(`toRole`,`in`,i));e.push((0,o.onSnapshot)(a,e=>S(`rolewide`,e.docs.map(n)),e=>w(`rolewide`,e)))}else S(`direct`,[]),S(`rolewide`,[]);return()=>e.forEach(e=>e())}},[_,v,m?.uid,m?.email,g]);let[T,E]=(0,r.useState)(()=>typeof window<`u`?parseInt(localStorage.getItem(`admin_notifications_last_read`)||`0`,10):0),O=()=>{let t=!e;if(n(t),t){let e=u.current?.getBoundingClientRect();f(typeof window<`u`&&window.innerWidth<640&&e?e.bottom+8:null);let t=Date.now();E(t),typeof window<`u`&&localStorage.setItem(`admin_notifications_last_read`,t.toString())}},k=a.some(e=>{if(!e.time)return!0;let t=e.time?.toDate?e.time.toDate().getTime():new Date(e.time).getTime();return t>T||isNaN(t)}),A=e=>{n(!1),e.link?p(e.link):e.type===`user`?p(`/users`):e.type===`booking`?p(v?`/schedule`:`/my-bookings`):(e.type===`submission`||e.type===`request`)&&p(`/inbox`)},j=e=>{if(!e)return``;let t=e.toDate?e.toDate():new Date(e),n=Date.now()-t.getTime();if(isNaN(n))return``;let r=Math.floor(n/6e4);if(r<1)return`now`;if(r<60)return`${r}m`;let i=Math.floor(r/60);if(i<24)return`${i}h`;let a=Math.floor(i/24);return a<7?`${a}d`:new Intl.DateTimeFormat(`en-US`,{month:`short`,day:`numeric`}).format(t)};return(0,i.jsxs)(`div`,{className:`relative z-50 flex-shrink-0`,ref:l,children:[(0,i.jsxs)(`button`,{ref:u,onClick:O,className:`w-9 h-9 rounded-xl border border-[var(--panel-border)] transition-all relative text-foreground/60 hover:bg-foreground/5 hover:text-foreground flex items-center justify-center shadow-sm cursor-pointer`,"aria-label":`Notifications`,children:[(0,i.jsx)(t.Hi,{className:`w-4 h-4`}),k&&(0,i.jsx)(`span`,{className:`absolute top-1.5 right-1.5 w-2 h-2 bg-[var(--notification-icon-color)] rounded-full animate-pulse`})]}),(0,i.jsx)(t.pr,{children:e&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:-5,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,scale:.98,y:-5},className:`${d===null?`absolute top-full mt-2 right-0`:`fixed right-4`} w-[min(320px,calc(100vw-2rem))] md:w-[400px] glass-popover border border-[var(--panel-border)] rounded-2xl z-50 flex flex-col origin-top-right overflow-hidden`,style:d===null?void 0:{top:d},children:[(0,i.jsxs)(`div`,{className:`px-4 border-b border-[var(--panel-border)]/50 pb-3 pt-4 flex items-center justify-between`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[14px] text-foreground tracking-wide`,children:`Notifications`}),(_||v)&&(0,i.jsx)(`span`,{className:`text-[10px] font-bold uppercase tracking-widest text-accent bg-accent/10 px-2 py-0.5 rounded-md`,children:_?`Admin`:`Team`})]}),(0,i.jsx)(`div`,{className:`max-h-[350px] overflow-y-auto w-full p-2 flex flex-col gap-1`,children:a.length===0?(0,i.jsx)(`div`,{className:`p-6 text-center text-foreground/40 text-[13px] font-medium`,children:`No recent activity.`}):a.map(e=>(0,i.jsxs)(`button`,{onClick:()=>A(e),className:`w-full flex items-start gap-3 p-3 rounded-xl hover:bg-foreground/5 transition-all text-left group border border-transparent hover:border-[var(--panel-border)]`,children:[(0,i.jsx)(`div`,{className:`mt-0.5 w-8 h-8 rounded-full flex items-center justify-center shrink-0 bg-foreground/5 text-notification-icon`,children:e.type===`user`?(0,i.jsx)(t.Sr,{className:`w-4 h-4`}):e.type===`booking`?(0,i.jsx)(t.Bi,{className:`w-4 h-4`}):e.type===`submission`?(0,i.jsx)(t.Xr,{className:`w-4 h-4`}):e.type===`message`?(0,i.jsx)(t.Hi,{className:`w-4 h-4`}):(0,i.jsx)(t.Oi,{className:`w-4 h-4`})}),(0,i.jsxs)(`div`,{className:`flex flex-col flex-1 min-w-0`,children:[(0,i.jsxs)(`div`,{className:`flex items-baseline gap-2`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground group-hover:text-accent transition-colors truncate flex-1 min-w-0`,children:e.title}),(0,i.jsx)(`span`,{className:`text-[10px] font-mono tracking-wide text-foreground/40 shrink-0`,children:j(e.time)})]}),(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/60 truncate`,children:e.subtitle})]})]},e.id))})]})})]})}var k=[{id:`contact`,hidden:!1}],A={drive:`assets`,submissions:`inbox`,requests:`inbox`},j=new Set([`setup`]),M=e=>{let t=(e||[]).map(e=>typeof e==`string`?{id:e,hidden:!1}:{id:String(e.id),hidden:!!e.hidden}).map(e=>({...e,id:A[e.id]||e.id})).filter(e=>!j.has(e.id));return t.filter((e,n)=>t.findIndex(t=>t.id===e.id)===n)},N=[{id:`inbox`,hidden:!1},{id:`users`,hidden:!1},{id:`pages`,hidden:!1},{id:`schedule`,hidden:!1},{id:`mybookings`,hidden:!1},{id:`payments`,hidden:!1},{id:`email`,hidden:!1},{id:`forms`,hidden:!1},{id:`theme`,hidden:!1},{id:`assets`,hidden:!1},{id:`publish`,hidden:!1}],P={route:`/support`,template:`popup_form`,form:`support`,tabName:`Support`,iconName:``};function F(e,t,n,r){let i=0,a=!0;for(let r=0;r<e.length;r++)if(i+=e[r]+(r>0?n:0),i>t){a=!1;break}if(a)return e.length;let o=0,s=0;for(let i=0;i<e.length;i++){let a=o+e[i]+(i>0?n:0);if(a+r>t)break;o=a,s++}return Math.max(s,1)}function I({count:e,listKey:t,shown:n,gap:i,moreButtonWidth:a}){let o=(0,r.useRef)(null),s=(0,r.useRef)(null),[c,l]=(0,r.useState)(null);return(0,r.useLayoutEffect)(()=>{if(!n)return;let r=!0,c=0,u=()=>{let n=o.current,c=s.current;if(!r||!n||!c)return;let u=window.getComputedStyle(n),d=n.clientWidth-(parseFloat(u.paddingLeft)||0)-(parseFloat(u.paddingRight)||0);if(d<=0)return;let f=c.querySelectorAll(`[data-measure]`);if(f.length!==e)return;let p=parseFloat(u.columnGap);l({listKey:t,count:F(Array.from(f,e=>e.offsetWidth),d,Number.isFinite(p)?p:i,a)})},d=()=>{cancelAnimationFrame(c),c=requestAnimationFrame(u)};u(),document.fonts?.ready.then(d).catch(()=>{});let f=typeof ResizeObserver>`u`?null:new ResizeObserver(d);return f&&o.current&&f.observe(o.current),()=>{r=!1,cancelAnimationFrame(c),f?.disconnect()}},[e,t,n,i,a]),{rowRef:o,measureRef:s,visible:c&&c.listKey===t?Math.min(c.count,e):e}}var L=`Could not reach the server. Check your connection and try again.`,R={goTo(e){window.location.href=e}},z=`/api/payments/webhook`,B=e=>e?`${e.replace(/\/$/,``)}${z}`:``;async function V(){try{let e=t.Sa?.currentUser;return e?await e.getIdToken():null}catch{return null}}function H(e){return e?{Authorization:`Bearer ${e}`}:{}}async function U(e,t){try{let t=await e.json();if(t&&typeof t.error==`string`&&t.error)return t.error}catch{}return t}async function W(e){let t=await G(e);return typeof t==`string`?t:(R.goTo(t.url),null)}async function G(e){try{let t=await V(),n=await fetch(`/api/payments/checkout`,{method:`POST`,headers:{"Content-Type":`application/json`,...H(t)},body:JSON.stringify({...e,origin:window.location.origin})});if(!n.ok)return await U(n,`The payment could not be started. Please try again.`);let r=await n.json();return r?.url?{sessionId:String(r.sessionId||``),url:String(r.url)}:`The payment could not be started. Please try again.`}catch{return L}}async function ee(){let e=await V();if(!e)return`Sign in to manage your plan.`;try{let t=await fetch(`/api/payments/portal`,{method:`POST`,headers:{"Content-Type":`application/json`,...H(e)},body:JSON.stringify({origin:window.location.origin})});if(!t.ok)return await U(t,`The billing portal could not be opened.`);let n=await t.json();return n?.url?(R.goTo(String(n.url)),null):`The billing portal could not be opened.`}catch{return L}}async function K(e){let t={paid:!1,paymentStatus:null,amountTotal:null,currency:null,customerEmail:null,metadata:{},error:null};if(!e)return{...t,error:`No payment session to confirm.`};try{let n=await fetch(`/api/payments/session/${encodeURIComponent(e)}`);if(!n.ok)return{...t,error:await U(n,`That payment could not be found.`)};let r=await n.json();return{paid:r?.paid===!0,paymentStatus:r?.paymentStatus??null,amountTotal:r?.amountTotal??null,currency:r?.currency??null,customerEmail:r?.customerEmail??null,metadata:r?.metadata||{},error:null}}catch{return{...t,error:L}}}var q=null;function J(){return q||=fetch(`/api/payments/status`).then(e=>e.json()).then(e=>({configured:e?.configured===!0&&e?.enabled!==!1,mode:e?.mode??null})).catch(()=>(q=null,{configured:!1,mode:null})),q}function Y(){q=null}function X(){let[e,t]=(0,r.useState)({loading:!0,configured:!1,mode:null});return(0,r.useEffect)(()=>{let e=!1;return J().then(n=>{e||t({loading:!1,...n})}),()=>{e=!0}},[]),e}function te(){let[e,t]=(0,r.useState)({loading:!0,active:!1,subscriptions:[],payments:[],error:null});return(0,r.useEffect)(()=>{let e=!1,n=n=>{e||t({loading:!1,...n})};return(async()=>{let e=await V();if(!e)return n({active:!1,subscriptions:[],payments:[],error:null});try{let t=await fetch(`/api/payments/me`,{headers:H(e)});if(!t.ok)return n({active:!1,subscriptions:[],payments:[],error:await U(t,`Your payments could not be loaded.`)});let r=await t.json();return n({active:r?.active===!0,subscriptions:r?.subscriptions||[],payments:r?.payments||[],error:null})}catch{return n({active:!1,subscriptions:[],payments:[],error:L})}})(),()=>{e=!0}},[]),e}function ne(){let[e,t]=(0,r.useState)({loading:!0,charges:[],subscriptions:[],error:null});return(0,r.useEffect)(()=>{let e=!1,n=n=>{e||t({loading:!1,...n})};return(async()=>{let e=await V();if(!e)return n({charges:[],subscriptions:[],error:`Please sign in first.`});try{let t=await fetch(`/api/payments/sales`,{headers:H(e)});if(!t.ok)return n({charges:[],subscriptions:[],error:await U(t,`The sales could not be loaded.`)});let r=await t.json();return n({charges:r?.charges||[],subscriptions:r?.subscriptions||[],error:null})}catch{return n({charges:[],subscriptions:[],error:L})}})(),()=>{e=!0}},[]),e}var re={"/contact":t.Xr},Z=e=>e&&re[e]||t.oi;function Q({onNavigate:e}){let{subscriptions:n,payments:r}=te();return n.length===0&&r.length===0?null:(0,i.jsxs)(c.Link,{to:`/billing`,onClick:e,className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.xi,{className:`w-3 h-3 text-accent`})}),`Billing`]})}function ie(){let{subscriptions:e}=te(),t=e.find(e=>e.active&&e.productName)?.productName;return(0,i.jsx)(i.Fragment,{children:t||`Member`})}var ae={contact:{label:`Contact`,path:`/contact`}},oe=new Set([`setup`,`templates`,`guide`]);function se({customMenu:e,standalone:n}){let{user:a,userRole:s,signOut:l,roleResolved:u}=t.Qi(),d=u!==!1,f=t.la(s),p=t.da(s),m=t.ea[p],[h,g]=(0,r.useState)(!1),[_,v]=(0,r.useState)(null),[y,x]=(0,r.useState)(!1),[S,C]=(0,r.useState)(!1),[w,T]=(0,r.useState)(!1),E=a?.displayName||a?.email?.split(`@`)[0]||`User`,D=E.charAt(0).toUpperCase()+E.slice(1),{theme:A,toggleTheme:j,activeConfig:N,canSwitchTheme:F}=t.Da(),L=async()=>{await l(),g(!1)},[R,z]=(0,r.useState)({...ae}),[B,V]=(0,r.useState)(k),[H,U]=(0,r.useState)(P.tabName);(0,r.useEffect)(()=>{if(!t.Ca)return;let e=(0,o.onSnapshot)((0,o.collection)(t.Ca,`sys_pages`),e=>{let t={...ae};for(let[e,n]of b()){if(!n.isPublic)continue;let r=n.config||{};if(r.enabled===!1)continue;let i=r.route?r.route.startsWith(`/`)?r.route:`/`+r.route:`/`+e;t[e]={label:r.pageName||r.pageTitle||r.title||e,path:i}}e.forEach(e=>{let n=e.data();if(n.enabled===!1)return;let r=n.pageName||n.title||ae[e.id]?.label||e.id,i=n.route||(e.id===`home`?`/`:`/`+e.id);t[e.id]={label:r,path:i}});for(let e of oe)delete t[e];z(t)},e=>{console.warn(`sys_pages snapshot error (safe to ignore during auth transition):`,e)}),n=(0,o.onSnapshot)((0,o.doc)(t.Ca,`sys_configs`,`page_order`),e=>{V(e.exists()&&Array.isArray(e.data().order)?M(e.data().order):k)},e=>{console.warn(`page_order snapshot error (safe to ignore during auth transition):`,e)}),r=(0,o.onSnapshot)((0,o.doc)(t.Ca,`sys_tabs`,`support`),e=>{e.exists()&&e.data().pageName&&U(e.data().pageName)},e=>{console.warn(`support snapshot error (safe to ignore during auth transition):`,e)});return()=>{e(),n(),r()}},[]);let W=(()=>{let e=new Set(B.filter(e=>e.hidden).map(e=>e.id)),t=new Set,n=[];return B.forEach(e=>{if(e.hidden||e.id===`home`)return;let r=R[e.id];r&&(n.push({label:r.label,path:r.path}),t.add(e.id))}),Object.entries(R).forEach(([r,i])=>{!t.has(r)&&!e.has(r)&&r!==`home`&&i.path!==`/`&&i.path!==`/support`&&n.push({label:i.label,path:i.path})}),n})(),G=e||W,[ee,K]=(0,r.useState)(()=>typeof window<`u`&&window.innerWidth<640);(0,r.useEffect)(()=>{if(typeof window>`u`)return;let e=()=>{let e=window.innerWidth<640;K(t=>(t!==e&&g(!1),e))};return e(),window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[]);let q=!n&&!a&&!ee,{rowRef:J,measureRef:Y,visible:X}=I({count:G.length,listKey:G.map(e=>e.label+(e.submenu?` ▾`:``)).join(`|`),shown:q,gap:28,moreButtonWidth:50}),te=G.slice(0,X),ne=G.slice(X);return(0,i.jsxs)(`nav`,{className:`flex items-center justify-between w-full max-w-7xl mx-auto z-40 p-4 md:p-10 relative`,children:[(0,i.jsx)(`div`,{className:`flex items-center min-w-0 z-50`,children:(0,i.jsxs)(c.Link,{to:`/`,className:`flex items-center gap-2 md:gap-2.5 lg:gap-3 group cursor-pointer z-50 min-w-0`,children:[(0,i.jsx)(`div`,{className:`w-8 h-8 md:w-9 md:h-9 rounded-lg glass-panel flex items-center justify-center glow-hover shadow-lg transition-transform duration-500 group-hover:rotate-180 group-active:scale-95 overflow-hidden shrink-0`,children:N?.logoUrl?(0,i.jsx)(`img`,{src:N.logoUrl,alt:`Logo`,className:`w-full h-full object-contain max-md:p-0.5`}):(0,i.jsx)(t.bi,{className:`w-4 h-4 text-accent`})}),(0,i.jsx)(`span`,{className:`font-bold text-[17px] md:text-[19px] lg:text-[22px] tracking-tight text-gradient transition-all duration-300 drop-shadow-sm truncate`,children:N?.appName||``})]})}),(0,i.jsx)(t.pr,{children:y&&(0,i.jsx)(t.t,{formId:`contact`,onClose:()=>x(!1)})}),(0,i.jsx)(t.pr,{children:S&&(0,i.jsx)(t.t,{formId:`support`,onClose:()=>C(!1)})}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5 md:gap-4 z-50 relative ml-auto flex-1 min-w-0 justify-end`,children:[q&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{ref:Y,"aria-hidden":`true`,className:`flex items-center gap-7 whitespace-nowrap px-1`,style:{position:`fixed`,top:-9999,left:0,visibility:`hidden`,height:0,pointerEvents:`none`},children:G.map((e,n)=>(0,i.jsxs)(`span`,{"data-measure":!0,className:`text-[13px] md:text-[14px] font-bold tracking-wide flex items-center gap-1.5 shrink-0`,children:[e.label,e.submenu&&(0,i.jsx)(t.Pi,{className:`w-3 h-3`})]},n))}),(0,i.jsxs)(`div`,{className:`flex items-center gap-7 mr-6 flex-1 min-w-0 justify-end relative`,ref:J,children:[te.map((e,n)=>(0,i.jsxs)(`div`,{className:`relative shrink-0`,onMouseEnter:()=>v(e.label),onMouseLeave:()=>v(null),children:[e.path?(0,i.jsxs)(c.Link,{to:e.path,className:`text-[13px] md:text-[14px] font-bold tracking-wide text-foreground/50 hover:text-accent transition-all cursor-pointer flex items-center gap-1.5`,children:[e.label,e.submenu&&(0,i.jsx)(t.Pi,{className:`w-3 h-3`})]}):(0,i.jsxs)(`button`,{onClick:e.action,className:`text-[13px] md:text-[14px] font-bold tracking-wide text-foreground/50 hover:text-accent transition-all flex items-center gap-1.5`,children:[e.label,e.submenu&&(0,i.jsx)(t.Pi,{className:`w-3 h-3`})]}),e.submenu&&_===e.label&&(0,i.jsx)(`div`,{className:`absolute top-[100%] left-0 pt-2 z-50`,children:(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:5},animate:{opacity:1,y:0},className:`min-w-[180px] max-h-[300px] overflow-y-auto styled-scrollbars bg-background/95 backdrop-blur-xl border border-[var(--panel-border)] rounded-2xl shadow-xl flex flex-col py-2`,children:e.submenu.map((e,t)=>e.path?(0,i.jsx)(c.Link,{to:e.path,className:`px-5 py-3 text-[13px] font-medium text-foreground/70 hover:text-foreground hover:bg-foreground/5 transition-colors`,children:e.label},t):(0,i.jsx)(`button`,{onClick:e.action,className:`px-5 py-3 text-left w-full text-[13px] font-medium text-foreground/70 hover:text-foreground hover:bg-foreground/5 transition-colors`,children:e.label},t))})})]},`${e.path||`no-path`}-${n}`)),ne.length>0&&(0,i.jsxs)(`div`,{className:`relative flex items-center shrink-0`,onMouseEnter:()=>g(`overflow`),children:[(0,i.jsx)(`button`,{onClick:()=>g(h===`overflow`?!1:`overflow`),"aria-label":`More pages`,"aria-expanded":h===`overflow`,className:`p-1 rounded-lg transition-colors flex items-center ${h===`overflow`?`bg-foreground/5 text-accent`:`text-foreground/50 hover:bg-foreground/5 hover:text-accent`}`,children:(0,i.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`w-5 h-5`,children:[(0,i.jsx)(`circle`,{cx:`12`,cy:`12`,r:`1`}),(0,i.jsx)(`circle`,{cx:`12`,cy:`5`,r:`1`}),(0,i.jsx)(`circle`,{cx:`12`,cy:`19`,r:`1`})]})}),(0,i.jsx)(t.pr,{children:h===`overflow`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>g(!1)}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:5,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:5,scale:.98},className:`absolute top-[100%] pt-1 right-0 min-w-[200px] max-h-[350px] overflow-y-auto styled-scrollbars glass-popover border border-[var(--panel-border)] rounded-2xl flex flex-col py-2 z-50 origin-top-right`,children:ne.map((e,t)=>e.path?(0,i.jsx)(c.Link,{to:e.path,onClick:()=>g(!1),className:`px-5 py-3 text-[13px] font-bold tracking-wide text-foreground/70 hover:text-foreground hover:bg-foreground/5 transition-colors`,children:e.label},t):(0,i.jsx)(`button`,{onClick:()=>{e.action&&e.action(),g(!1)},className:`px-5 py-3 text-left w-full text-[13px] font-bold tracking-wide text-foreground/70 hover:text-foreground hover:bg-foreground/5 transition-colors`,children:e.label},t))})]})})]})]})]}),!n&&!a&&(0,i.jsxs)(i.Fragment,{children:[F&&(0,i.jsx)(`button`,{onClick:j,className:`w-9 h-9 rounded-xl border border-[var(--panel-border)] hover:bg-foreground/5 transition-all text-foreground/60 hover:text-foreground flex items-center justify-center shadow-sm shrink-0 cursor-pointer`,"aria-label":`Toggle Theme`,children:A===`dark`?(0,i.jsx)(t.jr,{className:`w-4 h-4`}):(0,i.jsx)(t.Jr,{className:`w-4 h-4`})}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5 shrink-0`,children:[!ee&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(c.Link,{to:`/login`,className:`flex text-[14px] font-bold tracking-wide text-foreground/80 hover:text-accent transition-colors px-3 py-1.5 shrink-0`,children:`Sign In`}),(0,i.jsx)(c.Link,{to:`/register`,className:`flex text-[13px] md:text-[14px] font-bold tracking-wide px-4 py-1.5 md:px-5 md:py-2 rounded-xl btn-primary transition-all duration-300 hover:shadow-lg hover:-translate-y-0.5 active:scale-95 items-center justify-center ml-2 shrink-0`,children:`Get Started`})]}),ee&&(0,i.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,i.jsx)(`button`,{onClick:()=>g(h===`guest`?!1:`guest`),"aria-label":`Open menu`,"aria-expanded":h===`guest`,className:`w-9 h-9 rounded-xl glass-panel glow-hover border transition-all flex items-center justify-center ${h===`guest`?`border-accent bg-foreground/5`:`border-[var(--panel-border)] hover:bg-foreground/5`}`,children:(0,i.jsx)(t.Yr,{className:`w-5 h-5 text-accent/80`})}),(0,i.jsx)(t.pr,{children:h===`guest`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>g(!1)}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:-10,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,scale:.95},className:`absolute top-full right-0 mt-3 w-[220px] p-2 glass-popover border border-[var(--panel-border)] rounded-2xl z-50 flex flex-col gap-1 origin-top-right`,children:[G.map((e,t)=>{let n=Z(e.path);return e.path?(0,i.jsxs)(c.Link,{to:e.path,onClick:()=>g(!1),className:`flex items-center gap-3 px-3 py-2.5 rounded-xl hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all min-w-0`,children:[(0,i.jsx)(n,{className:`w-4 h-4 text-accent/70 shrink-0`}),` `,(0,i.jsx)(`span`,{className:`text-[14px] font-semibold truncate`,children:e.label})]},`${e.path}-${t}`):(0,i.jsxs)(`button`,{onClick:()=>{e.action&&e.action(),g(!1)},className:`flex items-center gap-3 px-3 py-2.5 rounded-xl hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all w-full text-left min-w-0`,children:[(0,i.jsx)(n,{className:`w-4 h-4 text-accent/70 shrink-0`}),` `,(0,i.jsx)(`span`,{className:`text-[14px] font-semibold truncate`,children:e.label})]},`${e.label}-${t}`)}),(0,i.jsx)(`div`,{className:`pt-2 mt-1 border-t border-[var(--panel-border)]/50 flex flex-col gap-1`,children:(0,i.jsxs)(c.Link,{to:`/login`,onClick:()=>g(!1),className:`flex items-center gap-3 px-3 py-2.5 rounded-xl hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all w-full`,children:[(0,i.jsx)(t.Qr,{className:`w-4 h-4 text-accent/70`}),` `,(0,i.jsx)(`span`,{className:`text-[14px] font-semibold`,children:`Sign In`})]})})]})]})})]})]})]}),!n&&a&&(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5`,children:[d&&!!a&&(0,i.jsx)(O,{}),F&&(0,i.jsx)(`button`,{onClick:j,className:`w-9 h-9 rounded-xl border border-[var(--panel-border)] hover:bg-foreground/5 transition-all text-foreground/60 hover:text-foreground flex items-center justify-center shadow-sm shrink-0 cursor-pointer`,"aria-label":`Toggle Theme`,children:A===`dark`?(0,i.jsx)(t.jr,{className:`w-4 h-4`}):(0,i.jsx)(t.Jr,{className:`w-4 h-4`})}),(0,i.jsxs)(`div`,{className:`relative z-50 flex-shrink-0`,children:[(0,i.jsxs)(`button`,{onClick:()=>g(h===`user`?!1:`user`),className:`flex items-center gap-2 group p-0.5 sm:p-1 sm:pr-2.5 rounded-full hover:bg-foreground/5 transition-all duration-300 cursor-pointer sm:border ${h===`user`?`sm:border-accent/50 sm:bg-foreground/5`:`sm:border-[var(--panel-border)] sm:hover:border-accent/30`}`,children:[(0,i.jsx)(`div`,{className:`w-8 h-8 md:w-9 md:h-9 rounded-full bg-accent/10 flex items-center justify-center overflow-hidden border sm:border-0 transition-colors shrink-0 text-accent ${h===`user`?`border-accent/50`:`border-[var(--panel-border)] group-hover:border-accent/30`}`,children:a.photoURL&&!w?(0,i.jsx)(`img`,{src:a.photoURL,alt:`Profile`,className:`w-full h-full object-cover`,onError:()=>T(!0)}):(0,i.jsx)(t.Sr,{className:`w-4 h-4 md:w-5 md:h-5 text-accent`})}),(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex flex-col text-left mr-1 justify-center min-w-[70px] max-w-[160px]`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-extrabold leading-tight text-foreground truncate w-full`,children:D}),d?(0,i.jsx)(`span`,{className:`text-[10px] font-mono tracking-wider leading-tight text-accent truncate w-full mt-0.5 uppercase font-bold`,children:p===`free`?(0,i.jsx)(ie,{}):m}):(0,i.jsx)(`span`,{className:`h-[10px] w-12 rounded bg-foreground/10 animate-pulse mt-1`,"aria-hidden":`true`})]})]}),(0,i.jsx)(t.pr,{children:h===`user`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>g(!1)}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:-5,scale:.98},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,scale:.98,y:-5},className:`absolute top-full mt-2 right-0 w-[280px] md:w-[320px] glass-popover border border-[var(--panel-border)] rounded-2xl p-2 z-50 flex flex-col origin-top-right`,children:[(0,i.jsxs)(`div`,{className:`p-3 border-b border-[var(--panel-border)]/50 mb-1 flex flex-col gap-1.5`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[15px] text-foreground truncate`,children:D}),(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/50 truncate font-mono`,children:a.email})]}),(0,i.jsxs)(`div`,{className:`py-1`,children:[(0,i.jsxs)(c.Link,{to:`/dashboard`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.ai,{className:`w-3 h-3 text-accent`})}),`Dashboard`]}),f&&(0,i.jsxs)(c.Link,{to:`/assets`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.ui,{className:`w-3 h-3 text-accent`})}),`Assets`]}),s===`admin`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(c.Link,{to:`/users`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.xr,{className:`w-3 h-3 text-accent`})}),`Users`]}),(0,i.jsxs)(c.Link,{to:`/inbox`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.ci,{className:`w-3 h-3 text-accent`})}),`Inbox`]}),(0,i.jsxs)(c.Link,{to:`/pages`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.oi,{className:`w-3 h-3 text-accent`})}),`Pages`]})]}),s!==`admin`&&(0,i.jsxs)(c.Link,{to:`/support`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3 text-left`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.Oi,{className:`w-3 h-3 text-accent`})}),H]}),(0,i.jsx)(Q,{onNavigate:()=>g(!1)}),(0,i.jsxs)(c.Link,{to:`/profile`,onClick:()=>g(!1),className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-semibold tracking-wide hover:bg-foreground/5 text-foreground/80 hover:text-foreground transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.Sr,{className:`w-3 h-3 text-accent`})}),`Profile Settings`]})]}),(0,i.jsx)(`div`,{className:`pt-1 mt-1 border-t border-[var(--panel-border)]/50`,children:(0,i.jsxs)(`button`,{onClick:L,className:`flex items-center w-full px-3 py-2.5 rounded-xl text-[13px] font-bold tracking-wide hover:bg-red-500/10 hover:text-red-500 text-foreground/70 transition-all gap-3`,children:[(0,i.jsx)(`span`,{className:`w-5 h-5 rounded-md bg-red-500/5 flex items-center justify-center shrink-0 text-red-500`,children:(0,i.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`w-3 h-3`,children:[(0,i.jsx)(`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`}),(0,i.jsx)(`polyline`,{points:`16 17 21 12 16 7`}),(0,i.jsx)(`line`,{x1:`21`,y1:`12`,x2:`9`,y2:`12`})]})}),`Sign Out`]})})]})]})})]})]}),n&&(0,i.jsx)(i.Fragment,{children:F&&(0,i.jsx)(`button`,{onClick:j,className:`w-9 h-9 rounded-xl border border-[var(--panel-border)] hover:bg-foreground/5 transition-all text-foreground/60 hover:text-foreground flex items-center justify-center shadow-sm shrink-0 cursor-pointer`,"aria-label":`Toggle Theme`,children:A===`dark`?(0,i.jsx)(t.jr,{className:`w-4 h-4`}):(0,i.jsx)(t.Jr,{className:`w-4 h-4`})})})]})]})}function ce(){let[e,n]=(0,r.useState)(null);return(0,i.jsxs)(`main`,{className:`flex-1 flex flex-col items-center justify-center w-full max-w-5xl mx-auto mt-4 md:mt-12 mb-16 md:mb-24 z-10 relative`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:30},animate:{opacity:1,y:0},transition:{duration:.8},className:`text-center mb-8 md:mb-12`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.9},animate:{opacity:1,scale:1},transition:{delay:.2},className:`inline-flex items-center gap-2 md:gap-3 px-5 md:px-6 py-2 md:py-2.5 mb-8 md:mb-10 text-[13px] md:text-[15px] font-semibold tracking-wide uppercase rounded-full glass-panel text-foreground glow-hover cursor-pointer`,children:[(0,i.jsx)(t.gr,{className:`w-4 h-4 text-accent`}),` The Open-Source Firebase Starter`]}),(0,i.jsx)(t.fr.h1,{className:`text-4xl sm:text-5xl md:text-6xl lg:text-[4.5rem] font-extrabold tracking-tight mb-6 md:mb-8 text-gradient animate-float leading-[1.1] md:leading-[1.15] px-2`,children:`Your AI Firebase`}),(0,i.jsx)(`p`,{className:`text-[14px] sm:text-[15px] md:text-lg lg:text-xl text-foreground/60 max-w-3xl mx-auto font-medium leading-[1.6] md:leading-[1.7] mb-10 md:mb-14 px-6 md:px-4`,children:`A production-ready Firebase backend template with Auth, Firestore prefix rules, and a clean dashboard — ready for vibe-coded apps.`}),(0,i.jsxs)(t.fr.div,{className:`flex flex-col sm:flex-row items-center justify-center gap-4 sm:gap-6 w-full max-w-2xl mx-auto px-6`,initial:{opacity:0},animate:{opacity:1},transition:{delay:.5},children:[(0,i.jsx)(c.Link,{to:`/register`,style:{borderRadius:`var(--btn-radius, 0.75rem)`},className:`w-full sm:w-auto px-6 md:px-8 py-3 md:py-3.5 font-semibold tracking-wide btn-primary text-[15px] shadow-xl transition-all duration-300 hover:-translate-y-1 active:scale-95 flex items-center justify-center`,children:`Start Building Free`}),(0,i.jsx)(c.Link,{to:`/login`,style:{borderRadius:`var(--btn-radius, 0.75rem)`},className:`w-full sm:w-auto px-6 md:px-8 py-3 md:py-3.5 font-semibold tracking-wide btn-secondary text-[15px] transition-all duration-300 flex items-center justify-center hover:-translate-y-1`,children:`Sign In`})]})]}),(0,i.jsx)(t.pr,{children:e&&(0,i.jsx)(t.t,{onClose:()=>n(null),formId:e})})]})}async function le(){if(!t.Sa)throw Error(`Firebase is not initialized. Check your configuration.`);let e=new a.GoogleAuthProvider;try{return await(0,a.signInWithPopup)(t.Sa,e),`done`}catch(n){if(n?.code===`auth/popup-blocked`||n?.code===`auth/popup-closed-by-user`||n?.code===`auth/cancelled-popup-request`){let{signInWithRedirect:n}=await import(`firebase/auth`);return await n(t.Sa,e),`redirecting`}throw n}}function ue(e,t){let n=e?.code||``;return n===`auth/unauthorized-domain`||(e?.message||``).includes(`requested action is invalid`)?`Google Sign-In failed: your app domain is not authorized. Go to Firebase Console → Authentication → Settings → Authorized domains and add your domain (e.g. localhost or your-app.com).`:n===`auth/network-request-failed`?`Network error — please check your internet connection and Firebase configuration.`:e?.message||t}var de=[{id:`length`,label:`At least 8 characters`,ok:e=>e.length>=8},{id:`case`,label:`An uppercase and a lowercase letter`,ok:e=>/[a-z]/.test(e)&&/[A-Z]/.test(e)},{id:`number`,label:`A number`,ok:e=>/[0-9]/.test(e)}],fe=new Set(`password1.password12.password123.password1234.passw0rd1.p@ssword1.p@ssw0rd1.test1234.test12345.testing123.test123456.qwerty123.qwerty1234.abcd1234.abc12345.welcome1.welcome123.admin123.admin1234.letmein123.iloveyou1.monkey123.football1.changeme1.secret123.summer2024.summer2025`.split(`.`)),pe=e=>e.toLowerCase().replace(/[\s._-]/g,``),me=e=>fe.has(pe(e||``)),he=e=>de.map(t=>({rule:t,met:t.ok(e||``)}));function ge(e){let t=e||``;if(!t)return`Choose a password.`;let n=de.find(e=>!e.ok(t));return n?`Your password needs ${n.label.toLowerCase()}.`:me(t)?`That password is one of the first anyone would guess. Please pick another.`:``}function _e(e,t){return t?e===t?``:`Both passwords must be the same.`:`Type your password a second time.`}function ve({value:e,className:n=``}){return(0,i.jsx)(`ul`,{className:`flex flex-col gap-1 ml-1 ${n}`,"aria-label":`Password requirements`,children:he(e).map(({rule:e,met:n})=>(0,i.jsxs)(`li`,{className:`flex items-center gap-2 text-[12.5px] font-medium transition-colors ${n?`text-emerald-500`:`text-foreground/45`}`,children:[n?(0,i.jsx)(t.Fi,{className:`w-3.5 h-3.5 shrink-0`}):(0,i.jsx)(`span`,{className:`w-3.5 flex justify-center shrink-0`,children:(0,i.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-foreground/25`})}),e.label]},e.id))})}function ye(){let[e,n]=(0,r.useState)(!1),[a,o]=(0,r.useState)(null),[s,l]=(0,r.useState)(``),[u,d]=(0,r.useState)(``),[f,p]=(0,r.useState)(``),[m,h]=(0,r.useState)(``),g=(0,c.useNavigate)(),{registerUser:_}=t.Qi();return(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mt-6 mb-8 md:mt-0 md:mb-0 md:pt-8 md:pb-32`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.5},className:`w-full max-w-[500px] p-5 sm:p-8 lg:p-10 rounded-3xl md:rounded-3xl glass-panel relative glow-hover shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-30 blur-[20px] rounded-3xl md:rounded-3xl -z-10`}),(0,i.jsxs)(`div`,{className:`mb-5 sm:mb-6 text-center`,children:[(0,i.jsx)(`h3`,{className:`text-[21px] sm:text-3xl font-extrabold mb-1.5 sm:mb-2 text-foreground tracking-tight`,children:`Create an account`}),(0,i.jsx)(`p`,{className:`text-[13.5px] md:text-[15px] font-medium text-foreground/60 tracking-wide`,children:`Join Your AI Firebase and start building today.`})]}),a&&(0,i.jsx)(`div`,{className:`p-3 mb-6 text-[14px] font-medium text-red-400 bg-red-500/10 rounded-xl border border-red-500/20`,children:a}),(0,i.jsxs)(`form`,{className:`space-y-3.5 sm:space-y-4`,onSubmit:async e=>{e.preventDefault(),n(!0),o(null);let t=new FormData(e.currentTarget),r=t.get(`email`),a=t.get(`firstName`),l=t.get(`lastName`),d=ge(s),f=d?``:_e(s,u);if(p(d),h(f),d||f){o(d||f),n(!1);return}try{await _(r,s,a,l),g(`/verify`)}catch(e){e?.code===`auth/email-already-in-use`?o((0,i.jsxs)(`span`,{children:[`An account with this email already exists.`,` `,(0,i.jsx)(c.Link,{to:`/login?email=${encodeURIComponent(r)}`,className:`font-bold underline hover:text-accent transition-colors`,children:`Sign in?`})]})):e?.code===`auth/weak-password`?o(ge(s)||`Please choose a stronger password.`):o(e?.message||`An error occurred during registration.`)}finally{n(!1)}},children:[(0,i.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-3.5 sm:gap-4`,children:[(0,i.jsx)(t.lr,{name:`firstName`,label:`First Name`,type:`text`,placeholder:`John`,className:`max-sm:h-11`,required:!0}),(0,i.jsx)(t.lr,{name:`lastName`,label:`Last Name`,type:`text`,placeholder:`Doe`,className:`max-sm:h-11`,required:!0})]}),(0,i.jsx)(t.lr,{name:`email`,label:`Email`,type:`email`,placeholder:`name@example.com`,className:`max-sm:h-11`,required:!0}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[(0,i.jsx)(t.lr,{name:`password`,label:`Password`,type:`password`,placeholder:`••••••••`,className:`max-sm:h-11`,autoComplete:`new-password`,value:s,onChange:e=>{l(e.target.value),f&&p(``),m&&e.target.value===u&&h(``)},onBlur:()=>p(s?ge(s):``),error:f,required:!0}),s&&(0,i.jsx)(ve,{value:s})]}),s&&(0,i.jsx)(t.lr,{name:`confirmPassword`,label:`Confirm password`,type:`password`,placeholder:`••••••••`,className:`max-sm:h-11`,autoComplete:`new-password`,value:u,onChange:e=>{d(e.target.value),m&&h(``)},onBlur:()=>h(u?_e(s,u):``),error:m,required:!0}),(0,i.jsx)(`div`,{className:`pt-2`,children:(0,i.jsxs)(t.cr,{type:`submit`,className:`w-full py-2.5 sm:py-3 text-[15px] font-bold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,isLoading:e,children:[`Create Account `,(0,i.jsx)(t.Ki,{className:`ml-2 w-4 h-4 group-hover:translate-x-1 transition-transform shrink-0`})]})})]}),(0,i.jsxs)(`div`,{className:`mt-5 pt-4 sm:mt-6 sm:pt-5 border-t border-[var(--panel-border)] space-y-4 text-center`,children:[(0,i.jsxs)(t.cr,{variant:`secondary`,onClick:async()=>{n(!0),o(null);try{await le()}catch(e){o(ue(e,`Google sign-up failed.`))}finally{n(!1)}},className:`w-full py-2.5 sm:py-3 text-[15px] font-bold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,disabled:e,children:[(0,i.jsxs)(`svg`,{className:`w-5 h-5 mr-3`,viewBox:`0 0 24 24`,children:[(0,i.jsx)(`path`,{fill:`currentColor`,d:`M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z`})]}),`Sign up with Google`]}),(0,i.jsxs)(`p`,{className:`text-[13.5px] sm:text-[14px] text-foreground/70 font-medium pt-1 sm:pt-2 tracking-wide`,children:[`Already have an account? `,(0,i.jsx)(c.Link,{to:`/login`,className:`text-accent hover:underline font-bold ml-1`,children:`Sign in`})]})]})]})})}function be(){let[e,n]=(0,r.useState)(!1),[o,s]=(0,r.useState)(null),[l]=(0,c.useSearchParams)(),u=(0,c.useNavigate)(),[d]=(0,r.useState)(l.get(`email`)||``);return(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mt-6 mb-8 md:mt-0 md:mb-0 md:pt-8 md:pb-32`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.5},className:`w-full max-w-[480px] p-5 sm:p-8 lg:p-10 rounded-3xl md:rounded-3xl glass-panel relative glow-hover shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-30 blur-[20px] rounded-3xl md:rounded-3xl -z-10`}),(0,i.jsxs)(`div`,{className:`mb-5 sm:mb-6 text-center`,children:[(0,i.jsx)(`h3`,{className:`text-[21px] sm:text-3xl font-extrabold mb-1.5 sm:mb-2 text-foreground tracking-tight`,children:`Welcome back`}),(0,i.jsx)(`p`,{className:`text-[13.5px] md:text-[15px] font-medium text-foreground/60 tracking-wide`,children:`Sign in to Your AI Firebase.`})]}),o&&(0,i.jsx)(`div`,{className:`p-3 mb-6 text-[14px] font-medium text-red-400 bg-red-500/10 rounded-xl border border-red-500/20`,children:o}),(0,i.jsxs)(`form`,{className:`space-y-3.5 sm:space-y-4`,onSubmit:async e=>{e.preventDefault(),n(!0),s(null);let r=new FormData(e.currentTarget),o=r.get(`email`),d=r.get(`password`);try{if(!t.Sa)throw Error(`Firebase is not initialized. Check your configuration.`);await(0,a.signInWithEmailAndPassword)(t.Sa,o,d),u(l.get(`from`)||`/dashboard`,{replace:!0})}catch(e){e?.code===`auth/invalid-credential`||e?.code===`auth/user-not-found`||e?.code===`auth/wrong-password`?s((0,i.jsxs)(`span`,{children:[`Email or Password are incorrect.`,` `,(0,i.jsx)(c.Link,{to:`/reset-password`,className:`font-bold underline hover:text-red-400 transition-colors`,children:`Reset password?`})]})):e?.code===`auth/network-request-failed`?s(`Network error — please check your internet connection and Firebase configuration.`):s(e?.message||`Invalid credentials.`),n(!1)}},children:[(0,i.jsx)(t.lr,{name:`email`,label:`Email`,type:`email`,defaultValue:d,placeholder:`name@example.com`,className:`max-sm:h-11`,required:!0}),(0,i.jsxs)(`div`,{className:`space-y-2`,children:[(0,i.jsxs)(`div`,{className:`flex justify-between items-center pr-1`,children:[(0,i.jsx)(`label`,{className:`text-[14px] md:text-[15px] tracking-wide font-medium text-foreground/80 select-none pb-1`,children:`Password`}),(0,i.jsx)(c.Link,{to:`/reset-password`,className:`text-[13px] md:text-[14px] text-accent hover:underline font-bold tracking-wide`,children:`Forgot Password?`})]}),(0,i.jsx)(t.lr,{name:`password`,type:`password`,placeholder:`••••••••`,className:`max-sm:h-11`,required:!0})]}),(0,i.jsx)(`div`,{className:`pt-2`,children:(0,i.jsxs)(t.cr,{type:`submit`,className:`w-full py-2.5 sm:py-3 text-[15px] sm:text-base font-bold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,isLoading:e,children:[`Sign In `,(0,i.jsx)(t.Ki,{className:`ml-2 w-4 h-4 group-hover:translate-x-1 transition-transform shrink-0`})]})})]}),(0,i.jsxs)(`div`,{className:`mt-5 pt-4 sm:mt-6 sm:pt-5 border-t border-[var(--panel-border)] space-y-4 text-center`,children:[(0,i.jsxs)(t.cr,{variant:`secondary`,onClick:async()=>{n(!0),s(null);try{if(await le()===`redirecting`)return;u(l.get(`from`)||`/dashboard`,{replace:!0})}catch(e){s(ue(e,`Google sign-in failed.`))}finally{n(!1)}},className:`w-full py-2.5 sm:py-3 text-[15px] sm:text-base font-bold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,disabled:e,children:[(0,i.jsxs)(`svg`,{className:`w-5 h-5 mr-3`,viewBox:`0 0 24 24`,children:[(0,i.jsx)(`path`,{fill:`currentColor`,d:`M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z`}),(0,i.jsx)(`path`,{fill:`currentColor`,d:`M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z`})]}),`Sign in with Google`]}),(0,i.jsxs)(`p`,{className:`text-[13.5px] sm:text-[14px] text-foreground/70 font-medium pt-1 sm:pt-2 tracking-wide`,children:[`New here? `,(0,i.jsx)(c.Link,{to:`/register`,className:`text-accent hover:underline font-bold ml-1`,children:`Create account`})]})]})]})})}function xe(){let{user:e,refreshUser:n}=t.Qi(),o=(0,c.useNavigate)(),[s,l]=(0,r.useState)(!1),[u,d]=(0,r.useState)(!1),[f,p]=(0,r.useState)(``);return(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mb-16`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.5},className:`w-full max-w-[480px] p-6 md:p-8 lg:p-10 rounded-3xl glass-panel relative glow-hover text-center shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-30 blur-[20px] rounded-3xl -z-10`}),(0,i.jsx)(`div`,{className:`w-14 h-14 md:w-16 md:h-16 rounded-2xl glass-panel border border-[var(--panel-border)] flex items-center justify-center mx-auto mb-5 md:mb-6 animate-float shadow-xl`,children:(0,i.jsx)(t.Xr,{className:`w-7 h-7 md:w-8 md:h-8 text-accent opacity-90`})}),(0,i.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold mb-3 text-foreground tracking-tight`,children:`Verify your email`}),(0,i.jsxs)(`p`,{className:`text-[14px] md:text-[15px] text-foreground/60 mb-6 md:mb-8 leading-[1.6] tracking-wide`,children:[`We've sent a verification link to `,(0,i.jsx)(`span`,{className:`font-semibold text-foreground`,children:e?.email}),`. Please check your inbox (and spam folder) to verify your account and access your dashboard.`]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 max-w-[360px] mx-auto`,children:[f&&(0,i.jsx)(`div`,{role:`status`,className:`w-full px-4 py-2.5 md:py-3 text-[13px] md:text-[14px] font-semibold leading-snug rounded-xl border ${f.includes(`Failed`)||f.includes(`not verified`)||f.includes(`wrong`)?`text-red-400 bg-red-500/10 border-red-500/20`:`text-emerald-400 bg-emerald-500/10 border-emerald-500/20`}`,children:f}),(0,i.jsx)(t.cr,{variant:`primary`,onClick:async()=>{l(!0),p(``);try{if(t.Sa.currentUser){if(await t.Sa.currentUser.reload(),!t.Sa.currentUser.emailVerified){p(`Email is not verified yet. Please check your inbox.`),l(!1);return}await t.Sa.currentUser.getIdToken(!0),await n(),o(`/dashboard`)}}catch{p(`Something went wrong. Please try again.`),l(!1)}},isLoading:s,className:`w-full py-2.5 md:py-3 text-[14px] font-bold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,children:`I've verified my email`}),(0,i.jsx)(t.cr,{variant:`ghost`,onClick:async()=>{if(e){d(!0),p(``);try{await(0,a.sendEmailVerification)(e),p(`Verification email sent! Please check your inbox.`)}catch(e){e?.code===`auth/too-many-requests`?p(`Failed to resend: Please wait a minute before trying again.`):p(e?.message||`Failed to resend. Please try again later.`)}finally{d(!1)}}},isLoading:u,className:`w-full py-2.5 md:py-3 text-[13px] md:text-[14px] font-semibold tracking-wide rounded-xl transition-all hover:-translate-y-0.5`,children:`Resend verification link`})]})]})})}var Se=.72;function Ce(e){let t=(0,r.useRef)(null);return(0,r.useLayoutEffect)(()=>{let e=t.current,n=e?.parentElement;if(!e||!n)return;let r=()=>{e.style.removeProperty(`font-size`),e.removeAttribute(`data-fold`);let t=n.clientWidth,r=e.scrollWidth;if(!t||r<=t)return;let i=parseFloat(window.getComputedStyle(e).fontSize)||24,a=t/r;e.style.setProperty(`font-size`,`${(i*Math.max(a,Se)).toFixed(2)}px`,`important`),a<.72&&e.setAttribute(`data-fold`,``)};if(r(),document.fonts?.ready.then(r).catch(()=>{}),typeof ResizeObserver>`u`)return;let i=new ResizeObserver(r);return i.observe(n),()=>i.disconnect()},e),t}var we=({className:e,children:n,...r})=>(0,i.jsx)(`h1`,{ref:Ce([n]),className:t.ur(`page-title w-fit inline-block tracking-tight mb-3 mt-1 text-gradient`,e),...r,children:n});we.displayName=`PageTitle`;var Te=/^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i,Ee=e=>{let t=String(e??``).trim();return Te.test(t)?t:``};function De(e,t){let n=String(e??``).trim();if(!n||/^data:/i.test(n))return``;try{let e=new URL(n,t||void 0);return/^https?:$/.test(e.protocol)?e.href:``}catch{return``}}function Oe(e,t){let n=e?.colors?.light||{},r=Array.isArray(n.buttonGradient)?n.buttonGradient.map(Ee).filter(Boolean).slice(0,2):[];return{appName:String(e?.appName||``).replace(/\s+/g,` `).trim().slice(0,60),logoUrl:De(e?.logoUrl,t),appUrl:De(t,``),accent:Ee(n.accent),foreground:Ee(n.foreground),buttonText:Ee(n.buttonText),buttonGradient:r,panelBg:Ee(n.panelBg),panelBorder:Ee(n.panelBorder)}}function ke(e){return{appName:String(e?.appName||``),logoUrl:String(e?.logoUrl||``),appUrl:String(e?.appUrl||``),accent:String(e?.accent||``),foreground:String(e?.foreground||``),buttonText:String(e?.buttonText||``),buttonGradient:Array.isArray(e?.buttonGradient)?e.buttonGradient.map(String):[],panelBg:String(e?.panelBg||``),panelBorder:String(e?.panelBorder||``)}}var Ae=``,je=e=>/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/i.test(e);function Me(){let e=null;try{e=t.Da().activeConfig}catch{e=null}let n=!!t.Qi()?.isAdmin,i=typeof window<`u`?window.location.origin:``,a=e&&n?JSON.stringify(Oe(e,i)):``;(0,r.useEffect)(()=>{if(!a||!t.Ca||a===Ae)return;let e=!1;return(async()=>{try{let n=(0,o.doc)(t.Ca,`sys_configs`,`emailBrand`),r=await(0,o.getDoc)(n);if(e)return;let s=r.exists()?ke(r.data()):null,c=JSON.parse(a);je(i)&&s?.appUrl&&(c.appUrl=s.appUrl),(!s||JSON.stringify(s)!==JSON.stringify(c))&&await(0,o.setDoc)(n,c),Ae=a}catch{}})(),()=>{e=!0}},[a])}var Ne=t.va(`admin`),Pe={inbox:{path:`/inbox`,label:`Inbox`,icon:t.ci,roles:Ne},users:{path:`/users`,label:`Users`,icon:t.xr,roles:Ne},pages:{path:`/pages`,label:`Pages`,icon:t.oi,roles:Ne},schedule:{path:`/schedule`,label:`Schedule`,icon:t.Bi,roles:t.va(`internal`)},mybookings:{path:`/my-bookings`,label:`My bookings`,icon:t.Vi,roles:t.va(`user`)},payments:{path:`/payments`,label:`Payments`,icon:t.xi,roles:Ne},email:{path:`/email`,label:`Email`,icon:t.Xr,roles:Ne},forms:{path:`/forms`,label:`Forms`,icon:t.zr,roles:Ne},theme:{path:`/theme`,label:`Theme`,icon:t.qr,roles:Ne},assets:{path:`/assets`,label:`Assets`,icon:t.ui,roles:Ne},publish:{path:`/publish`,label:`Publish App`,icon:t.Rr,roles:Ne}};function Fe(e){try{let t=localStorage.getItem(e);return t?JSON.parse(t):null}catch{return null}}function Ie({customTabs:e=[]}){let{pathname:n}=(0,c.useLocation)(),{user:a,userRole:s,roleResolved:l}=t.Qi();Me();let u=t.v(``,a?.email||``).bookings.length>0,[d,f]=(0,r.useState)(!1),p=(0,r.useRef)(null),[m,h]=(0,r.useState)(()=>Fe(`fbos_nav_tabs`)??{}),[g,_]=(0,r.useState)(()=>{let e=Fe(`fbos_nav_order`);return Array.isArray(e)?M(e):N}),[v,y]=(0,r.useState)(()=>Fe(`fbos_nav_tabs`)!==null),[x,S]=(0,r.useState)(()=>Fe(`fbos_nav_order`)!==null);(0,r.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(t.Ca,`sys_tabs`),e=>{let t={};e.forEach(e=>{t[e.id]=e.data()}),h(t),y(!0),localStorage.setItem(`fbos_nav_tabs`,JSON.stringify(t))},e=>{console.warn(`sys_tabs snapshot error:`,e),y(!0)}),n=(0,o.onSnapshot)((0,o.doc)(t.Ca,`sys_configs`,`tab_order`),e=>{let t=e.exists()&&Array.isArray(e.data().order)?M(e.data().order):N;_(t),S(!0),localStorage.setItem(`fbos_nav_order`,JSON.stringify(t))},e=>{console.warn(`tab_order snapshot error:`,e),S(!0)}),r=setTimeout(()=>{y(!0),S(!0)},3e3);return()=>{e(),n(),clearTimeout(r)}},[]);let C=l!==!1&&v&&x;(0,r.useEffect)(()=>{function e(e){p.current&&!p.current.contains(e.target)&&f(!1)}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let w=[...(()=>{let e={};Object.entries(Pe).forEach(([t,n])=>{t===`mybookings`&&!u||(e[t]={id:t,...n,exact:!0})});let n={...m};for(let[e,t]of b())t.isPublic||(n[e]={...t.config,...m[e]});Object.entries(n).forEach(([n,r])=>{let i=e[n],a=i?.icon??t.oi;if(r?.iconName){let e=r.iconName.trim(),n=e.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);t.mr[n]?a=t.mr[n]:t.mr[e]&&(a=t.mr[e])}let o=i?.roles??Ne;r?.pageType&&(o=t.ba(r)),e[n]={id:n,path:r?.route?r.route.startsWith(`/`)?r.route:`/`+r.route:i?.path??`/`+n,label:r?.tabName||r?.pageTitle||r?.pageName||i?.label||n,icon:a,roles:o,exact:!0}});let r=[],i=new Set;g.forEach(t=>{t.hidden||i.has(t.id)||e[t.id]&&(r.push(e[t.id]),i.add(t.id))});let a=[],o=[];return Object.keys(e).forEach(t=>{if(i.has(t))return;let r=g.find(e=>e.id===t);r?.hidden||(t in n&&!r?a.push(e[t]):o.push(e[t]))}),a.length>0&&r.unshift(...a),o.length>0&&r.push(...o),r})(),...e.map(e=>({...e,id:e.path}))].filter(e=>{let n=t.xa(s,!!a);return t.ya(e.roles,n)}),{rowRef:T,measureRef:E,visible:D}=I({count:w.length,listKey:w.map(e=>e.id+e.label).join(`|`),shown:C&&w.length>0,gap:40,moreButtonWidth:52}),O=w.slice(0,D),k=w.slice(D),A=e=>e.exact?n===e.path:n.startsWith(e.path),j=k.some(e=>A(e));return C?w.length===0?null:(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{ref:E,"aria-hidden":`true`,className:`flex items-center gap-5 md:gap-10 whitespace-nowrap px-1`,style:{position:`fixed`,top:-9999,left:0,visibility:`hidden`,pointerEvents:`none`},children:w.map((e,t)=>{let n=e.icon;return(0,i.jsxs)(`span`,{"data-measure":!0,className:`flex items-center gap-2 text-[13px] md:text-[14.5px] font-semibold shrink-0 pb-2.5 md:pb-3`,children:[(0,i.jsx)(n,{className:`w-4 h-4 md:w-[18px] md:h-[18px]`}),e.label]},t)})}),(0,i.jsxs)(`div`,{ref:T,className:`w-full flex items-center gap-5 md:gap-10 mb-5 border-b border-[var(--panel-border)] px-1 whitespace-nowrap relative`,children:[O.map(e=>{let t=A(e),n=e.icon;return(0,i.jsxs)(c.Link,{to:e.path||`/`,className:`flex items-center gap-2 text-[13px] md:text-[14.5px] font-semibold transition-all duration-300 pb-2.5 md:pb-3 -mb-[1px] border-b-2 shrink-0 ${t?`text-accent border-accent`:`text-foreground/50 hover:text-foreground/80 border-transparent`}`,children:[(0,i.jsx)(n,{className:`w-4 h-4 md:w-[18px] md:h-[18px]`}),e.label]},e.path||e.id)}),k.length>0&&(0,i.jsxs)(`div`,{className:`relative shrink-0 ml-auto`,ref:p,children:[(0,i.jsx)(`button`,{onClick:()=>f(!d),className:`flex items-center justify-center transition-all duration-300 pb-2.5 md:pb-3 -mb-[1px] border-b-2 cursor-pointer ${j?`text-accent border-accent`:`text-foreground/50 hover:text-foreground/80 border-transparent`}`,title:`More items`,children:(0,i.jsx)(t.vi,{className:`w-[18px] h-[18px] md:w-5 md:h-5`})}),(0,i.jsx)(t.pr,{children:d&&(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},exit:{opacity:0,y:10},className:`absolute top-[100%] right-0 mt-2 min-w-[200px] glass-popover border border-[var(--panel-border)] rounded-2xl z-50 flex flex-col py-2 overflow-hidden`,children:k.map(e=>{let t=A(e),n=e.icon;return(0,i.jsxs)(c.Link,{to:e.path||`/`,onClick:()=>f(!1),className:`flex items-center gap-3 px-5 py-3 text-[14px] font-medium transition-colors ${t?`text-accent bg-accent/5`:`text-foreground/70 hover:text-foreground hover:bg-foreground/5`}`,children:[(0,i.jsx)(n,{className:`w-4 h-4`}),e.label]},e.path||e.id)})})})]})]})]}):(0,i.jsx)(`div`,{className:`w-full flex items-center gap-5 md:gap-10 mb-5 border-b border-[var(--panel-border)] px-1 whitespace-nowrap relative`,children:[56,72,64].map((e,t)=>(0,i.jsxs)(`span`,{className:`flex items-center gap-2 pb-2.5 md:pb-3 h-[30px] md:h-[33px] shrink-0`,"aria-hidden":`true`,children:[(0,i.jsx)(`span`,{className:`w-4 h-4 md:w-[18px] md:h-[18px] rounded-md bg-foreground/5 animate-pulse`}),(0,i.jsx)(`span`,{className:`h-3.5 rounded bg-foreground/5 animate-pulse`,style:{width:e}})]},t))})}function Le(){let{user:e,refreshUser:n,isInternal:c}=t.Qi(),[l,u]=(0,r.useState)(e?.displayName||``),[d,f]=(0,r.useState)(e?.email||``),[p,m]=(0,r.useState)(e?.photoURL||``),[h,g]=(0,r.useState)(!1),[_,v]=(0,r.useState)(null),[y,b]=(0,r.useState)(``),[x,S]=(0,r.useState)(``),[C,w]=(0,r.useState)(``),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(!1),[k,A]=(0,r.useState)(!0);r.default.useEffect(()=>{u(e?.displayName||``),f(e?.email||``),m(e?.photoURL||``)},[e?.uid,e?.displayName,e?.email,e?.photoURL]);let j=async n=>{if(e)try{if(!c)return;let r=[`mem_files`,`admin_files`];(await(0,o.getDocs)((0,o.collection)(t.Ca,`sys_tabs`))).forEach(e=>{let n=e.data(),i=(n.tabName||e.id).toLowerCase().replace(/[^a-z0-9]+/g,`_`),a=t.fa(n.pageType);a===`internal`&&r.push(`mem_${i}_records`),a===`admin`&&r.push(`admin_${i}_records`)});for(let i of r)try{let r=await(0,o.getDocs)((0,o.query)((0,o.collection)(t.Ca,i),(0,o.where)(`uid`,`==`,e.uid)));if(r.empty)continue;let a=(0,o.writeBatch)(t.Ca);r.docs.forEach(e=>a.update(e.ref,{creatorAvatar:n})),await a.commit()}catch{}}catch(e){console.error(`Error propagating avatar to records:`,e)}},M=async r=>{if(!e)return;let i=await t.or(r,{maxSide:512});if(i.size>2*1024*1024){v({text:`File too large. Please select an image under 2MB.`,type:`error`});return}O(!0),E(!1),A(!0);try{let r=(0,s.ref)(t.Ta,`user_avatars/${e.uid}/file.png`);await(0,s.uploadBytes)(r,i,{customMetadata:{ownerId:e.uid}});let c=await(0,s.getDownloadURL)(r);m(c);let l=(0,o.doc)(t.Ca,`user_profiles`,e.uid);await Promise.all([(0,a.updateProfile)(e,{photoURL:c}),(0,o.updateDoc)(l,{avatar:c}),j(c)]),await n(),v({text:`Avatar successfully updated!`,type:`success`})}catch(e){console.error(e),v({text:`Failed to upload photo.`,type:`error`})}finally{O(!1)}},N=e=>{let t=e.target.files?.[0];t&&M(t)},{over:P,dropProps:F}=t.er({accept:`image/*`,disabled:D,onFiles:([e])=>M(e),onReject:()=>v({text:`That is not a picture. Drop a JPG or a PNG.`,type:`error`})}),I=async()=>{if(e){O(!0),E(!1),A(!1);try{let r=(0,s.ref)(t.Ta,`user_avatars/${e.uid}/file.png`);m(``),O(!1);let i=(0,o.doc)(t.Ca,`user_profiles`,e.uid);await Promise.all([(0,s.deleteObject)(r).catch(e=>console.error(e)),(0,a.updateProfile)(e,{photoURL:``}),(0,o.updateDoc)(i,{avatar:``}),j(``)]),await n(),v({text:`Avatar removed.`,type:`success`})}catch(e){console.error(e),v({text:`Failed to delete photo.`,type:`error`}),O(!1)}}};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-5 sm:mb-8`,children:[(0,i.jsx)(we,{children:`Profile Settings`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/profile`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-6 animate-in fade-in duration-500 pb-20`,children:[(0,i.jsx)(`div`,{className:`flex justify-start`,children:(0,i.jsx)(Ie,{})}),(0,i.jsx)(t.pr,{children:_&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.98,y:-10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.98,y:-10},className:`p-4 mb-6 rounded-2xl border flex flex-col sm:flex-row sm:items-center gap-3 ${_.type===`error`?`bg-red-500/10 border-red-500/20 text-red-400`:`bg-accent/10 border-accent/20 text-accent`}`,children:[_.type===`success`?(0,i.jsx)(t.ki,{className:`w-5 h-5 shrink-0`}):(0,i.jsx)(t.Ai,{className:`w-5 h-5 shrink-0`}),(0,i.jsx)(`span`,{className:`text-[14px] font-semibold tracking-wide leading-relaxed`,children:_.text})]})}),(0,i.jsx)(`form`,{onSubmit:async r=>{if(r.preventDefault(),e){g(!0),v(null);try{l!==e.displayName&&await(0,a.updateProfile)(e,{displayName:l});let r=!1;if(d!==e.email){let n=await(0,a.fetchSignInMethodsForEmail)(t.Sa,d);if(n&&n.length>0)throw Error(`An account with this email already exists.`);await(0,a.verifyBeforeUpdateEmail)(e,d),r=!0}if(y){let t=ge(y);if(t)throw Error(t);let n=_e(y,x);if(n)throw w(n),Error(n);await(0,a.updatePassword)(e,y),b(``),S(``),w(``)}await n(),v(r?{text:`Profile updated. A verification link has been sent to your new email address.`,type:`success`}:{text:`Profile successfully updated.`,type:`success`})}catch(e){console.error(e),e.code===`auth/requires-recent-login`?v({text:`For security, please sign out and sign back in before changing your email or password.`,type:`error`}):v({text:e.message||`Failed to update profile.`,type:`error`})}finally{g(!1)}}},className:`w-full flex flex-col`,children:(0,i.jsxs)(`div`,{className:`glass-panel w-full p-5 sm:p-8 md:p-12 rounded-3xl border border-[var(--panel-border)] shadow-2xl space-y-8 md:min-h-[500px]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-4 sm:gap-5 pb-6 border-b border-[var(--panel-border)]/50`,children:[(0,i.jsxs)(`div`,{...F,className:`relative shrink-0 group/avatar rounded-full transition-shadow ${P?`ring-2 ring-accent ring-offset-2 ring-offset-background`:``}`,children:[(0,i.jsxs)(`div`,{className:`w-16 h-16 sm:w-20 sm:h-20 rounded-full glass-panel border-2 border-[var(--panel-border)] shadow-lg bg-accent/10 flex items-center justify-center relative overflow-hidden`,children:[(D||p&&k&&!T)&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center bg-accent/5 backdrop-blur-sm z-10`,children:(0,i.jsx)(t.ei,{className:`w-6 h-6 text-accent animate-spin`})}),p&&!T?(0,i.jsx)(`img`,{src:p,alt:`Avatar`,className:`w-full h-full object-cover transition-opacity duration-300 ${k?`opacity-0`:`opacity-100`}`,onLoad:()=>A(!1),onError:()=>{E(!0),A(!1)}}):(0,i.jsx)(t.Sr,{className:`w-7 h-7 sm:w-8 sm:h-8 text-accent`})]}),!D&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`label`,{title:p?`Change photo`:`Upload photo`,className:`absolute inset-0 rounded-full bg-background/60 backdrop-blur-[2px] opacity-0 group-hover/avatar:opacity-100 focus-within:opacity-100 flex items-center justify-center cursor-pointer transition-opacity z-20`,children:[(0,i.jsx)(t.Ii,{className:`w-4 h-4 text-foreground`}),(0,i.jsx)(`input`,{type:`file`,accept:`image/*`,"aria-label":`Upload photo`,onChange:N,className:`hidden`})]}),p&&(0,i.jsx)(`button`,{type:`button`,onClick:I,title:`Remove photo`,"aria-label":`Remove photo`,className:`hidden group-hover/avatar:flex absolute -top-1 -right-1 w-6 h-6 rounded-full bg-background border border-[var(--panel-border)] text-foreground/50 hover:text-red-500 hover:border-red-500/40 items-center justify-center shadow-sm cursor-pointer z-30`,children:(0,i.jsx)(t.Or,{className:`w-3 h-3`})})]})]}),(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h3`,{className:`font-extrabold text-lg sm:text-xl text-foreground mb-1 truncate`,children:l||`User`}),(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/40 mt-1 font-medium break-words`,children:e?.email})]})]}),(0,i.jsxs)(`div`,{className:`space-y-6`,children:[(0,i.jsx)(`h3`,{className:`text-[16px] font-extrabold text-foreground flex items-center gap-2`,children:`Account Details`}),(0,i.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-5 md:gap-6`,children:[(0,i.jsx)(t.lr,{name:`name`,value:l,onChange:e=>u(e.target.value),label:`Display Name`,placeholder:`John Doe`}),(0,i.jsxs)(`div`,{className:`flex flex-col`,children:[(0,i.jsx)(t.lr,{name:`email`,type:`email`,value:d,onChange:e=>f(e.target.value),label:`Email Address`,placeholder:`name@example.com`,required:!0}),(0,i.jsx)(`p`,{className:`text-[11px] text-foreground/40 mt-1.5 px-2 font-medium`,children:`Changing email sends a verification link to the new address.`})]})]})]}),(0,i.jsxs)(`div`,{className:`pt-6 border-t border-[var(--panel-border)]/50`,children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-bold text-foreground mb-4 flex items-center gap-2`,children:`Change Password`}),(0,i.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-5 md:gap-6`,children:[(0,i.jsx)(t.lr,{name:`password`,type:`password`,label:`New Password`,autoComplete:`new-password`,value:y,onChange:e=>{b(e.target.value),C&&e.target.value===x&&w(``)},placeholder:`At least 8 characters`}),(0,i.jsx)(t.lr,{name:`confirmPassword`,type:`password`,label:`Confirm New Password`,autoComplete:`new-password`,value:x,onChange:e=>{S(e.target.value),C&&w(``)},onBlur:()=>w(x?_e(y,x):``),error:C,placeholder:`Type it a second time`})]}),y&&(0,i.jsx)(ve,{value:y,className:`mt-3`})]}),(0,i.jsx)(`div`,{className:`pt-6 md:pt-8 border-t border-[var(--panel-border)]/50 flex justify-start w-full`,children:(0,i.jsx)(t.cr,{type:`submit`,isLoading:h,className:`w-full sm:w-auto sm:px-12 py-3 md:py-2.5 text-[14px] md:text-[15px] font-bold tracking-wide rounded-xl hover:-translate-y-0.5`,children:`Save Changes`})})]})})]})]})}function Re(){let[e,n]=(0,r.useState)(!1),[o,s]=(0,r.useState)(null),[l,u]=(0,r.useState)(0),[d,f]=(0,r.useState)(0);return(0,r.useEffect)(()=>{let e;return l>0&&(e=setInterval(()=>u(e=>e-1),1e3)),()=>clearInterval(e)},[l]),(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mb-16 mt-6 md:mt-0 md:mb-0 md:pt-8 md:pb-32`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.5},className:`w-full max-w-[480px] p-6 md:p-8 lg:p-10 rounded-3xl glass-panel relative glow-hover shadow-[0_8px_32px_rgba(0,0,0,0.08)] text-center`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-40 blur-[15px] rounded-3xl -z-10`}),(0,i.jsx)(`div`,{className:`w-14 h-14 md:w-16 md:h-16 rounded-2xl glass-panel border border-[var(--panel-border)] flex items-center justify-center mx-auto mb-5 md:mb-6 animate-float shadow-xl`,children:(0,i.jsx)(t.si,{className:`w-7 h-7 md:w-8 md:h-8 text-accent opacity-90`})}),(0,i.jsxs)(`div`,{className:`mb-6 text-center`,children:[(0,i.jsx)(`h3`,{className:`text-2xl md:text-3xl font-extrabold mb-2 md:mb-3 text-foreground tracking-tight`,children:`Reset Password`}),(0,i.jsx)(`p`,{className:`text-[14px] md:text-[15px] font-medium text-foreground/60 tracking-wide`,children:`Enter your email to receive a recovery link.`})]}),o&&(0,i.jsx)(`div`,{className:`p-3 md:p-4 mb-5 md:mb-6 text-[13px] md:text-[14px] font-medium text-emerald-400 bg-emerald-500/10 rounded-xl border border-emerald-500/20 max-w-[360px] mx-auto`,children:o}),(0,i.jsxs)(`form`,{className:`space-y-4 text-left max-w-[360px] mx-auto`,onSubmit:async e=>{e.preventDefault(),n(!0),s(null);let r=new FormData(e.currentTarget).get(`email`);try{await(0,a.sendPasswordResetEmail)(t.Sa,r)}catch(e){console.error(e)}finally{s(`If an account exists, a reset link has been sent. Check your inbox and spam folder.`);let e=d+1;f(e),u(e===1?60:120),n(!1)}},children:[(0,i.jsx)(t.lr,{name:`email`,label:`Work Email`,type:`email`,placeholder:`name@company.com`,required:!0}),(0,i.jsx)(`div`,{className:`pt-2`,children:(0,i.jsx)(t.cr,{type:`submit`,className:`w-full py-2.5 md:py-3 text-[14px] font-bold tracking-wide rounded-xl transition-all ${l>0?`opacity-60 shadow-none cursor-not-allowed pointer-events-none hover:translate-y-0`:`hover:-translate-y-0.5`}`,isLoading:e,disabled:l>0,children:l>0?`Resend link in ${(e=>`${Math.floor(e/60)}:${(e%60).toString().padStart(2,`0`)}`)(l)}`:d>0?`Resend reset password link`:`Send Reset Link`})})]}),(0,i.jsx)(`div`,{className:`mt-6 pt-5 border-t border-[var(--panel-border)] space-y-4 text-center`,children:(0,i.jsxs)(c.Link,{to:`/login`,className:`inline-flex items-center text-[13px] md:text-[14px] text-foreground/70 font-medium hover:text-accent transition-colors tracking-wide`,children:[(0,i.jsx)(t.qi,{className:`w-4 h-4 mr-2`}),`Back to Sign In`]})})]})})}var ze=`(max-width: 767px)`,Be=()=>typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(ze).matches;function Ve(){let[e,t]=(0,r.useState)(Be);return(0,r.useEffect)(()=>{if(typeof window>`u`||typeof window.matchMedia!=`function`)return;let e=window.matchMedia(ze),n=()=>t(e.matches);return n(),e.addEventListener?.(`change`,n),()=>e.removeEventListener?.(`change`,n)},[]),e}function He({isOpen:e,title:n,message:r,confirmText:a=`Delete`,cancelText:o=`Cancel`,onConfirm:s,onCancel:c,isProcessing:l=!1,disableConfirm:u=!1}){return(0,i.jsx)(t.pr,{children:e&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>!l&&c(),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/80 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`w-full max-w-[400px] p-6 rounded-3xl glass-popover border border-[var(--panel-border)] shadow-2xl relative z-10 text-center`,children:(0,i.jsxs)(`div`,{className:`w-full flex flex-col items-center`,children:[(0,i.jsx)(`h3`,{className:`text-xl font-extrabold mb-2 text-foreground tracking-tight`,children:n}),(0,i.jsx)(`p`,{className:`w-full text-[14px] font-medium text-foreground/60 leading-relaxed mb-6 break-words`,children:r}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3 w-full`,children:[(0,i.jsx)(t.cr,{variant:`secondary`,onClick:c,disabled:l,className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl`,children:o}),(0,i.jsx)(t.cr,{onClick:s,disabled:l||u,className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl bg-red-500 hover:bg-red-600 border-none text-white shadow-xl hover:shadow-red-500/20 glow-hover`,children:l?(0,i.jsx)(t.ei,{className:`w-5 h-5 animate-spin mx-auto`}):a})]})]})})]})})}var Ue=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).replace(/([A-Z])([A-Z][a-z])/g,`$1-$2`).toLowerCase(),We=(()=>{let e=t.hr,n=e?Object.keys(e):[];return n.length===0&&(n=Object.keys(t.mr).filter(e=>/^[A-Z]/.test(e)&&!/Icon$/.test(e)&&!/^Lucide/.test(e)&&e!==`IconNode`)),Array.from(new Set(n.map(Ue))).sort()})(),Ge=`layers.house.layout-dashboard.list.table.kanban.calendar.clock.file-text.files.folder.hard-drive.upload.download.paperclip.book-open.notebook-pen.users.user.user-plus.contact.building.briefcase.handshake.mail.message-square.message-circle.send.inbox.bell.megaphone.phone.shopping-cart.package.truck.receipt.credit-card.banknote.wallet.tag.percent.chart-bar.chart-line.chart-pie.trending-up.target.gauge.activity.settings.sliders-horizontal.wrench.shield.lock.key.eye.search.star.heart.bookmark.flag.pin.map-pin.globe.circle-check.circle-alert.info.circle-question-mark.life-buoy.sparkles.zap.rocket.camera.image.video.music.mic.palette.pen-tool.scissors.stethoscope.graduation-cap.utensils.plane.car.dumbbell.leaf.sun.moon`.split(`.`),Ke={money:[`banknote`,`wallet`,`credit-card`,`coins`,`dollar-sign`,`receipt`],cash:[`banknote`,`coins`,`wallet`],payment:[`credit-card`,`banknote`,`receipt`],invoice:[`receipt`,`file-text`],price:[`tag`,`dollar-sign`,`receipt`],people:[`users`,`user`,`contact`],customer:[`users`,`contact`,`user-round`],client:[`users`,`contact`,`briefcase`],team:[`users`,`users-round`],staff:[`users`,`id-card`],chat:[`message-circle`,`message-square`,`messages-square`],message:[`message-circle`,`mail`,`send`],email:[`mail`,`send`,`inbox`],task:[`list-checks`,`square-check`,`clipboard-check`],todo:[`list-checks`,`square-check`],project:[`kanban`,`folder-kanban`,`briefcase`],board:[`kanban`,`layout-dashboard`],photo:[`image`,`camera`,`images`],picture:[`image`,`images`],document:[`file-text`,`files`,`file`],doc:[`file-text`,`file`],shop:[`shopping-cart`,`store`,`shopping-bag`],store:[`store`,`shopping-bag`,`shopping-cart`],order:[`shopping-cart`,`package`,`receipt`],delivery:[`truck`,`package`],home:[`house`,`house-heart`],booking:[`calendar-check`,`calendar`,`clock`],appointment:[`calendar-clock`,`calendar`,`clock`],schedule:[`calendar-days`,`calendar`,`clock`],event:[`calendar`,`party-popper`,`ticket`],report:[`chart-bar`,`chart-line`,`file-chart-column`],stats:[`chart-bar`,`chart-line`,`chart-pie`],analytics:[`chart-line`,`chart-bar`,`activity`],help:[`circle-question-mark`,`life-buoy`,`info`],support:[`life-buoy`,`headset`,`circle-question-mark`],idea:[`lightbulb`,`sparkles`],health:[`heart-pulse`,`stethoscope`,`activity`],food:[`utensils`,`chef-hat`,`pizza`],travel:[`plane`,`map`,`luggage`],location:[`map-pin`,`map`,`globe`],address:[`map-pin`,`house`],security:[`shield`,`lock`,`key`],password:[`key`,`lock`],settings:[`settings`,`sliders-horizontal`,`wrench`],file:[`file`,`file-text`,`files`,`folder`],upload:[`upload`,`cloud-upload`],video:[`video`,`film`,`clapperboard`],school:[`graduation-cap`,`book-open`,`school`],course:[`graduation-cap`,`book-open`],gym:[`dumbbell`,`activity`],garden:[`leaf`,`flower`,`sprout`],car:[`car`,`car-front`],pet:[`paw-print`,`dog`,`cat`],note:[`notebook-pen`,`sticky-note`,`pencil`],write:[`pencil`,`pen-tool`,`notebook-pen`],time:[`clock`,`timer`,`hourglass`],star:[`star`,`sparkles`],favourite:[`star`,`heart`,`bookmark`],favorite:[`star`,`heart`,`bookmark`],album:[`images`,`image`,`camera`],gallery:[`images`,`image`,`camera`],profile:[`circle-user`,`user-round`,`id-card`],account:[`circle-user`,`user-round`,`id-card`],member:[`users`,`user-round`,`id-card`],membership:[`id-card`,`users`,`award`],subscription:[`credit-card`,`repeat`,`wallet`],plan:[`clipboard-list`,`layout-list`,`credit-card`],ticket:[`ticket`,`tickets`,`inbox`],request:[`inbox`,`send`,`file-text`],progress:[`trending-up`,`gauge`,`activity`],result:[`chart-bar`,`clipboard-check`,`trophy`],score:[`trophy`,`target`,`star`],library:[`library`,`book-open`,`folder`],lesson:[`graduation-cap`,`book-open`],session:[`calendar-clock`,`clock`,`video`],service:[`wrench`,`handshake`,`briefcase`],statement:[`file-text`,`receipt`,`banknote`],saved:[`bookmark`,`heart`,`star`],list:[`list`,`list-checks`,`layout-list`],detail:[`file-text`,`info`],referral:[`user-plus`,`share`,`gift`],reward:[`gift`,`trophy`,`award`],badge:[`award`,`badge`,`medal`],certificate:[`award`,`file-badge`,`scroll`],download:[`download`,`cloud-download`],history:[`history`,`clock`,`rotate-ccw`],feedback:[`message-square`,`star`,`thumbs-up`],review:[`star`,`message-square`],wishlist:[`heart`,`bookmark`,`star`],cart:[`shopping-cart`,`shopping-bag`],credit:[`coins`,`wallet`,`credit-card`],dashboard:[`layout-dashboard`,`gauge`],welcome:[`hand`,`house`,`sparkles`],onboarding:[`rocket`,`list-checks`,`user-plus`],benefit:[`gift`,`sparkles`,`award`],perk:[`gift`,`sparkles`],resource:[`folder`,`book-open`,`files`],guide:[`book-open`,`compass`,`map`],faq:[`circle-question-mark`,`message-circle`],contract:[`file-pen`,`file-text`,`scroll`],agreement:[`handshake`,`file-pen`],quote:[`file-text`,`receipt`,`tag`],enquiry:[`message-square`,`mail`],inquiry:[`message-square`,`mail`],application:[`file-text`,`clipboard-list`,`send`],form:[`clipboard-list`,`file-text`],submission:[`inbox`,`send`,`file-text`],record:[`folder`,`file-text`,`database`],log:[`history`,`list`,`file-text`]},qe=new Set([`my`,`our`,`your`,`their`,`the`,`a`,`an`,`all`,`new`,`page`,`pages`,`of`,`and`,`for`,`to`,`in`,`on`,`at`,`is`,`it`,`this`,`that`]),Je=(e,t)=>{if(Math.abs(e.length-t.length)>2)return 3;let n=Array.from({length:t.length+1},(e,t)=>t);for(let r=1;r<=e.length;r++){let i=n[0];n[0]=r;for(let a=1;a<=t.length;a++){let o=n[a];n[a]=Math.min(n[a]+1,n[a-1]+1,i+(e[r-1]===t[a-1]?0:1)),i=o}}return n[t.length]},Ye=(e,t)=>{let n=0;for(let r of t)r===e[n]&&n++;return n===e.length};function Xe(e,t=96,n=We){let r=e.trim().toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9-]/g,``);if(!r)return[];let i=r.split(`-`).filter(Boolean),a=new Set(n),o=new Map,s=(e,t)=>{a.has(e)&&o.set(e,Math.max(o.get(e)||0,t))};for(let e of n){let t=e.split(`-`);if(e===r){s(e,100);continue}if(e.startsWith(r)){s(e,90);continue}if(t.some(e=>e===r)){s(e,85);continue}if(t.some(e=>e.startsWith(r))){s(e,75);continue}if(e.includes(r)){s(e,65);continue}if(i.length>1&&i.every(e=>t.some(t=>t.startsWith(e)))){s(e,60);continue}}let c=e=>{(Ke[e]||[]).forEach((e,t)=>s(e,74-t)),e.endsWith(`s`)&&(Ke[e.slice(0,-1)]||[]).forEach((e,t)=>s(e,74-t))};for(let e of i)c(e);if(o.size===0&&i.length>1)for(let e of[...i].reverse()){if(qe.has(e)||e.length<3)continue;let r=Xe(e,t,n);if(r.length)return r}if(o.size===0&&r.length>=3)for(let e of n)e.split(`-`).some(e=>Je(r,e)<=(r.length>5?2:1))?s(e,40):r.length>=4&&Ye(r,e.replace(/-/g,``))&&s(e,20);let l=e=>{let t=Ge.indexOf(e);return t===-1?Ge.length:t};return Array.from(o.entries()).sort((e,t)=>t[1]-e[1]||l(e[0])-l(t[0])||e[0].length-t[0].length||e[0].localeCompare(t[0])).slice(0,t).map(([e])=>e)}var Ze=/(<[A-Z][A-Za-z0-9]*(?:\s[^<>]*)?\/?>|src\/[A-Za-z0-9_./-]*[A-Za-z0-9_-]|'[A-Za-z0-9_@./-]+')/g,Qe=/(https?:\/\/[^\s]+)/g,$e=e=>e.split(Qe).flatMap((e,t)=>t%2==1?[{text:e,kind:`value`}]:e.split(Ze).map((e,t)=>({text:e,kind:t%2==1?`code`:void 0}))).filter(e=>e.text),et=/exactly: |Here is (?:what|how) [^:]*: |It should ask for: |Where the form belongs on the page: |a button that says /,tt=e=>{let t=et.exec(e);if(!t)return $e(e);let n=t.index+t[0].length,r=e.slice(0,n),i=e.slice(n),a=i.indexOf(` — `);return[...$e(r),{text:a===-1?i:i.slice(0,a),kind:`value`},...$e(a===-1?``:i.slice(a))]},nt=`text-accent font-semibold bg-accent/[0.08] rounded-[4px] px-1 -mx-[1px] [overflow-wrap:anywhere]`,rt=`font-mono text-[0.92em] text-foreground/75 bg-foreground/[0.055] border border-[var(--panel-border)]/60 rounded-[4px] px-1 py-[1px] [overflow-wrap:anywhere]`;function it({text:e}){return(0,i.jsx)(i.Fragment,{children:tt(e).map((e,t)=>e.kind?(0,i.jsx)(`span`,{className:e.kind===`value`?nt:rt,children:e.text},t):(0,i.jsx)(r.default.Fragment,{children:e.text},t))})}function at({title:e=`Ask your assistant`,description:n,prompt:a,compact:o=!1,locked:s=!1,onCopied:c}){let[l,u]=(0,r.useState)(!1),d=a.includes(`
|
|
2
|
+
`);return s?null:(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 min-w-0 max-w-full rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)] ${o?`px-4 py-3.5`:`px-5 py-4`}`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-extrabold tracking-tight text-gradient`,children:e}),(0,i.jsxs)(`button`,{type:`button`,onClick:()=>{navigator.clipboard?.writeText(a),u(!0),setTimeout(()=>u(!1),2e3),c&&setTimeout(c,550)},"aria-label":l?`Copied`:`Copy`,className:`inline-flex items-center justify-center gap-1.5 h-8 w-8 px-0 sm:w-auto sm:px-3 rounded-[var(--btn-radius,0.75rem)] text-[12px] font-semibold shrink-0 border ${l?`copy-btn-done border-emerald-500/30 bg-emerald-500/10 text-emerald-500 cursor-pointer`:`copy-btn cursor-pointer`}`,children:[l?(0,i.jsx)(t.Fi,{className:`copy-icon w-3.5 h-3.5`}):(0,i.jsx)(t.Si,{className:`copy-icon w-3.5 h-3.5`}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:l?`Copied`:`Copy`})]})]}),n&&(0,i.jsx)(`p`,{className:`text-[12.5px] text-foreground/50 font-medium leading-relaxed break-words`,children:n}),(0,i.jsx)(`div`,{className:`text-[13.5px] font-medium leading-relaxed break-words [overflow-wrap:anywhere]`,children:d?(0,i.jsx)(`div`,{className:`flex flex-col gap-2 text-foreground/80`,children:a.split(`
|
|
3
|
+
`).filter(e=>e.trim()).map((e,t)=>(0,i.jsx)(`p`,{className:`min-w-0`,children:(0,i.jsx)(it,{text:e})},t))}):(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`“`,(0,i.jsx)(it,{text:a}),`”`]})})]})}var ot=`w-11 h-11 shrink-0 rounded-[var(--input-radius,0.75rem)] overflow-hidden border border-[var(--panel-border)]`,st=e=>{try{return(decodeURIComponent(new URL(e).pathname).split(`/`).pop()||``).replace(/^\d{10,}_/,``)||`Your picture`}catch{return`Your picture`}};function ct({label:e,hint:n,value:a,onChange:o,accept:s=`image/*`,action:c,clearable:l=!0,tips:u,onBusyChange:d}){let{user:f}=t.Qi(),[p,m]=(0,r.useState)(!1),[h,g]=(0,r.useState)(``),[_,v]=(0,r.useState)(!1),[y,b]=(0,r.useState)(!1),x=async e=>{if(!p){m(!0),d?.(!0),g(``);try{o(await t.ar(e,f))}catch(e){g(t.ir(e))}m(!1),d?.(!1),b(!1)}},S=e=>{let t=e.target.files?.[0];e.target.value=``,t&&x(t)},{over:C,dropProps:w}=t.er({accept:s,disabled:p,onFiles:([e])=>x(e),onReject:()=>g(s.startsWith(`image`)?`That is not a picture — drop a JPG or a PNG.`:`That kind of file does not go here.`)}),T=(0,i.jsx)(`input`,{type:`file`,accept:s,"aria-label":a?`Replace ${e}`:`Upload ${e}`,disabled:p,onChange:S,className:`sr-only`});return(0,i.jsxs)(t.Z,{label:e,hint:n,error:h,action:c,children:[(0,i.jsx)(`div`,{...w,className:`min-w-0`,children:a&&!p?(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`div`,{className:`${t.tt} min-w-0 ${C?`border-accent bg-accent/[0.04]`:``}`,children:(0,i.jsx)(`span`,{className:`flex-1 min-w-0 truncate text-[14px] select-none ${C?`text-accent`:`text-foreground/60`}`,children:C?`Drop it to replace this one`:st(a)})}),(0,i.jsxs)(`div`,{className:`${ot} relative group/pic`,children:[(0,i.jsx)(`button`,{type:`button`,onClick:()=>b(e=>!e),"aria-label":`Change ${e}`,"aria-expanded":y,className:`block w-full h-full cursor-pointer`,children:(0,i.jsx)(`img`,{src:a,alt:e,className:`w-full h-full object-cover`})}),(0,i.jsxs)(`div`,{className:`absolute inset-0 flex items-center justify-center gap-1 bg-background/85 transition-opacity duration-200 ${y?`opacity-100`:`opacity-0 pointer-events-none group-hover/pic:opacity-100 group-hover/pic:pointer-events-auto focus-within:opacity-100 focus-within:pointer-events-auto`}`,children:[(0,i.jsxs)(`label`,{title:`Replace ${e}`,className:`w-6 h-6 rounded-md flex items-center justify-center text-foreground/60 hover:text-accent hover:bg-foreground/10 transition-colors cursor-pointer`,children:[(0,i.jsx)(t.wi,{className:`w-3.5 h-3.5`}),T]}),l&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>{g(``),b(!1),o(``)},"aria-label":`Remove ${e}`,title:`Remove ${e}`,className:`w-6 h-6 rounded-md flex items-center justify-center text-foreground/60 hover:text-red-500 hover:bg-red-500/10 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-3.5 h-3.5`})})]})]})]}):(0,i.jsxs)(`label`,{title:`Upload ${e}`,className:`group/up flex items-center gap-2 ${p?`pointer-events-none`:`cursor-pointer`}`,children:[(0,i.jsx)(`span`,{className:`${t.tt} select-none text-[14px] truncate ${C?`border-accent bg-accent/[0.04] text-accent`:p?`text-foreground/50`:`text-foreground/35`} group-hover/up:border-accent/40 group-focus-within/up:border-accent`,children:C?`Drop it here`:p?`Uploading your picture…`:`Upload a picture, or drop one here`}),(0,i.jsx)(`span`,{"aria-hidden":!0,className:`${ot} flex items-center justify-center bg-[var(--panel-bg)] ${C?`text-accent border-accent`:`text-foreground/40`} group-hover/up:text-accent group-hover/up:border-accent/40 transition-colors`,children:p?(0,i.jsx)(t.ei,{className:`w-4 h-4 animate-spin text-accent`}):(0,i.jsx)(t.wi,{className:`w-4 h-4`})}),T]})}),!!u?.length&&(0,i.jsxs)(`div`,{className:`mt-2 px-1`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:()=>v(e=>!e),"aria-expanded":_,className:`inline-flex items-center gap-1 text-[11.5px] font-semibold text-foreground/40 hover:text-foreground/70 transition-colors cursor-pointer`,children:[(0,i.jsx)(t.Mi,{className:`w-3 h-3 shrink-0 transition-transform duration-200 ${_?`rotate-90`:``}`}),`Which picture should I upload?`]}),_&&(0,i.jsx)(`ul`,{className:`flex flex-col gap-1 mt-1.5 ml-4`,children:u.map(e=>(0,i.jsxs)(`li`,{className:`text-[11.5px] text-foreground/40 font-medium leading-snug flex gap-1.5`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`text-accent/60`,children:`•`}),e]},e))})]})]})}var lt=[`A wide picture sits best across a page — about 1600 by 900.`,`JPG or PNG. Any size — a big photo is shrunk for you as it uploads, so the page still opens quickly.`,`Your own photo beats a stock one. People can tell.`,`No writing baked into the picture — your assistant sets the words, so they stay readable on a phone.`],ut=[`A wide picture, not a square one — it sits in a short bar about 40px tall.`,`PNG with a see-through background looks right on both the light and the dark theme.`],dt=[`A square picture — 64 by 64 is plenty.`,`One shape or one letter. A whole logo turns to mush at this size.`],ft=`sys_roles`,pt=(e,t)=>({id:e,name:String(t?.name||e),...typeof t?.createdAt==`number`?{createdAt:t.createdAt}:{}}),mt=(e,t)=>e.name.localeCompare(t.name),ht=[],gt=e=>{ht=e},_t=()=>ht,vt=(e,t=_t())=>t.find(t=>t.id===e)?.name||e;function yt(e,n=_t()){let r=String(e||``).trim();if(!r)return`Type a name for the role first — Client, say, or Supplier.`;let i=t.ga(r);return i.length<2||!/^[a-z]/.test(i)?`Use a name with at least two letters in it.`:t.na.has(i)||!t.ua(i)?`${r} is a word the app already uses. Pick another.`:n.some(e=>e.id===i)?`You already have a role called ${n.find(e=>e.id===i).name}.`:``}async function bt(e){let n=String(e||``).trim().slice(0,48),r={id:t.ga(n),name:n,createdAt:Date.now()};return await(0,o.setDoc)((0,o.doc)(t.Ca,ft,r.id),{name:r.name,createdAt:r.createdAt}),r}async function xt(e,n){let r=String(n||``).trim().slice(0,48);!t.ua(e)||!r||await(0,o.setDoc)((0,o.doc)(t.Ca,ft,e),{name:r},{merge:!0})}function St(e,t,n=_t()){let r=String(t||``).trim();if(!r)return`A role needs a name.`;let i=n.find(t=>t.id!==e&&t.name.trim().toLowerCase()===r.toLowerCase());return i?`You already have a role called ${i.name}.`:``}async function Ct(e){let n={people:[],pages:[]};return t.ua(e)?((await(0,o.getDocs)((0,o.query)((0,o.collection)(t.Ca,`user_profiles`),(0,o.where)(`role`,`==`,e)))).forEach(e=>n.people.push(e.id)),(await(0,o.getDocs)((0,o.collection)(t.Ca,`sys_tabs`))).forEach(r=>{t.ia(r.data()?.roles).includes(e)&&n.pages.push(r.id)}),n):n}async function wt(e){if(!t.ua(e))return;let n=await(0,o.getDocs)((0,o.query)((0,o.collection)(t.Ca,`user_profiles`),(0,o.where)(`role`,`==`,e)));for(let e of n.docs)await(0,o.updateDoc)((0,o.doc)(t.Ca,`user_profiles`,e.id),{role:t.ha(`free`)});let r=await(0,o.getDocs)((0,o.collection)(t.Ca,`sys_tabs`));for(let n of r.docs){let r=t.ia(n.data()?.roles);if(!r.includes(e))continue;let i=r.filter(t=>t!==e);await(0,o.setDoc)((0,o.doc)(t.Ca,`sys_tabs`,n.id),{roles:i.length?i:[`user`]},{merge:!0})}await(0,o.deleteDoc)((0,o.doc)(t.Ca,ft,e))}function Tt(){let[e,n]=(0,r.useState)(()=>_t());return(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.collection)(t.Ca,ft),e=>{let t=[];e.forEach(e=>t.push(pt(e.id,e.data()))),t.sort(mt),gt(t),n(t)},()=>{}),[]),e}function Et({roles:e}){let[n,a]=(0,r.useState)(``),[o,s]=(0,r.useState)(``),[c,l]=(0,r.useState)(``),[u,d]=(0,r.useState)(``),[f,p]=(0,r.useState)(null);if(!e.length)return null;let m=async t=>{let n=St(t.id,o,e);if(n){l(n);return}d(t.id);try{await xt(t.id,o),a(``),l(``)}catch(e){l(e?.message||`The new name could not be saved. Try again.`)}d(``)},h=async e=>{d(e.id);try{p({role:e,standing:await Ct(e.id)})}catch{p({role:e,standing:{people:[],pages:[]}})}d(``)};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`div`,{className:`border-t border-[var(--panel-border)] p-4 sm:p-6 flex flex-col gap-4`,children:[(0,i.jsx)(t.ot,{icon:t.kr,title:`Your own roles`,description:`The words you mark people with. Renaming one changes it everywhere; nobody is unmarked.`}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.map(e=>(0,i.jsx)(`div`,{className:`rounded-2xl glass-panel border border-[var(--panel-border)] px-3.5 py-2.5 flex items-center gap-2.5`,children:n===e.id?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`input`,{autoFocus:!0,value:o,disabled:u===e.id,"aria-label":`Rename ${e.name}`,onChange:e=>{s(e.target.value),c&&l(``)},onKeyDown:t=>{t.key===`Enter`&&(t.preventDefault(),m(e)),t.key===`Escape`&&(t.preventDefault(),a(``),l(``))},className:`${t.et} flex-1 min-w-0`}),(0,i.jsx)(t.Q,{icon:t.Fi,compact:!0,busy:u===e.id,title:`Save ${o||e.name}`,onClick:()=>m(e),children:`Save`}),(0,i.jsx)(t.Q,{icon:t._r,compact:!0,title:`Keep the name`,onClick:()=>{a(``),l(``)},children:`Cancel`})]}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`span`,{className:`flex-1 min-w-0 text-[13.5px] font-bold text-foreground truncate`,children:e.name}),(0,i.jsx)(t.Q,{icon:t.Wr,compact:!0,title:`Rename ${e.name}`,onClick:()=>{a(e.id),s(e.name),l(``)},children:`Rename`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,busy:u===e.id,title:`Remove ${e.name}`,onClick:()=>h(e),children:`Remove`})]})},e.id)),!!c&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:c}),(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Make a new role on the Pages screen, on the row of the page you want to keep for it.`})]})]}),(0,i.jsx)(He,{isOpen:!!f,title:f?`Remove ${f.role.name}?`:``,message:f?Dt(f.standing):``,confirmText:`Yes, remove it`,cancelText:`Keep it`,isProcessing:u===`removing`,onCancel:()=>p(null),onConfirm:async()=>{if(f){d(`removing`);try{await wt(f.role.id),p(null)}catch(e){l(e?.message||`The role could not be removed. Try again.`),p(null)}d(``)}}})]})}function Dt(e){let t=e.people.length,n=e.pages.length,r=[];return t&&r.push(`${t} ${t===1?`person goes`:`people go`} back to being ${t===1?`a member`:`members`}`),n&&r.push(`${n} ${n===1?`page goes`:`pages go`} back to everybody signed in`),`${r.length?`${r.join(`, and `)}. `:`Nobody is marked with it and no page is kept for it. `}Whatever those pages have saved stays exactly where it is — you and your admins can still read it — but nobody else will, and the word itself is gone from every list.`}function Ot(){let{user:e,userRole:n}=t.Qi(),a=Tt(),[l,u]=(0,r.useState)(!0),d=(0,c.useNavigate)(),{id:f}=(0,c.useParams)(),p=Ve(),[m,h]=(0,r.useState)([]),[g,_]=(0,r.useState)(null),[v,y]=(0,r.useState)(!1),[b,x]=(0,r.useState)(``),[S,C]=(0,r.useState)(!1),w=f?m.find(e=>e.id===f)||null:m.length>0?m[0]:null,T=e=>{d(e?`/users/${e.id}`:`/users`)};(0,r.useEffect)(()=>{u(!0);let e=(0,o.onSnapshot)((0,o.collection)(t.Ca,`user_profiles`),e=>{let t=[];e.forEach(e=>{t.push({id:e.id,...e.data()})}),h(t),u(!1),!f&&t.length>0&&!Be()&&d(`/users/${t[0].id}`,{replace:!0})},e=>{console.error(`Error fetching users:`,e),u(!1)});return()=>e()},[f,d]);let E=m.find(t=>t.id===e?.uid),D=e=>e.id===E?.id?!1:e.role!==`admin`||!E?.createdAt?!0:e.createdAt?new Date(E.createdAt).getTime()<=new Date(e.createdAt).getTime():!1,O=[...t.$i.map(e=>({value:t.ha(e),label:t.ea[e]})),...a.map(e=>({value:e.id,label:e.name}))],k=e=>t.sa(e.role)||t.ha(t.da(e.role)),A=e=>{let n=t.sa(e.role);return n?vt(n,a):t.ea[t.da(e.role)]},j=async(e,r,i)=>{if(!(n!==`admin`||!D(e))&&k(e)!==r)try{await(0,o.updateDoc)((0,o.doc)(t.Ca,`user_profiles`,e.id),{role:r}),_({text:`Access level set to ${i}`,type:`success`}),setTimeout(()=>_(null),3e3)}catch(e){_({text:e.message,type:`error`}),setTimeout(()=>_(null),3e3)}},M=async(e,r)=>{if(!(n!==`admin`||!D(e)))try{await(0,o.updateDoc)((0,o.doc)(t.Ca,`user_profiles`,e.id),{inactive:r}),_({text:`User ${r?`deactivated`:`activated`} successfully`,type:`success`}),setTimeout(()=>_(null),3e3)}catch(e){_({text:e.message,type:`error`}),setTimeout(()=>_(null),3e3)}},N=async()=>{if(y(!1),!(!w||!D(w)||b===w.displayName))try{await(0,o.updateDoc)((0,o.doc)(t.Ca,`user_profiles`,w.id),{displayName:b}),_({text:`Name updated successfully`,type:`success`}),setTimeout(()=>_(null),3e3)}catch(e){_({text:e.message,type:`error`}),setTimeout(()=>_(null),3e3)}},P=async e=>{if(!w||!D(w))return;let n=await t.or(e,{maxSide:512});if(n.size>2*1024*1024){_({text:`File too large. Please select an image under 2MB.`,type:`error`});return}C(!0);try{let e=(0,s.ref)(t.Ta,`user_avatars/${w.id}/file.png`);await(0,s.uploadBytes)(e,n);let r=await(0,s.getDownloadURL)(e);h(e=>e.map(e=>e.id===w.id?{...e,avatar:r}:e)),await(0,o.updateDoc)((0,o.doc)(t.Ca,`user_profiles`,w.id),{avatar:r}),_({text:`Avatar successfully updated.`,type:`success`}),setTimeout(()=>_(null),3e3)}catch{_({text:`Failed to upload photo.`,type:`error`})}C(!1)},F=e=>{let t=e.target.files?.[0];t&&P(t)},{over:I,dropProps:L}=t.er({accept:`image/*`,disabled:S||!w||!D(w),onFiles:([e])=>P(e),onReject:()=>_({text:`That is not a picture. Drop a JPG or a PNG.`,type:`error`})}),[R,z]=(0,r.useState)(!1);if((0,r.useEffect)(()=>{let e;return l&&m.length===0?e=setTimeout(()=>z(!0),150):z(!1),()=>clearTimeout(e)},[l,m.length]),l&&m.length===0)return R?(0,i.jsx)(`div`,{className:`fixed inset-0 z-[100] flex items-center justify-center bg-background/60 backdrop-blur-xl transition-all duration-300`,children:(0,i.jsx)(t.ei,{className:`w-8 h-8 animate-spin text-accent`})}):null;let B=p&&!!f,V=!B,H=!p||!!f;return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto z-10 flex flex-col min-h-screen p-4 pt-2 md:p-8 md:pt-4`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-8`,children:[(0,i.jsx)(we,{children:`Users`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/users`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col animate-in fade-in duration-500 gap-6 ${B?`flex-1 pb-6`:`pb-20`}`,children:[(0,i.jsx)(t.pr,{children:g&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},exit:{opacity:0,y:-10},className:`p-4 text-[14px] font-medium border rounded-xl ${g.type===`error`?`text-red-500 bg-red-500/10 border-red-500/20 shadow-[0_0_15px_rgba(239,68,68,0.1)]`:`text-emerald-400 bg-emerald-500/10 border-emerald-500/20 shadow-[0_0_15px_rgba(52,211,153,0.1)]`} flex items-center gap-2`,children:[g.type===`success`&&(0,i.jsx)(t.ki,{className:`w-4 h-4 shrink-0`}),g.text]})}),(0,i.jsx)(`div`,{className:`flex justify-start`,children:(0,i.jsx)(Ie,{})}),(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] bg-[var(--panel-bg)] overflow-hidden rounded-3xl shadow-2xl ${B?`flex-1 flex flex-col`:``}`,children:[m.length===0?(0,i.jsx)(`div`,{className:`p-8 text-center text-foreground/50 text-[14px]`,children:`No members found.`}):(0,i.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 md:min-h-[500px] ${B?`flex-1`:``}`,children:[V&&(0,i.jsxs)(`div`,{className:`flex md:col-span-1 border-r md:border-r-[var(--panel-border)] border-b md:border-b-0 border-[var(--panel-border)] flex-col hide-scrollbar bg-foreground/[0.03] rounded-t-3xl md:rounded-tr-none md:rounded-l-3xl`,children:[(0,i.jsx)(`div`,{className:`p-4 border-b border-[var(--panel-border)] font-bold text-[13px] text-foreground/70 uppercase tracking-wider`,children:`System Users`}),(0,i.jsx)(`div`,{className:`flex-1 overflow-y-auto p-4 space-y-2 md:max-h-[520px]`,children:m.map(e=>(0,i.jsxs)(`div`,{onClick:()=>T(e),className:`p-3.5 rounded-2xl border transition-all flex items-center gap-3 cursor-pointer ${w?.id===e.id?`bg-foreground/[0.06] border-accent/40 shadow-sm`:`glass-panel border-[var(--panel-border)] hover:border-accent/40`} ${e.inactive?`opacity-50 grayscale`:``}`,children:[(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-full overflow-hidden bg-accent/10 shrink-0 flex items-center justify-center border border-accent/20 shadow-sm`,children:e.avatar||e.photoURL?(0,i.jsx)(`img`,{src:e.avatar||e.photoURL,alt:``,className:`w-full h-full object-cover`}):(0,i.jsx)(t.Sr,{className:`w-4 h-4 text-accent`})}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[14px] text-foreground truncate`,children:e.displayName||`No Name`}),(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/50 truncate font-medium mt-0.5`,children:e.email})]}),p&&(0,i.jsx)(t.Mi,{className:`w-4 h-4 text-foreground/25 shrink-0`})]},e.id))})]}),H&&(0,i.jsx)(`div`,{className:`flex md:col-span-2 flex-col relative ${B?`px-4 pt-4 pb-10`:`p-5 sm:p-6 md:p-10`}`,children:w?(0,i.jsxs)(`div`,{className:`animate-in fade-in duration-300 w-full max-w-lg`,children:[(0,i.jsxs)(`div`,{className:`flex flex-row items-center gap-3 sm:gap-6 md:gap-8 mb-8 sm:mb-10`,children:[B&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>T(null),"aria-label":`Back to all users`,className:`shrink-0 -ml-1.5 w-7 h-7 flex items-center justify-center rounded-lg text-foreground/40 hover:text-foreground active:bg-foreground/5 transition-colors cursor-pointer`,children:(0,i.jsx)(t.qi,{className:`w-5 h-5`})}),(0,i.jsxs)(`div`,{...L,className:`relative shrink-0 group/avatar rounded-full transition-shadow ${I?`ring-2 ring-accent ring-offset-2 ring-offset-background`:``}`,children:[(0,i.jsx)(`div`,{className:`w-14 h-14 sm:w-24 sm:h-24 rounded-full glass-panel border-2 sm:border-4 border-[var(--panel-border)] shadow-lg sm:shadow-xl bg-accent/10 flex items-center justify-center overflow-hidden`,children:S?(0,i.jsx)(t.ei,{className:`w-5 h-5 sm:w-8 sm:h-8 text-accent animate-spin`}):w.avatar||w.photoURL?(0,i.jsx)(`img`,{src:w.avatar||w.photoURL,alt:`Avatar`,className:`w-full h-full object-cover`}):(0,i.jsx)(t.Sr,{className:`w-6 h-6 sm:w-10 sm:h-10 text-accent`})}),!S&&D(w)&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`label`,{title:`Change photo`,className:`max-sm:hidden sm:flex absolute -bottom-0.5 -right-0.5 w-9 h-9 rounded-full btn-primary text-white items-center justify-center cursor-pointer shadow-lg border-2 border-[var(--bg-color)] hover:scale-105 active:scale-95 transition-transform z-10`,children:[(0,i.jsx)(t.Ii,{className:`w-4 h-4`}),(0,i.jsx)(`input`,{type:`file`,accept:`image/*`,"aria-label":`Change photo`,onChange:F,className:`hidden`})]}),(0,i.jsxs)(`label`,{title:`Change photo`,className:`flex sm:hidden absolute inset-0 rounded-full bg-background/60 backdrop-blur-[2px] opacity-0 group-hover/avatar:opacity-100 focus-within:opacity-100 items-center justify-center cursor-pointer transition-opacity z-10`,children:[(0,i.jsx)(t.Ii,{className:`w-4 h-4 text-foreground`}),(0,i.jsx)(`input`,{type:`file`,accept:`image/*`,"aria-label":`Change photo`,onChange:F,className:`hidden`})]})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col flex-1 w-full min-w-0 relative`,children:[v?(0,i.jsx)(`input`,{autoFocus:!0,value:b,onChange:e=>x(e.target.value),onBlur:N,onKeyDown:e=>e.key===`Enter`&&N(),className:`text-xl sm:text-2xl md:text-3xl font-extrabold mb-1 bg-transparent border-b-2 border-accent outline-none text-foreground w-full py-1`}):(0,i.jsx)(`h3`,{onDoubleClick:()=>{D(w)&&(x(w.displayName||``),y(!0))},className:`text-xl sm:text-2xl md:text-3xl font-extrabold mb-1 select-none break-words ${D(w)?`cursor-pointer hover:text-accent transition-colors`:``}`,title:D(w)?`Double-click to edit`:``,children:w.displayName||`No Name`}),(0,i.jsx)(`p`,{className:`text-[13px] sm:text-[14px] font-mono text-foreground/50 break-all`,children:w.email}),(0,i.jsx)(`span`,{className:`mt-2 self-start inline-flex items-center h-6 px-2.5 rounded-full text-[11.5px] font-bold bg-accent/10 text-accent border border-accent/20`,children:A(w)}),!D(w)&&w.id!==E?.id&&(0,i.jsxs)(`p`,{className:`mt-2 flex items-center gap-1.5 text-[12px] font-medium text-foreground/45`,children:[(0,i.jsx)(t.$r,{className:`w-3 h-3 shrink-0`}),`Admin since before you, so only they can change this account.`]})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(`div`,{className:`p-4 rounded-2xl glass-panel border border-[var(--panel-border)] flex flex-col gap-3`,children:(0,i.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[14px] text-foreground`,children:`Access level`}),(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/50`,children:`What this person can open`})]}),(0,i.jsx)(`div`,{role:`radiogroup`,"aria-label":`Access level`,className:`flex items-center gap-1.5 flex-wrap ${D(w)?``:`opacity-50`}`,children:O.map(e=>{let t=k(w)===e.value;return(0,i.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":t,disabled:!D(w),onClick:()=>j(w,e.value,e.label),className:`h-8 px-3.5 rounded-full text-[12.5px] font-semibold border transition-all ${t?`bg-accent/10 border-accent/40 text-accent`:`border-[var(--panel-border)] text-foreground/55 hover:text-foreground hover:border-accent/30`} ${D(w)?`cursor-pointer`:`cursor-not-allowed`}`,children:e.label},e.value)})})]})}),(0,i.jsxs)(`div`,{className:`p-4 rounded-2xl glass-panel border flex items-center justify-between gap-3 ${w.inactive?`border-amber-500/30 bg-amber-500/5`:`border-red-500/20 bg-red-500/5`}`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[14px] ${w.inactive?`text-amber-500`:`text-red-500`}`,children:w.inactive?`Reactivate User`:`Deactivate User`}),(0,i.jsx)(`span`,{className:`text-[12px] ${w.inactive?`text-amber-500/70`:`text-red-500/70`}`,children:`Block access to this app`})]}),(0,i.jsx)(`button`,{type:`button`,disabled:!D(w),onClick:()=>M(w,!w.inactive),className:`relative inline-flex h-7 w-12 shrink-0 items-center rounded-full transition-colors focus:outline-none shadow-inner ${w.inactive?`bg-amber-500`:`bg-red-500/20`} ${D(w)?`cursor-pointer`:`opacity-50 cursor-not-allowed`}`,children:(0,i.jsx)(`span`,{className:`inline-block h-5 w-5 transform rounded-full bg-white transition-transform shadow-md ${w.inactive?`translate-x-6`:`translate-x-1`}`})})]})]})]}):(0,i.jsxs)(`div`,{className:`absolute inset-0 flex flex-col items-center justify-center opacity-30 pointer-events-none`,children:[(0,i.jsx)(t.xr,{className:`w-12 h-12 mb-4`}),(0,i.jsx)(`p`,{className:`font-bold tracking-widest uppercase text-[12px]`,children:`Select a User`})]})})]}),!B&&(0,i.jsx)(Et,{roles:a})]})]})]})}var kt={anyone:{collectionName:`user_submissions`,chip:`Anyone`,filterLabel:`From anyone`},signedIn:{collectionName:`user_requests`,chip:`Signed-in user`,filterLabel:`From signed-in users`}},At=[`id`,`source`,`uid`,`submittedAt`,`avatarUrl`,`isArchived`,`name`,`full_name`,`email`,`contactEmail`,`topic`],jt=e=>{let t=e.submittedAt;if(!t)return 0;if(typeof t.toMillis==`function`)return t.toMillis();if(typeof t.toDate==`function`)return t.toDate().getTime();let n=new Date(t).getTime();return Number.isNaN(n)?0:n},Mt=e=>{if(!e)return`Just now`;let t=e.toDate?e.toDate():new Date(e);return new Intl.DateTimeFormat(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`,minute:`numeric`}).format(t)},Nt=e=>{if(!e)return`now`;let t=e.toDate?e.toDate():new Date(e),n=new Date;return t.toDateString()===n.toDateString()?new Intl.DateTimeFormat(`en-US`,{hour:`numeric`,minute:`numeric`}).format(t):new Intl.DateTimeFormat(`en-US`,t.getFullYear()===n.getFullYear()?{month:`short`,day:`numeric`}:{month:`short`,year:`numeric`}).format(t)},Pt=e=>{let t=new Date(e);return new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()},Ft=e=>{let t=jt(e);if(!t)return`Older`;let n=Math.round((Pt(Date.now())-Pt(t))/864e5);return n<=0?`Today`:n===1?`Yesterday`:n<7?`This week`:n<30?`This month`:`Older`},It=e=>e.reduce((e,t)=>{let n=Ft(t),r=e[e.length-1];return r&&r.label===n?r.items.push(t):e.push({label:n,items:[t]}),e},[]);function Lt({label:e}){return(0,i.jsxs)(`div`,{className:`md:hidden flex items-center gap-3 pt-1 first:pt-0 select-none`,children:[(0,i.jsx)(`span`,{className:`text-[10.5px] font-bold uppercase tracking-[0.18em] text-foreground/35 shrink-0`,children:e}),(0,i.jsx)(`span`,{className:`h-px flex-1 bg-[var(--panel-border)]/60`})]})}var Rt=e=>e.submitterName||e.name||e.full_name||`Anonymous`,zt=e=>e.contactEmail||e.email||`No email provided`;function Bt(e){let[n,i]=(0,r.useState)([]),[a,s]=(0,r.useState)(!0);return(0,r.useEffect)(()=>{let n=!1,r=kt[e].collectionName,a=(0,o.onSnapshot)((0,o.query)((0,o.collection)(t.Ca,r),(0,o.orderBy)(`submittedAt`,`desc`)),async r=>{let a=[];for(let n of r.docs){let r={...n.data()};if(r.formId===`booking`||t.on(r))continue;let i=``;if(r.uid&&r.uid!==`guest`)try{let e=await(0,o.getDoc)((0,o.doc)(t.Ca,`user_profiles`,r.uid));if(e.exists()){let t=e.data();(t.avatar||t.photoURL)&&(i=t.avatar||t.photoURL),r.name||=t.name||t.displayName,r.email||=t.email,r.contactEmail||=t.email}}catch(e){console.error(`Failed to fetch profile`,e)}a.push({...r,id:n.id,source:e,avatarUrl:i})}n||(i(a),s(!1))},e=>{console.error(`Error loading ${r}:`,e),n||s(!1)});return()=>{n=!0,a()}},[e]),{items:n,loading:a}}function Vt({source:e}){return(0,i.jsx)(`span`,{className:`text-[10px] font-bold uppercase tracking-widest text-accent bg-accent/10 px-2 py-0.5 rounded-md border border-accent/20 shrink-0`,children:kt[e].chip})}function Ht({item:e,isExpanded:n,onToggle:r,onArchive:a,onDelete:o,busy:s,dimmed:l}){let u=Rt(e),d=e.avatarUrl||e.submitterAvatar,f=!!e.uid&&e.uid!==`guest`,p=Object.entries(e).filter(([e])=>!At.includes(e)&&!e.toLowerCase().startsWith(`submitter`)&&e.toLowerCase()!==`formid`),m=e.topic?[[`topic`,e.topic],...p]:p;return(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`glass-panel border border-[var(--panel-border)] rounded-2xl flex flex-col overflow-hidden hover:border-accent/40 transition-all duration-300 ${l?`opacity-60 hover:opacity-100`:``}`,children:[(0,i.jsxs)(`div`,{className:`w-full flex items-center gap-3 p-3.5 md:px-5`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:r,"aria-expanded":n,className:`flex items-center gap-3 flex-1 min-w-0 text-left cursor-pointer`,children:[(0,i.jsx)(`div`,{className:`relative shrink-0`,children:d?(0,i.jsx)(`img`,{src:d,alt:``,className:`w-9 h-9 rounded-full object-cover border border-[var(--panel-border)] shadow-sm`}):(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-full bg-accent/10 text-accent flex items-center justify-center font-bold border border-accent/20 shadow-sm uppercase`,children:(u||`A`)[0]})}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`font-bold text-[14px] text-foreground truncate`,children:u}),(0,i.jsxs)(`span`,{className:`text-[12px] text-foreground/50 truncate flex items-center gap-1.5 font-medium mt-0.5`,children:[(0,i.jsx)(t.Xr,{className:`w-3.5 h-3.5 shrink-0`}),` `,zt(e)]})]})]}),(0,i.jsx)(`button`,{type:`button`,onClick:r,tabIndex:-1,"aria-hidden":`true`,className:`md:hidden w-8 h-8 -mr-1 flex items-center justify-center rounded-lg text-foreground/30 hover:text-accent hover:bg-foreground/5 transition-colors shrink-0 cursor-pointer`,children:(0,i.jsx)(t.Pi,{className:`w-4 h-4 transition-transform duration-300 ${n?`rotate-180`:``}`})}),(0,i.jsxs)(`div`,{className:`max-md:hidden md:flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/35 tabular-nums whitespace-nowrap mr-1`,children:Nt(e.submittedAt)}),(0,i.jsx)(t.Q,{icon:e.isArchived?t.Gi:t.Yi,onClick:a,busy:s,children:e.isArchived?`Restore`:`Archive`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,onClick:o,children:`Delete`}),(0,i.jsx)(`button`,{type:`button`,onClick:r,"aria-label":n?`Hide details from ${u}`:`Show details from ${u}`,className:`p-1.5 text-foreground/40 transition-transform duration-300 cursor-pointer ${n?`rotate-180`:``}`,children:(0,i.jsx)(t.Pi,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(t.pr,{children:n&&(0,i.jsx)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden`,children:(0,i.jsxs)(`div`,{className:`px-3.5 md:px-5 py-4 border-t border-[var(--panel-border)]/40`,children:[(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 mb-3`,children:[(0,i.jsx)(Vt,{source:e.source}),e.formId&&(0,i.jsx)(`span`,{className:`text-[10px] font-bold uppercase tracking-widest text-foreground/40 bg-foreground/5 px-2 py-0.5 rounded-md border border-[var(--panel-border)] shrink-0`,children:String(e.formId).replace(/_/g,` `)}),(0,i.jsx)(`span`,{className:`text-[11px] font-medium text-foreground/40 shrink-0`,children:Mt(e.submittedAt)})]}),m.length>0?(0,i.jsx)(`div`,{className:`rounded-xl border border-[var(--panel-border)]/60 bg-foreground/[0.02] divide-y divide-[var(--panel-border)]/40 overflow-hidden`,children:m.map(([e,n])=>(0,i.jsxs)(`div`,{className:`px-3.5 md:px-4 py-3`,children:[(0,i.jsx)(`span`,{className:`block text-[11px] font-bold uppercase tracking-widest text-foreground/40 mb-1`,children:e.replace(/_/g,` `).replace(/\b\w/g,e=>e.toUpperCase())}),t.rr(n)?(0,i.jsx)(`div`,{className:`flex flex-col gap-1.5`,children:t.nr(n).map(e=>(0,i.jsxs)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,className:`inline-flex items-center gap-2 text-[14px] font-semibold text-accent hover:underline break-all [overflow-wrap:anywhere]`,children:[(0,i.jsx)(t.Kr,{className:`w-4 h-4 shrink-0`}),t.tr(e)]},e))}):(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/85 leading-relaxed whitespace-pre-wrap break-words [overflow-wrap:anywhere]`,children:typeof n==`boolean`?n?`Yes`:`No`:String(n??``)||`No data provided`})]},e))}):(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/40 font-medium`,children:`This form only asked for a name and email.`}),f&&(0,i.jsx)(c.Link,{to:`/users/${e.uid}`,className:`inline-flex mt-3 text-[12.5px] font-bold text-accent hover:underline`,children:`Open this person’s profile`}),(0,i.jsxs)(`div`,{className:`md:hidden flex items-center justify-end gap-2 mt-4`,children:[(0,i.jsx)(t.Q,{icon:e.isArchived?t.Gi:t.Yi,onClick:a,busy:s,children:e.isArchived?`Restore`:`Archive`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,onClick:o,children:`Delete`})]})]})})})]})}function Ut(){let e=Bt(`anyone`),n=Bt(`signedIn`),[a,s]=(0,r.useState)(`all`),[l,u]=(0,r.useState)(null),[d,f]=(0,r.useState)(!1),[p,m]=(0,r.useState)(null),[h,g]=(0,r.useState)(null),[_,v]=(0,r.useState)(!1),y=e.loading||n.loading,b=(0,r.useMemo)(()=>[...e.items,...n.items].sort((e,t)=>jt(t)-jt(e)),[e.items,n.items]),x=a===`all`?b:b.filter(e=>e.source===a),S=x.filter(e=>!e.isArchived),C=x.filter(e=>e.isArchived),w=e=>`${e.source}:${e.id}`,[T,E]=(0,c.useSearchParams)(),D=T.get(`open`);(0,r.useEffect)(()=>{if(!D||y)return;let e=b.find(e=>w(e)===D);e&&(e.isArchived&&f(!0),u(D),E({},{replace:!0}))},[D,y,b]);let O=e=>u(t=>t===w(e)?null:w(e)),k=async e=>{m(w(e));try{await(0,o.updateDoc)((0,o.doc)(t.Ca,kt[e.source].collectionName,e.id),{isArchived:!e.isArchived}),!e.isArchived&&l===w(e)&&u(null)}catch(e){console.error(`Failed to archive`,e)}m(null)},A=async()=>{if(h){v(!0);try{await(0,o.deleteDoc)((0,o.doc)(t.Ca,kt[h.source].collectionName,h.id)),l===w(h)&&u(null),g(null)}catch(e){console.error(`Failed to delete`,e)}v(!1)}},j=[{key:`all`,label:`Everything`,short:`All`},{key:`anyone`,label:kt.anyone.filterLabel,short:`Anyone`},{key:`signedIn`,label:kt.signedIn.filterLabel,short:`Signed in`}];return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-8`,children:[(0,i.jsx)(we,{children:`Inbox`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/inbox`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 flex-1 min-h-[500px]`,children:[(0,i.jsx)(`div`,{className:`flex justify-start`,children:(0,i.jsx)(Ie,{})}),(0,i.jsxs)(`div`,{className:`w-full flex-1 flex flex-col glass-panel rounded-2xl md:rounded-3xl p-3 sm:p-6 md:p-10 relative overflow-hidden border border-[var(--panel-border)] shadow-2xl bg-[var(--panel-bg)]`,children:[(0,i.jsx)(`div`,{className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-64 h-64 bg-accent/5 blur-[100px] rounded-full pointer-events-none`}),(0,i.jsx)(`div`,{className:`relative z-10 flex-1 flex flex-col`,children:y?(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center min-h-[500px]`,children:(0,i.jsx)(`div`,{className:`w-8 h-8 md:w-10 md:h-10 border-4 border-accent/20 border-t-accent rounded-full animate-spin`})}):b.length===0?(0,i.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center text-center p-8 gap-6`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-3xl bg-accent/10 border border-accent/20 flex items-center justify-center text-accent shadow-inner`,children:(0,i.jsx)(t.ci,{className:`w-6 h-6`})}),(0,i.jsxs)(`div`,{children:[(0,i.jsx)(`h2`,{className:`text-2xl font-extrabold text-foreground mb-2`,children:`Nothing here yet`}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/50 font-medium max-w-md`,children:`Everything people send you through a form on your site lands here.`})]})]}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 pb-8`,children:[(0,i.jsx)(`div`,{className:`flex flex-wrap items-center gap-2 mb-2`,children:j.map(e=>(0,i.jsxs)(`button`,{type:`button`,onClick:()=>s(e.key),"aria-pressed":a===e.key,"aria-label":e.label,className:`h-8 md:h-9 px-3 md:px-4 rounded-full text-[12px] md:text-[12.5px] font-bold border transition-all cursor-pointer ${a===e.key?`bg-accent/10 border-accent/40 text-accent`:`border-[var(--panel-border)]/70 bg-background/60 text-foreground/60 hover:text-foreground hover:border-accent/30`}`,children:[(0,i.jsx)(`span`,{className:`sm:hidden`,children:e.short}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:e.label})]},e.key))}),S.length===0&&(0,i.jsx)(`div`,{className:`bg-foreground/[0.02] border border-dashed border-[var(--panel-border)] rounded-2xl flex flex-col items-center justify-center p-8 text-center mb-4`,children:(0,i.jsx)(`p`,{className:`text-[14px] font-bold text-foreground/50`,children:C.length>0?`Everything here is archived.`:`Nothing matches this filter.`})}),(0,i.jsx)(t.pr,{children:It(S).map(e=>(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(Lt,{label:e.label}),e.items.map(e=>(0,i.jsx)(Ht,{item:e,isExpanded:l===w(e),onToggle:()=>O(e),onArchive:()=>k(e),onDelete:()=>g(e),busy:p===w(e)},w(e)))]},e.label))}),C.length>0&&(0,i.jsxs)(`div`,{className:`mt-6 pt-4 border-t border-[var(--panel-border)]/30`,children:[(0,i.jsx)(`div`,{className:`flex justify-center`,children:(0,i.jsxs)(`button`,{type:`button`,onClick:()=>f(e=>!e),className:`flex items-center gap-2 text-[11px] font-bold text-foreground/40 hover:text-foreground/70 transition-colors py-2 uppercase tracking-widest cursor-pointer`,children:[d?`Hide`:`View`,` `,C.length,` archived`,(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 transition-transform duration-300 ${d?`rotate-180`:``}`})]})}),(0,i.jsx)(t.pr,{children:d&&(0,i.jsx)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden mt-4`,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:It(C).map(e=>(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(Lt,{label:e.label}),e.items.map(e=>(0,i.jsx)(Ht,{item:e,isExpanded:l===w(e),onToggle:()=>O(e),onArchive:()=>k(e),onDelete:()=>g(e),busy:p===w(e),dimmed:!0},w(e)))]},e.label))})})})]})]})})]})]}),(0,i.jsx)(He,{isOpen:!!h,title:`Delete this message?`,message:`This removes it for good. There is no undo — archive it instead if you only want it out of the way.`,onConfirm:A,onCancel:()=>g(null),isProcessing:_,confirmText:`Yes, delete`})]})}var Wt=`inline-flex items-center justify-center w-9 h-9 rounded-full border border-[var(--panel-border)] text-foreground/50 hover:text-accent hover:bg-foreground/5 transition-colors shrink-0 cursor-pointer`,Gt=({to:e})=>e?(0,i.jsx)(c.Link,{to:e,"aria-label":`Go back`,title:`Go back`,className:Wt,children:(0,i.jsx)(t.qi,{className:`w-4 h-4`})}):(0,i.jsx)(`button`,{type:`button`,onClick:()=>window.history.back(),"aria-label":`Go back`,title:`Go back`,className:Wt,children:(0,i.jsx)(t.qi,{className:`w-4 h-4`})}),Kt=e=>{if(!e)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**+r).toFixed(2))+` `+n[r]};function qt({title:e=`Drive`,subtitle:n=`/drive`,backUrl:a,filesCollection:u=`pub_files`,config:d,customContent:f,footer:p}){let{user:m,userRole:h}=t.Qi(),g=!!d,_=h===`admin`,v=u,y=u.startsWith(`user_`),[b,x]=(0,r.useState)([]),[S,C]=(0,r.useState)(!0),[w,T]=(0,r.useState)(null),[E,D]=(0,r.useState)(!0),[O,k]=(0,r.useState)(null),[A,j]=(0,r.useState)(!1),[M,N]=(0,r.useState)(null),[P,F]=(0,r.useState)(null),[I,L]=(0,r.useState)({}),[R,z]=(0,r.useState)(!1),[B,V]=(0,r.useState)(null),[H,U]=(0,r.useState)(``),[W,G]=(0,r.useState)(!1),[ee,K]=(0,r.useState)(``),[q,J]=(0,r.useState)(!1),Y=(0,r.useRef)(null);(0,r.useEffect)(()=>{D(!0)},[w?._id]),(0,r.useEffect)(()=>{if(!(y&&!m))return C(!0),(0,o.onSnapshot)(y?(0,o.query)((0,o.collection)(t.Ca,u),(0,o.where)(`uid`,`==`,m.uid)):(0,o.query)((0,o.collection)(t.Ca,u),(0,o.orderBy)(`createdAt`,`desc`)),e=>{let t=e.docs.map(e=>({_id:e.id,...e.data()}));t.sort((e,t)=>(t.createdAt?.toMillis?.()||0)-(e.createdAt?.toMillis?.()||0)),x(t),C(!1)},e=>{console.warn(`Error listening to ${u}:`,e),C(!1)})},[u,y,m?.uid]);let X=e=>!!m&&(e.uid===m.uid||_),te=e=>{V(e),U(e.name),K(``),z(!0)},ne=()=>{V(null),K(``),z(!0)},re=async e=>{if(e.preventDefault(),!(!B||!H.trim()||!m)){G(!0),K(``);try{let e=await t.or(B),n=`${v}/${`${Date.now()}_${e.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,r=(0,s.ref)(t.Ta,n);await(0,s.uploadBytes)(r,e,{customMetadata:{ownerId:m.uid}});let i=await(0,s.getDownloadURL)(r);await(0,o.addDoc)((0,o.collection)(t.Ca,u),{fileName:H.trim(),fileType:e.type||`unknown`,fileSize:e.size,downloadURL:i,storagePath:n,uid:m.uid,uploaderEmail:m.email||``,createdAt:(0,o.serverTimestamp)()}),z(!1),V(null),U(``)}catch(e){K(e?.code===`storage/unauthorized`?`You do not have permission to upload here.`:e?.message||`Upload failed. Please try again.`)}G(!1)}},Z=async()=>{if(O){j(!0);try{await Promise.all([(0,s.deleteObject)((0,s.ref)(t.Ta,O.storagePath||O.downloadURL)).catch(e=>console.warn(`Storage object missing:`,e)),(0,o.deleteDoc)((0,o.doc)(t.Ca,u,O._id))]),k(null)}catch(e){console.error(`Delete failed:`,e)}j(!1)}},Q=async()=>{if(!M||!M.name.trim()){N(null);return}try{await(0,o.updateDoc)((0,o.doc)(t.Ca,u,M.id),{fileName:M.name.trim()})}catch(e){console.error(`Rename failed:`,e)}N(null)},ie=(e,t)=>{navigator.clipboard.writeText(e),F(t),setTimeout(()=>F(null),2e3)},ae=(e,n=`row`)=>{let r=n===`card`?`w-16 h-16`:`w-10 h-10`,a=n===`card`?`w-8 h-8`:`w-5 h-5`;return e.includes(`video`)||e.includes(`audio`)?(0,i.jsx)(`div`,{className:`${r} flex items-center justify-center bg-accent/10 text-accent rounded-lg`,children:(0,i.jsx)(t.br,{className:a})}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,i.jsx)(`div`,{className:`${r} flex items-center justify-center bg-blue-500/10 text-blue-500 rounded-lg`,children:(0,i.jsx)(t.pi,{className:a})}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,i.jsx)(`div`,{className:`${r} flex items-center justify-center bg-yellow-500/10 text-yellow-500 rounded-lg`,children:(0,i.jsx)(t.Xi,{className:a})}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,i.jsx)(`div`,{className:`${r} flex items-center justify-center bg-emerald-500/10 text-emerald-500 rounded-lg`,children:(0,i.jsx)(t.Ci,{className:a})}):(0,i.jsx)(`div`,{className:`${r} flex items-center justify-center bg-foreground/5 text-foreground/40 rounded-lg`,children:(0,i.jsx)(t.fi,{className:a})})};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 flex flex-col min-h-screen relative`,onDragOver:e=>{e.preventDefault(),J(!0)},onDragLeave:e=>{e.preventDefault(),J(!1)},onDrop:e=>{e.preventDefault(),J(!1),e.dataTransfer.files?.[0]&&te(e.dataTransfer.files[0])},children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[!g&&(0,i.jsx)(Gt,{to:a}),(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(we,{children:e}),(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),n]})]})]}),g&&(0,i.jsx)(`div`,{className:`mb-6`,children:(0,i.jsx)(Ie,{})}),(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl md:rounded-3xl overflow-hidden flex-1 shadow-2xl min-h-[420px] md:min-h-[520px] mb-16 bg-background flex flex-col`,children:[(0,i.jsxs)(`div`,{className:`p-4 md:p-8 flex items-center justify-between gap-3 md:gap-6 border-b border-[var(--panel-border)]/50 bg-background/50`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-lg md:text-2xl font-extrabold text-foreground tracking-tight`,children:`Files`}),(0,i.jsx)(`p`,{className:`max-sm:hidden text-[12px] md:text-[13px] mt-1 md:mt-2 text-foreground/60 font-medium`,children:y?`Only you can see the files you upload here.`:`Everyone who can open this page can see these files.`})]}),!f&&(m?(0,i.jsxs)(t.cr,{onClick:ne,title:`Add file`,className:`flex items-center justify-center gap-2 w-9 h-9 p-0 sm:w-auto sm:h-auto sm:px-5 sm:py-2.5 rounded-xl text-[13px] font-bold shadow-md shrink-0`,children:[(0,i.jsx)(t.Hr,{className:`w-4 h-4`}),` `,(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:`Add file`})]}):(0,i.jsxs)(c.Link,{to:`/login`,title:`Sign in to add a file`,className:`btn-primary flex items-center justify-center gap-2 w-9 h-9 p-0 sm:w-auto sm:h-auto sm:px-5 sm:py-2.5 rounded-xl text-[13px] font-bold shadow-md shrink-0`,children:[(0,i.jsx)(t.Hr,{className:`w-4 h-4`}),` `,(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:`Add file`})]}))]}),f?(0,i.jsx)(`div`,{className:`fbos-content-slot p-4 md:p-8 flex-1`,children:(0,i.jsx)(f,{files:b,loading:S,user:m,uploadFile:te,deleteFile:k,openUploadModal:ne,config:d})}):(0,i.jsxs)(`div`,{className:`p-4 sm:p-6 md:p-8 flex-1 relative`,children:[S&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,i.jsx)(t.ei,{className:`w-8 h-8 text-accent animate-spin`})}),b.length>0?(0,i.jsx)(`div`,{className:`grid grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3 sm:gap-4`,children:b.map(e=>(0,i.jsxs)(`div`,{className:`flex flex-col bg-background border border-[var(--panel-border)] rounded-2xl hover:border-accent/40 transition-all group overflow-hidden shadow-sm h-[190px] relative`,children:[(0,i.jsxs)(`div`,{className:`absolute top-2 right-2 flex flex-col gap-1 opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 transition-opacity z-10 bg-background/90 backdrop-blur-md rounded-lg p-1 border border-[var(--panel-border)] shadow-xl`,children:[(0,i.jsx)(`a`,{href:e.downloadURL,download:!0,target:`_blank`,rel:`noreferrer`,className:`p-1.5 hover:bg-foreground/5 rounded-md text-foreground/60 hover:text-blue-500 transition-colors`,title:`Download`,children:(0,i.jsx)(t.yi,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),ie(e.downloadURL,e._id)},className:`p-1.5 hover:bg-foreground/5 rounded-md text-foreground/60 hover:text-emerald-500 transition-colors`,title:`Copy link`,children:P===e._id?(0,i.jsx)(t.Fi,{className:`w-4 h-4 text-emerald-500`}):(0,i.jsx)(t.ni,{className:`w-4 h-4`})}),X(e)&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),N({id:e._id,name:e.fileName})},className:`p-1.5 hover:bg-foreground/5 rounded-md text-foreground/60 hover:text-accent transition-colors`,title:`Rename`,children:(0,i.jsx)(t.Gr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),k(e)},className:`p-1.5 hover:bg-red-500/10 rounded-md text-foreground/60 hover:text-red-500 transition-colors`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`h-[120px] w-full border-b border-[var(--panel-border)]/50 bg-foreground/[0.02] flex items-center justify-center overflow-hidden relative cursor-pointer`,onClick:()=>T(e),children:e.fileType.startsWith(`image/`)?(0,i.jsxs)(i.Fragment,{children:[I[e._id]!==!1&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center bg-accent/5 z-0`,children:(0,i.jsx)(t.ei,{className:`w-5 h-5 text-accent animate-spin`})}),(0,i.jsx)(`img`,{src:e.downloadURL,alt:``,loading:`lazy`,className:`absolute inset-0 w-full h-full object-contain p-2 transition-opacity duration-300 ${I[e._id]===!1?`opacity-100`:`opacity-0`}`,onLoad:()=>L(t=>({...t,[e._id]:!1})),onError:()=>L(t=>({...t,[e._id]:!1}))})]}):ae(e.fileType,`card`)}),(0,i.jsxs)(`div`,{className:`p-3 flex flex-col justify-center flex-1 min-w-0`,onClick:()=>!M&&T(e),children:[M?.id===e._id?(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,value:M.name,onChange:e=>N({...M,name:e.target.value}),onBlur:Q,onKeyDown:e=>{e.key===`Enter`&&Q(),e.key===`Escape`&&N(null)},onClick:e=>e.stopPropagation(),className:`no-glow text-[12.5px] font-bold text-foreground bg-transparent border-b border-accent/30 outline-none pb-0.5 w-full`}):(0,i.jsx)(`span`,{className:`text-[12.5px] font-bold text-foreground truncate select-none group-hover:text-accent transition-colors`,title:e.fileName,children:e.fileName}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/40 font-bold uppercase tracking-wider mt-1 select-none`,children:Kt(e.fileSize)})]})]},e._id))}):!S&&(0,i.jsxs)(`div`,{onClick:()=>m&&z(!0),className:`min-h-[320px] flex flex-col items-center justify-center text-center cursor-pointer group`,children:[(0,i.jsx)(t.wi,{className:`w-12 h-12 text-foreground/15 mb-4`}),(0,i.jsx)(`p`,{className:`text-[20px] font-bold text-foreground/50 group-hover:text-foreground/70 transition-colors`,children:`No files yet`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium mt-1 text-foreground/40`,children:m?`Click here or drag a file in to upload`:`Sign in to upload a file`})]})]})]}),p,(0,i.jsx)(t.pr,{children:R&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>!W&&z(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/80 backdrop-blur-xl cursor-pointer`}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`w-full max-w-[480px] border-[var(--panel-border)] border rounded-3xl relative z-10 glass-panel shadow-2xl flex flex-col bg-background`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between p-4 md:p-6 border-b border-[var(--panel-border)]/50`,children:[(0,i.jsx)(`span`,{className:`text-[16px] font-extrabold text-foreground tracking-tight`,children:`Upload a file`}),(0,i.jsx)(`button`,{onClick:()=>!W&&z(!1),className:`text-foreground/40 hover:text-foreground transition-colors`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})})]}),B?(0,i.jsxs)(`form`,{onSubmit:re,className:`p-4 md:p-6 flex flex-col gap-5 md:gap-6`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-4 bg-foreground/[0.03] p-4 rounded-2xl border border-[var(--panel-border)]`,children:[ae(B.type),(0,i.jsxs)(`div`,{className:`flex flex-col flex-1 min-w-0 pr-4`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:B.name}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/50 font-bold uppercase tracking-wider mt-1`,children:Kt(B.size)})]}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>!W&&V(null),className:`w-8 h-8 flex items-center justify-center text-foreground/40 hover:text-red-500 rounded-xl hover:bg-red-500/10 transition-colors shrink-0`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsx)(`label`,{className:`text-[11px] font-bold text-foreground/50 uppercase tracking-widest pl-1`,children:`File name`}),(0,i.jsx)(`input`,{type:`text`,required:!0,value:H,onChange:e=>U(e.target.value),disabled:W,className:`no-glow w-full bg-foreground/[0.02] border border-[var(--panel-border)] rounded-xl px-4 py-3.5 text-[14px] font-bold text-foreground outline-none focus:border-accent transition-colors`})]}),ee&&(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-red-400 bg-red-500/10 border border-red-500/20 rounded-xl p-3`,children:ee}),(0,i.jsx)(t.cr,{type:`submit`,isLoading:W,className:`w-full py-4 rounded-xl text-[14px] font-bold shadow-lg`,children:W?`Uploading…`:`Upload`})]}):(0,i.jsx)(`div`,{className:`p-4 md:p-6`,children:(0,i.jsxs)(`label`,{onDragOver:e=>e.preventDefault(),onDrop:e=>{e.preventDefault(),e.dataTransfer.files?.[0]&&te(e.dataTransfer.files[0])},className:`group flex flex-col items-center justify-center gap-1.5 px-6 py-12 rounded-2xl border-2 border-dashed border-[var(--panel-border)] bg-foreground/[0.015] hover:border-accent/50 hover:bg-accent/[0.03] cursor-pointer text-center transition-all`,children:[(0,i.jsx)(`span`,{className:`w-14 h-14 rounded-full bg-accent/10 text-accent flex items-center justify-center mb-2 group-hover:scale-105 transition-transform`,children:(0,i.jsx)(t.wi,{className:`w-6 h-6`})}),(0,i.jsxs)(`p`,{className:`text-[15px] font-bold text-foreground`,children:[(0,i.jsx)(`span`,{className:`text-accent`,children:`Click to upload`}),` or drag a file in`]}),(0,i.jsx)(`p`,{className:`text-[12.5px] text-foreground/45 font-medium`,children:`Pictures, documents, anything`}),(0,i.jsx)(`input`,{type:`file`,ref:Y,"aria-label":`Upload a file`,onChange:e=>e.target.files?.[0]&&te(e.target.files[0]),className:`hidden`})]})})]})]})}),typeof window<`u`&&(0,l.createPortal)((0,i.jsx)(t.pr,{children:w&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>T(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(`button`,{onClick:()=>T(null),className:`absolute top-3 right-3 md:top-6 md:right-6 z-[160] w-10 h-10 md:w-12 md:h-12 bg-foreground/10 hover:bg-foreground/20 text-foreground rounded-full flex items-center justify-center backdrop-blur-md transition-all`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.95},className:`relative z-10 w-full max-w-6xl max-h-[85vh] flex flex-col shadow-2xl rounded-3xl overflow-hidden glass-panel border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between p-3.5 md:p-6 bg-background/80 backdrop-blur-md border-b border-[var(--panel-border)] shrink-0`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-3 md:pr-4`,children:[(0,i.jsx)(`span`,{className:`text-[15px] md:text-xl font-extrabold text-foreground truncate`,children:w.fileName}),(0,i.jsxs)(`span`,{className:`text-[10.5px] md:text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-0.5 md:mt-1 truncate`,children:[w.fileType,` • `,Kt(w.fileSize)]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 md:gap-2 shrink-0`,children:[(0,i.jsx)(`button`,{onClick:()=>ie(w.downloadURL,w._id),className:`p-2 md:p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 hover:text-emerald-500 transition-colors rounded-xl`,title:`Copy link`,children:P===w._id?(0,i.jsx)(t.Fi,{className:`w-4 h-4 text-emerald-500`}):(0,i.jsx)(t.ni,{className:`w-4 h-4`})}),X(w)&&(0,i.jsx)(`button`,{onClick:()=>{let e=w;T(null),k(e)},className:`p-2 md:p-2.5 bg-red-500/10 hover:bg-red-500/20 text-red-500 transition-colors rounded-xl`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})}),(0,i.jsx)(`a`,{href:w.downloadURL,download:!0,target:`_blank`,rel:`noreferrer`,className:`p-2 md:p-2.5 btn-primary transition-colors rounded-xl shadow-lg ml-0.5 md:ml-1`,title:`Download`,children:(0,i.jsx)(t.yi,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-0 h-[70vh]`,children:(0,i.jsxs)(`div`,{className:`absolute inset-4 md:inset-8 flex items-center justify-center`,children:[E&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center z-50 pointer-events-none`,children:(0,i.jsx)(t.ei,{className:`w-6 h-6 text-accent animate-spin`})}),w.fileType.startsWith(`image/`)?(0,i.jsx)(`img`,{onLoad:()=>D(!1),src:w.downloadURL,alt:w.fileName,className:`block max-w-full max-h-full w-auto h-auto object-contain rounded-lg transition-opacity duration-500 ${E?`opacity-0`:`opacity-100`}`}):w.fileType.startsWith(`video/`)?(0,i.jsx)(`video`,{onLoadedData:()=>D(!1),src:w.downloadURL,controls:!0,className:`max-w-full max-h-full rounded-lg transition-opacity duration-500 ${E?`opacity-0`:`opacity-100`}`}):w.fileType===`application/pdf`?(0,i.jsx)(`iframe`,{onLoad:()=>D(!1),src:w.downloadURL,className:`w-full h-full border-none bg-white rounded-lg transition-opacity duration-500 ${E?`opacity-0`:`opacity-100`}`,title:`PDF preview`}):(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center text-foreground/40 text-center`,onClick:()=>D(!1),children:[(0,i.jsx)(t.fi,{className:`w-24 h-24 mb-6 opacity-40`}),(0,i.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview unavailable`}),(0,i.jsx)(`span`,{className:`text-[14px] mt-2 text-foreground/60 font-medium max-w-xs`,children:`This format cannot be previewed. Download it instead.`})]})]})})]})]})}),document.body),(0,i.jsx)(He,{isOpen:!!O,title:`Delete file`,message:(0,i.jsxs)(i.Fragment,{children:[`Delete `,(0,i.jsx)(`strong`,{className:`text-foreground block my-1 break-words max-w-full text-center`,children:O?.fileName}),` This cannot be undone.`]}),onConfirm:Z,onCancel:()=>k(null),isProcessing:A,confirmText:`Yes, delete`}),(0,i.jsx)(t.pr,{children:q&&(0,i.jsx)(t.fr.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`fixed inset-0 z-[1000] bg-background/60 backdrop-blur-md pointer-events-none flex items-center justify-center p-6`,children:(0,i.jsxs)(`div`,{className:`w-full max-w-lg aspect-video bg-background/80 border-2 border-dashed border-accent rounded-[40px] shadow-2xl flex flex-col items-center justify-center gap-6`,children:[(0,i.jsx)(`div`,{className:`w-20 h-20 rounded-full bg-accent/10 flex items-center justify-center text-accent`,children:(0,i.jsx)(t.wi,{className:`w-10 h-10 animate-bounce`})}),(0,i.jsx)(`span`,{className:`text-[24px] font-extrabold text-foreground tracking-tight`,children:`Drop to upload`})]})})})]})}var Jt=[`mem_files`,`user_files`,`admin_files`],Yt=e=>!e.sourceTab;function Xt(){let[e,n]=(0,r.useState)(null),[a,c]=(0,r.useState)(!1),[l,u]=(0,r.useState)(!1),[d,f]=(0,r.useState)(``),[p,m]=(0,r.useState)(0);(0,r.useEffect)(()=>{let e=!1;return Promise.all(Jt.map(async e=>{try{return(await(0,o.getDocs)((0,o.collection)(t.Ca,e))).docs.map(t=>({collectionName:e,id:t.id,...t.data()}))}catch{return[]}})).then(t=>{e||n(t.flat())}),()=>{e=!0}},[]);let h=async()=>{if(!e)return;u(!0),f(``);let r=0;for(let n of e)try{let e=n.storagePath||n.downloadURL;e&&Yt(n)&&await(0,s.deleteObject)((0,s.ref)(t.Ta,e)).catch(()=>{}),await(0,o.deleteDoc)((0,o.doc)(t.Ca,n.collectionName,n.id)),m(e=>e+1)}catch(e){r+=1,console.error(`Could not delete ${n.collectionName}/${n.id}:`,e)}r>0?(f(`${r} file${r===1?``:`s`} could not be deleted. Reload and try again.`),n((await Promise.all(Jt.map(async e=>{try{return(await(0,o.getDocs)((0,o.collection)(t.Ca,e))).docs.map(t=>({collectionName:e,id:t.id,...t.data()}))}catch{return[]}}))).flat())):n([]),u(!1),c(!1)};if(!e||e.length===0)return null;let g=e.filter(Yt).length,_=Jt.map(t=>({name:t,n:e.filter(e=>e.collectionName===t).length})).filter(e=>e.n>0);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`mt-6 glass-panel border border-amber-500/25 bg-amber-500/[0.03] rounded-2xl md:rounded-3xl p-4 md:p-8`,children:[(0,i.jsxs)(`h3`,{className:`text-[17px] font-extrabold text-foreground tracking-tight mb-2`,children:[e.length,` leftover record`,e.length===1?``:`s`,` from the old Drive`]}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/60 leading-relaxed mb-3 max-w-2xl`,children:`Drive used to have Internal, User and Admin folders. They are gone — this page is the only built-in folder now, and each page you have built keeps its own files. Nothing reads these records any more.`}),(0,i.jsxs)(`p`,{className:`text-[14px] text-foreground/60 leading-relaxed mb-3 max-w-2xl`,children:[g>0?`${g} ${g===1?`was`:`were`} uploaded through the old Drive screen, so ${g===1?`its file is`:`their files are`} deleted too. `:``,e.length-g>0?`${e.length-g} belong to files a page still shows, so only the leftover record goes — the ${e.length-g===1?`file stays`:`files stay`} where ${e.length-g===1?`it is`:`they are`}.`:``]}),(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/50 font-medium mb-5`,children:_.map(e=>`${e.n} in ${e.name}`).join(` · `)}),d&&(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-red-400 bg-red-500/10 border border-red-500/20 rounded-xl p-3 mb-4`,children:d}),(0,i.jsxs)(`button`,{onClick:()=>c(!0),disabled:l,className:`inline-flex items-center gap-2 px-5 py-2.5 rounded-xl text-[13px] font-bold bg-red-500/10 hover:bg-red-500/20 text-red-500 border border-red-500/20 transition-colors disabled:opacity-50`,children:[l?(0,i.jsx)(t.ei,{className:`w-4 h-4 animate-spin`}):(0,i.jsx)(t.Or,{className:`w-4 h-4`}),l?`Deleting ${p} of ${e.length}…`:`Clean up all ${e.length} permanently`]})]}),(0,i.jsx)(He,{isOpen:a,title:`Delete the old Drive files`,message:(0,i.jsxs)(i.Fragment,{children:[`This permanently deletes `,(0,i.jsxs)(`strong`,{className:`text-foreground`,children:[e.length,` leftover record`,e.length===1?``:`s`]}),` `,`from `,_.map(e=>e.name).join(`, `),g>0&&(0,i.jsxs)(i.Fragment,{children:[`, along with the `,(0,i.jsxs)(`strong`,{className:`text-foreground`,children:[g,` file`,g===1?``:`s`]}),` uploaded through the old Drive screen`]}),`. It cannot be undone, and it covers every user's uploads, not only your own. Files that a page still shows are left alone.`]}),onConfirm:h,onCancel:()=>c(!1),isProcessing:l,confirmText:`Yes, delete them`})]})}function Zt(){let{isAdmin:e}=t.Qi();return(0,i.jsx)(qt,{title:`Assets`,subtitle:`/assets`,filesCollection:`pub_files`,config:{isAdmin:!0,pageId:`assets`},footer:e?(0,i.jsx)(Xt,{}):null})}var Qt=`fbos_theme_ai_draft`,$t=()=>{try{return JSON.parse(localStorage.getItem(Qt)||`{}`)}catch{return{}}},en=e=>{let t=String(e?.defaultTheme||``).trim();return t===`light`||t===`dark`?t:null},tn=`My logo is attached to this message as a picture. Read the colours straight out of that picture and build this look from them — that is what matching my logo means. If no picture reached you, say so and ask me for it, rather than picking colours of your own.`,nn=`Do it all in one file: src/your-ai-workflow-firebase-os/configs/theme.config.ts — the colours and how rounded things are. Do not restyle by rewriting components, and do not put colours of your own anywhere else.`,rn=`Use every colour the picture has, not just one. The accent is the one that stands out most — never one close to the accent the file holds now, so the change is plain to see — and the others go into the button fade, the heading gradient, the notification dot, the tint behind panels and the highlight behind selected text. Even the two backgrounds carry a faint wash of the logo instead of plain white or black. Read the exact shades off the picture; do not round them to the nearest colour you already know.`,an=`Mix a palette of your own for this brief — more than one colour. The accent is the one that stands out most — never one close to the accent the file holds now, so the change is plain to see — and the others go into the button fade, the heading gradient, the notification dot, the tint behind panels and the highlight behind selected text. Even the two backgrounds carry a faint wash of the palette instead of plain white or black.`,on=`Be as bold as my brief allows and decide everything yourself: this is your design, and a look that could pass for a default is the one thing I do not want. Mix each shade for this look. A swatch you know by heart from Tailwind, Material or any other stock palette — #38bdf8, #0f172a, #f8fafc and their kind — means you did not look, so mix your own instead. Keep text readable on its background in both modes.`,sn=`Every mode needs these five: background, backgroundSecondary, foreground, accent and buttonText. The other colours the file allows — the button fade and its hover, the quiet button, panel fill and edge, the focus glow, the notification dot, the heading gradient, and the highlight behind text someone selects together with the colour of that selected text — are yours to set wherever the look calls for them, and a colourful look wants the button fade, the heading gradient and the selection highlight at the least: selected text left in a colour from the look before is the first thing people notice. Where I have named a colour myself, use my exact value. Anything left in the file that you did not choose for this look, delete rather than keep: a colour left over from the look before is what makes a new theme come out wrong.`,cn=`Every mode keeps its five: background, backgroundSecondary, foreground, accent and buttonText. Where I name a colour, use my exact value, in both modes. If the change touches the accent, the highlight behind selected text follows it. Mix any new shade for this look rather than taking a stock swatch, and never copy a colour from another theme or an example.`,ln=(e,t)=>String(e||``).trim()===String(t||``).trim(),un=(e,t)=>e===`light`||e===`dark`?t.defaultTheme===e&&t.showThemeToggle===!1:e===`system`?t.defaultTheme===`system`:!1,dn=(e,t)=>{if(!t)return e;let n={...e};return ln(e.appName,t.appName)&&delete n.appName,ln(e.logoUrl,t.logoUrl)&&delete n.logoUrl,ln(e.faviconUrl,t.faviconUrl)&&delete n.faviconUrl,un(String(e.defaultTheme||``).trim(),t)&&delete n.defaultTheme,n},fn=`Before you tell me it is done, read the file back: if background, backgroundSecondary, foreground or accent is still the value it held when you started, in either mode, then you have not done what I asked — go and set it. And if every value you wrote is a stock swatch, you have not designed anything — go back and mix your own.`,pn=e=>{let t=en(e),n=`That is ten values at the least — five in dark, five in light — and every one of them changes: the colours in that file now are the look I am replacing, so a colour you leave where it is is the mistake I am trying to avoid.`;if(t){let e=t===`light`?`dark`:`light`;return`My site is ${t} only, so the ${t} colours are the ones everyone sees — design those with the most care. Set the ${e} colours as well, the same look ${e===`dark`?`at night`:`by day`}, since the file needs both. ${n}`}return`Set the dark colours and the light colours both, so my site reads well either way — the same hues in both, dark mode being the same look at night, not a second palette. ${n}`},mn=e=>{let t=String(e?.brief||``).trim(),n=String(e?.logoUrl||``).trim()!==``;return[...[`Design the look of my whole app. Here is what I am after: ${t||`___`}`,...n?[tn]:[],nn,pn(e),n?rn:an,on,sn,..._n(e),fn],...vn].join(`
|
|
4
|
+
`)},hn=(e,t)=>{let n=String(e?.changes||``).trim(),r=dn(e||{},t);return[...[`My app already has a look I am happy with, set in one file: src/your-ai-workflow-firebase-os/configs/theme.config.ts.`,`Change that one file, and change only what I ask for below. Do not restyle by rewriting components, and do not put colours of your own anywhere else.`,`Leave everything else in that file exactly as it is — how rounded things are, and every colour I have not mentioned. Do not tidy up, rebalance or improve anything I did not ask about.`,`If what I ask for is a colour, set it in the dark colours and the light colours both, so my site still reads well either way.`,cn,`Here is what I would like changed: ${n||`___`}`,..._n(r,`change`)],...vn].join(`
|
|
5
|
+
`)},gn=e=>{let t=String(e?.defaultTheme||``).trim();return t===`light`||t===`dark`?`In that same file, set defaultTheme to '${t}' and showThemeToggle to false: my site is ${t} only, and visitors get no switch.`:t===`system`?`In that same file, set defaultTheme to 'system', so my site opens in whichever mode the visitor's device already uses, and leave showThemeToggle as it is.`:`Leave defaultTheme exactly as it is — how my site opens is not part of this job, and changing it is not a redesign.`},_n=(e,t=`design`)=>{let n=String(e?.appName||``).trim(),r=String(e?.logoUrl||``).trim(),i=String(e?.faviconUrl||``).trim(),a=[`light`,`dark`,`system`].includes(String(e?.defaultTheme||``).trim()),o=a||t===`design`?[gn(e)]:[];if(n&&o.push(`In that same file, set appName to exactly: ${n}`),r&&o.push(`In that same file, set logoUrl to exactly this link: ${r} — that is my logo for the top bar. Use my link character for character, and never swap it for a placeholder or a picture of your own.`),i&&o.push(i===r?`Set faviconUrl to that same link — it is my browser tab icon too.`:`In that same file, set faviconUrl to exactly this link: ${i} — that is my browser tab icon. Use my link character for character.`),t===`change`){let e=[...r?[]:[`logoUrl`],...i?[]:[`faviconUrl`],...n?[]:[`appName`],...a?[]:[`defaultTheme and showThemeToggle`]];if(e.length){let t=e.length>1?`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`:e[0];o.push(`Leave ${t} exactly as they are — not part of this change.`)}return o}return!r&&!i?o.push(`Leave logoUrl and faviconUrl exactly as they are. The logo and the browser tab icon are mine, and my Theme screen is the only place they change.`):r?i||o.push(`Leave faviconUrl exactly as it is — my browser tab icon is mine, and my Theme screen is the only place it changes.`):o.push(`Leave logoUrl exactly as it is — my logo is mine, and my Theme screen is the only place it changes.`),o},vn=[`Tell me what you picked and why, in one short paragraph.`],yn=(e,t=`design`)=>t===`change`?String(e?.changes||``).trim()?``:`Say what you would like changed, and this sentence is ready to copy.`:String(e?.brief||``).trim()?``:`Say what look you are after, and this sentence is ready to copy.`;function bn(){let{activeConfig:e}=t.Da(),[n,a]=(0,r.useState)($t),[o,s]=(0,r.useState)(()=>$t().mode===`change`?`change`:`design`),l=e=>{s(e),a(t=>{let n={...t};e===`change`?n.mode=`change`:delete n.mode;try{localStorage.setItem(Qt,JSON.stringify(n))}catch{}return n})},u=(e,t)=>a(n=>{let r={...n,[e]:t};try{localStorage.setItem(Qt,JSON.stringify(r))}catch{}return r}),[d,f]=(0,r.useState)(!1),[p,m]=(0,r.useState)(null),h=()=>{f(!0);try{localStorage.removeItem(Qt),localStorage.removeItem(`theme-mode`),localStorage.removeItem(`last-seen-default-theme`),localStorage.removeItem(`theme_saved_cache`)}catch{}a({}),s(`design`),setTimeout(()=>f(!1),600)};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(we,{children:`Theme`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/theme`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,i.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-extrabold text-foreground tracking-tight`,children:o===`change`?`Change it with your assistant`:`Design it with your assistant`}),(0,i.jsxs)(`p`,{className:`text-[12.5px] sm:text-[13.5px] font-medium text-foreground/55 mt-1 sm:mt-1.5`,children:[(0,i.jsx)(`span`,{className:`sm:hidden`,children:`Fill these in for your assistant.`}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:o===`change`?`Say what to change, then copy the sentence below into your assistant’s chat. Nothing you do not mention is touched.`:`Fill these in, then copy the sentence below into your assistant’s chat. It designs the whole look — colours, corners, logo — and there is nothing to set by hand.`})]})]}),(0,i.jsx)(`div`,{className:`shrink-0 flex items-center gap-2`,children:(0,i.jsx)(t.Q,{icon:t.Lr,tone:`danger`,compact:!0,busy:d,title:`Start the whole look again`,onClick:()=>m({title:`Start the whole look again?`,message:`Your answers here clear and the sentence goes back to designing the whole look. Your theme file is not touched — copy the new sentence to your assistant to change it.`,apply:h}),children:`Start again`})})]}),(0,i.jsx)(ct,{label:`Logo`,hint:`The picture in the top bar. Attach this same picture in your assistant's chat — it cannot open the link, and the picture is where the colours come from.`,value:n.logoUrl||``,onChange:e=>u(`logoUrl`,e),tips:ut}),(0,i.jsx)(ct,{label:`Browser tab icon`,hint:`The tiny picture on the browser tab.`,value:n.faviconUrl||``,onChange:e=>u(`faviconUrl`,e),tips:dt}),(0,i.jsx)(t.ft,{label:`App name`,hint:`It goes in the top bar and on the browser tab.`,value:n.appName||``,onChange:e=>u(`appName`,e),placeholder:`Bright Studio`}),(0,i.jsx)(t.ct,{label:`How the site opens`,hint:`Only if you want it changed. Always light or always dark means one mode and no switch; otherwise whichever one the visitor already uses on their device, with a switch.`,value:n.defaultTheme||``,onChange:e=>u(`defaultTheme`,e),placeholder:`Leave it as it is`,options:[{value:`system`,label:`Whatever their device uses`},{value:`light`,label:`Always light`},{value:`dark`,label:`Always dark`}]}),o===`change`?(0,i.jsx)(t.dt,{label:`What would you like changed?`,hint:`Name just the parts you want moved. Everything else stays as it is.`,value:n.changes||``,onChange:e=>u(`changes`,e),placeholder:`Make the buttons a softer green, and warm up the page background a little. Leave the cards as they are.`}):(0,i.jsx)(t.dt,{label:`What look would you like?`,hint:`What you do, who it is for, and the feeling you are after. Your assistant designs the rest — the more feeling you give it, the further it goes.`,value:n.brief||``,onChange:e=>u(`brief`,e),placeholder:`A calm, modern look for a small physiotherapy clinic. Soft greens, lots of white space, nothing shouty. Rounded corners.`}),(0,i.jsx)(at,{title:`Copy this to your assistant`,prompt:o===`change`?hn(n,e):mn(n),locked:!!yn(n,o),onCopied:o===`change`?void 0:()=>l(`change`)}),(0,i.jsxs)(`p`,{className:`text-[11.5px] text-foreground/45 font-medium leading-snug px-1`,children:[`That sentence is the only way the look changes — there is nothing to set by hand here. Uploads are kept on your`,` `,(0,i.jsx)(c.Link,{to:`/assets`,className:`text-accent font-bold hover:underline`,children:`Assets page`}),` `,`too; edit the fields and copy the sentence again any time.`]})]})})]}),(0,i.jsx)(He,{isOpen:!!p,title:p?.title||``,message:p?.message||``,confirmText:`Start again`,cancelText:`Keep it`,isProcessing:d,onCancel:()=>m(null),onConfirm:()=>{p?.apply(),m(null)}})]})}function xn({tone:e,title:t,message:n,action:r}){let a=e===`red`?`border-red-500/20`:`border-amber-500/25`,o=e===`red`?`bg-red-500/5`:`bg-amber-500/5`,s=e===`red`?`text-red-500`:`text-amber-500`;return(0,i.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-center relative z-10 min-h-[60vh] animate-in fade-in duration-500`,children:(0,i.jsxs)(`div`,{className:`glass-panel p-8 md:p-10 rounded-3xl border ${a} text-center shadow-xl max-w-sm w-full relative overflow-hidden`,children:[(0,i.jsx)(`div`,{className:`absolute inset-0 ${o}`}),(0,i.jsx)(`h2`,{className:`text-2xl font-black ${s} mb-3 relative z-10 tracking-tight`,children:t}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/70 font-medium leading-relaxed relative z-10 mb-6`,children:n}),(0,i.jsx)(`div`,{className:`relative z-10`,children:r})]})})}var Sn=`w-full block py-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground text-[14px] font-bold rounded-xl transition-colors`,Cn=`No access`,wn=`You do not have access to view this page. If you think you should, ask whoever runs this app.`,Tn=()=>(0,i.jsx)(xn,{tone:`amber`,title:Cn,message:wn,action:(0,i.jsx)(c.Link,{to:`/dashboard`,className:Sn,children:`Back to dashboard`})}),En=Tn,Dn=Tn,On={route:`/page_1`,pageName:`New Page`,pageTitle:`My New Page`,template:`none`,form:``},kn={tabName:`New Page`,iconName:``,route:`/new-page`,tabTitle:`Your Page`,template:`none`,form:``},An={tabName:`New Admin Page`,iconName:``,route:`/new-admin-page`,tabTitle:`Admin Page`,template:`none`,form:``},jn={tabName:`New Team Page`,iconName:``,route:`/new-team-page`,tabTitle:`Team Page`,template:`none`,form:``},Mn=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``),Nn=`sys_payments`,Pn=`_settings`,Fn=()=>({on:!1,amount:``,priceId:``,livePriceId:``}),In=()=>({name:``,description:``,monthly:{...Fn(),on:!0},yearly:Fn()}),Ln=()=>({name:``,amount:``}),Rn=e=>({id:e,name:``,description:``,kind:``,amount:``,items:[],plans:[],how:``,emailReceipt:!0,notifyOwner:!0,pageIds:[],pagesNote:``,customNote:``,customPath:``,createdAt:Date.now()}),zn=e=>e.kind===`once`?e.items.length?e.items:e.name.trim()||e.amount.trim()?[{name:e.name,amount:e.amount}]:[]:[],Bn=e=>{let t=Number(String(e||``).trim().replace(/[^0-9.]/g,``));return Number.isFinite(t)&&t>0?t:null},Vn=e=>({on:!!e?.on,amount:String(e?.amount||``),priceId:String(e?.priceId||``),livePriceId:String(e?.livePriceId||``)}),Hn=e=>/^(no|none|nothing|n\/?a|nothing needed|nothing else|-)[.!]*$/i.test(e.trim()),Un=e=>/[.!?]$/.test(e)?e:`${e}.`,Wn=e=>{let t=[],n=String(e?.how||``),r=String(e?.collect||``).trim();r&&!Hn(r)&&t.push(`Before paying, the buyer tells me: ${Un(r)}`);let i=String(e?.after||``).trim();if(i&&t.push(`After they pay: ${Un(i)}`),Array.isArray(e?.plans))for(let n of e.plans){let e=String(n?.name||``).trim()||`The plan`,r=String(n?.features||``).trim(),i=String(n?.sees||``).trim();r&&t.push(`${e} unlocks: ${Un(r)}`),i&&t.push(`Someone on ${e} sees: ${Un(i)}`)}return t.length?[...n.trim()?[Un(n.trim())]:[],...t].join(` `):n},Gn=(e,t)=>{let n=t?.kind===`once`||t?.kind===`subscription`?t.kind:``,r=Array.isArray(t?.items)?t.items.map(e=>({name:String(e?.name||``),amount:String(e?.amount||``)})):[],i=String(t?.name||``),a=String(t?.amount||``);return n===`once`&&!r.length&&(i.trim()||a.trim())&&(r=[{name:i,amount:a}],i=``,a=``),{id:e,name:i,description:String(t?.description||``),kind:n,amount:a,items:r,plans:Array.isArray(t?.plans)?t.plans.map(e=>({name:String(e?.name||``),description:String(e?.description||``),monthly:Vn(e?.monthly),yearly:Vn(e?.yearly)})):[],how:Wn(t),emailReceipt:t?.emailReceipt!==!1,notifyOwner:t?.notifyOwner!==!1,pageIds:Array.isArray(t?.pageIds)?t.pageIds.map(e=>String(e||``)).filter(Boolean):[],pagesNote:String(t?.pagesNote||``),customNote:String(t?.customNote||``),customPath:String(t?.customPath||``),createdAt:typeof t?.createdAt==`number`?t.createdAt:void 0}},Kn=e=>/^price_[A-Za-z0-9]+$/.test(e.trim()),qn=(e,t=jr())=>t?e.livePriceId:e.priceId;function Jn(e,t=jr()){if(!e.kind)return`Say how it is paid — once, or a subscription.`;if(e.kind===`once`){let t=zn(e);if(!t.length)return`Add something to sell — a name and a price.`;for(let e of t){let t=e.name.trim();if(Bn(e.amount)===null)return`Give ${t||`it`} a price — just a number, like 25.`;if(!t)return`Give it a name, the way a buyer should read it.`}return``}if(!e.plans.length)return`Add at least one plan.`;for(let n of e.plans){let e=n.name.trim()||`each plan`;if(!n.name.trim())return`Give each plan a name.`;if(!n.monthly.on&&!n.yearly.on)return`Turn on monthly or yearly for ${e}.`;for(let[r,i]of[[`monthly`,n.monthly],[`yearly`,n.yearly]])if(i.on){if(Bn(i.amount)===null)return`Give ${e} its ${r} price — just a number.`;if(!Kn(qn(i,t)))return t?`Paste the live ${r} price id for ${e} — live mode is a fresh Stripe catalogue, so the price is made again there. Your test id is kept.`:`Paste the ${r} price id for ${e} — the steps above say where it comes from in Stripe.`}}return``}var Yn=(e,t=jr())=>Jn(e,t)===``,Xn=e=>e.kind===`subscription`&&e.plans.length>0&&e.plans.every(e=>e.name.trim()!==``&&(e.monthly.on||e.yearly.on)&&(!e.monthly.on||Bn(e.monthly.amount)!==null)&&(!e.yearly.on||Bn(e.yearly.amount)!==null));function Zn(e){let t=e.name.trim();if(t)return t;let n=zn(e);return n.length===1&&n[0].name.trim()?n[0].name.trim():`this product`}function Qn(e){let t=e.name.trim();if(!e.kind)return t?`${t} — say how it is paid`:`A new product — say how it is paid`;if(e.kind===`once`){let n=zn(e);if(n.length<=1){let e=n[0],r=e?.name.trim()||t,i=e?.amount.trim();return`${r||`A new product`}${i?` — ${i}, paid once`:` — paid once`}`}return`${t||n.map(e=>e.name.trim()).filter(Boolean).slice(0,3).join(`, `)||`A new product`} — ${n.length} things, paid once`}let n=e.plans.length;return`${t||`A new subscription`} — a subscription${n?`, ${n} plan${n===1?``:`s`}`:``}`}function $n(e,t,n=jr()){let r=e.name.trim(),i=`${t.name.trim()||`this plan`}${r?` — ${r}`:``}`,a=t.description.trim(),o=t.monthly.on&&t.yearly.on,s=t.monthly.on?t.monthly:t.yearly,c=t.monthly.on?`Monthly`:`Yearly`,l=[n?`In your Stripe dashboard, switch Test mode OFF — live mode is its own catalogue, so the plan is made once more there. Then open Product catalogue and click Add product.`:`In your Stripe dashboard, open Product catalogue and click Add product.`,`Name it "${i}"${a?` and paste your one-liner into the Description box: "${a}"`:``}.`,`On the same form, choose Recurring, type ${s.amount.trim()||`…`} as the amount, set the billing period to ${c}, and click Add product to save.`,o?`Click the product you just made, then click its ${c.toLowerCase()} price. The price id — it starts with price_ — sits in the top right corner: copy it and paste it into the ${c.toLowerCase()} box below.`:`Click the product you just made, then click the price inside it. The price id — it starts with price_ — sits in the top right corner: copy it and paste it into the box below.`];return o&&l.push(`Go back to the product. In its Pricing section click + to add a second price: Recurring, ${t.yearly.amount.trim()||`…`} as the amount, billing period Yearly — save it.`,`Click that yearly price, copy its id from the top right corner, and paste it into the yearly box below.`),l}var er=e=>e.includes(`'`)?`"${e}"`:`'${e}'`,tr=`Every payment goes through the app's own <PayButton> — never build a checkout, a card form or Stripe code of your own. The button's words, colour and place on the page are yours to design.`,nr=(e,t=jr())=>{let n=e.name.trim()||`this product`,r=e.description.trim();if(e.kind===`once`){let t=zn(e),r=e=>`<PayButton amount={${Bn(e.amount)??0}} productName=${er(e.name.trim())}>`;if(t.length<=1){let i=t[0]||{name:e.name,amount:e.amount};return[`It sells ${i.name.trim()||n} for ${i.amount.trim()}, paid once: ${r(i)}.`]}let i=e.name.trim();return[`It sells ${t.length} things${i?` under ${i}`:``}, each paid once with its own button:`,...t.map(e=>`${e.name.trim()||`Something`} for ${e.amount.trim()}: ${r(e)}.`)]}let i=[`It sells ${n}${r?` (${r})`:``} as a subscription. Lay its plans out as one pricing section — each plan is bought with its own button, and where a plan has monthly and yearly, offer a monthly/yearly switch:`];for(let n of e.plans){let e=n.name.trim()||`Plan`,r=n.description.trim(),a=[];n.monthly.on&&a.push(`${n.monthly.amount.trim()} per month: <PayButton priceId='${qn(n.monthly,t).trim()}' mode='subscription'>`),n.yearly.on&&a.push(`${n.yearly.amount.trim()} per year: <PayButton priceId='${qn(n.yearly,t).trim()}' mode='subscription'>`),i.push(`${e}${r?` (${r})`:``} — ${a.join(`; `)}.`)}return i},rr=`If my words ask the buyer for anything before paying — a phone number, a note, what they need — ask it with a form made the app's way: a *Form.config.ts whose fields are properly typed (tel for a phone number, email, date), shown with <ContactPopup formId='…' isInline onSubmitted={…} /> — never inputs you build by hand. onSubmitted hands you the answers as strings: put each one into the button's metadata as a plain string, and they read beside the order on my Payments screen. If my words ask for nothing, put no form in front of the button. Never ask for their email (Stripe collects it at checkout) and never build a backend of your own for this.`,ir=`Show and hide what a plan unlocks with the app's own useMyPayments() — it returns { loading, active, subscriptions, payments } — and that is presentation, not protection: anything genuinely paid, like a file or a secret, must come from the server.`;function ar(e,t=``,n=jr()){let r=[...nr(e,n)],i=e.how.trim();i&&r.push(`Here is how this payment should work, start to finish: ${i}`),r.push(rr),e.kind===`subscription`&&r.push(ir),r.push(`Set each button's successPath to ${t||`the page the button is on`} so the buyer lands back where they paid and finds what my words say happens after.`);let a=[];return e.emailReceipt&&a.push(`emailReceipt: 'yes'`),e.notifyOwner&&a.push(`notifyOwner: 'yes'`),a.length&&r.push(`Put ${a.join(` and `)} in the button's metadata — the app then sends ${a.length===2?`those emails`:`that email`} on its own.`),r}var or=e=>e===`internal`||e===`admin`,sr=()=>({name:``,address:``,type:`internal`,iconName:``,template:`none`,form:``,formFields:``,formButton:``,formSpot:``,about:``,formWish:``,images:[],imageNotes:``,booking:{schedules:[],party:`each`,ask:``,how:``}}),cr=e=>Array.isArray(e?.links)?e.links.map(e=>{let n={pageId:String(e?.pageId||``),how:String(e?.how||``)};if(e?.draft&&typeof e.draft==`object`){let r=e.draft,i=sr();n.draft={name:String(r.name??i.name),address:String(r.address??i.address),type:String(r.type||i.type),iconName:String(r.iconName??i.iconName),template:String(r.template||i.template),form:String(r.form??i.form),formFields:String(r.formFields??i.formFields),formButton:String(r.formButton??i.formButton),formSpot:String(r.formSpot??i.formSpot),about:String(r.about??i.about),formWish:String(r.formWish??i.formWish),images:Array.isArray(r.images)?r.images.map(e=>({url:String(e?.url||``),where:String(e?.where||``)})).filter(e=>e.url):[],imageNotes:String(r.imageNotes??i.imageNotes),booking:{schedules:Array.isArray(r.booking?.schedules)?r.booking.schedules.map(String).filter(Boolean):[],party:t.Wn(r.booking),ask:String(r.booking?.ask||``),how:String(r.booking?.how||``)}}}return n}):[],lr=(e,t)=>t.find(t=>t.id===e)||t.find(t=>String(t.config?.contentKey||``).trim()===e),ur=(e,t)=>e===t.id||e===String(t.config?.contentKey||``).trim();function dr(e){return e.how.trim()?``:`Describe how this payment will work.`}var fr=(e,t)=>t.filter(t=>e.pageIds.some(e=>ur(e,t))),pr=(e,t)=>e.pageIds.some(e=>ur(e,t)),mr=(e,t)=>pr(e,t)?e.pageIds.filter(e=>!ur(e,t)):[...e.pageIds,t.id],hr=(e,t)=>fr(e,t).length||e.pagesNote.trim()?``:`Tick the pages it goes on, or describe a page to add.`;function gr(e,t,n=jr()){if(!e.length)return`Describe what you sell first — the request is built from it.`;for(let t of e){let e=Qn(t).split(` — `)[0];if(!Yn(t,n))return`Finish ${e} under What you sell.`;if(dr(t))return`Say how ${e} works under How your payments work.`}for(let n of e){let e=Qn(n).split(` — `)[0];if(hr(n,t))return`Say where ${e} goes — tick its pages, or describe a page to add.`}return``}var _r={public:`anyone`,user:`signed-in users`,internal:`your team`,admin:`admins only`},vr=`Make everything match the rest of my app: style with the app's own theme styles so it looks right in light and dark. Do not pick your own colors. Build from the app's own pieces — import { SectionHeading, Card, Button } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button. Do not add a dropdown, a filter, a picker or a switch I did not ask for. If something I asked for needs a dropdown, it is CustomSelect from the same import (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser's own <select>, which ignores my theme. Everything must be readable: an icon or word on a button takes the button's own text color — give it no color of its own, so there is never a dark icon on a colored button — and nothing anywhere is light on light or dark on dark. If the page opens with a hero, make it the full height of the first screen (min-h-screen on that one section — never a fixed height, never overflow hidden), add visual elements that give it wow factor, and end it where the next section begins: the rest of the page comes after it, never inside it. The design should be minimal, modern and clean.`,yr=`This page is a screen inside my app, not a page of my website: it opens for somebody already signed in, under the heading and the menu the app draws itself, inside the app's own panel. So no full-height hero, no marketing sections, and no page heading, menu, background or wrapper of your own — begin with the thing the page is for.`,br=`Anything I have not decided — what the buyer is asked first, what they see after paying, what a plan unlocks, the section titles, the words on the buttons, the layout — decide yourself and build it finished; do not stop to ask me.`,xr="Read the sales on it with the app's own useSales() from 'your-ai-workflow-firebase-os' — it returns { loading, charges, subscriptions, error } live from my Stripe account: who paid, for what, when, and each subscription's current status. Show `error` when it is set. Design the list however fits; never write Stripe code, a backend or an export of your own for it. This page never sells — no <PayButton> on it.",Sr=[`A new page is made the app's way and no other: a page for anyone is one file src/your-ai-workflow-firebase-os/configs/somethingPage.config.ts exporting somethingPageConfig with route (its one web address, starting with /), pageName, pageTitle and form ('' for none); a page for signed-in users, my team or admins only is src/your-ai-workflow-firebase-os/configs/somethingTab.config.ts exporting somethingTabConfig with tabName, iconName, route, pageType ('user', 'internal' or 'admin'), tabTitle, template 'none' and form ''. Each page then gets ONE content file src/your-ai-workflow-firebase-os/microcomponents/SomethingContent.tsx with a default export, and its two lines in src/your-ai-workflow-firebase-os/microcomponents/registry.ts (import SomethingContent from './SomethingContent'; registerMicrocomponent('something', SomethingContent);). One page, one address, one config — never a second config for the same page, never a page written to Firestore, never a route or router of your own, never an edit to src/App.tsx or src/main.tsx.`,`A form — when my words ask for one — is one file src/your-ai-workflow-firebase-os/configs/somethingForm.config.ts exporting somethingFormConfig with systemName 'something' (the file name without Form, all lowercase), formType 'public' for anyone or 'private' for signed-in people, title, buttonName, submitText and typed fields (text, email, tel, textarea, number, date, select with options, checkbox, currency, file), shown with <ContactPopup formId='something' /> — isInline to build it into the page. Never build a form out of your own inputs; its entries would never reach my Inbox.`,`Pages connect with <Link to='/address'> from react-router-dom, or a Button that navigates there — never a router, a route or a web address of your own. A page for my team or admins never reads a pub_ or user_ page's data by hand, and a page for anyone never names a mem_, admin_ or user_ collection.`,`Every one of these pages appears on my Pages screen on its own, where I can rename it, move it, hide it or delete it — nothing to register anywhere else.`];function Cr(e){let t=e.audience||`public`,n=or(t),r=_r[t]||`anyone`,i=[`For the page at ${e.path}${e.title?` (${e.title})`:``}, which is for ${r}:`];if(e.id===`home`)i.push(`It is my home page and it is one file: src/your-ai-workflow-firebase-os/Home.tsx — change that one file. Keep its named export exactly as it is: export function Home. Never create a HomeContent.tsx, and do not create a page, a web address or a settings file for it.`);else if(e.id===`dashboard`)i.push(`It is my dashboard — the screen a signed-in person lands on — and its content is one file: src/your-ai-workflow-firebase-os/microcomponents/DashboardContent.tsx, with a default export. If it does not exist yet, write it and add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import DashboardContent from './DashboardContent'; and registerMicrocomponent('dashboard', DashboardContent); — never remove another page's lines from that file. It draws inside the dashboard's own panel, under the welcome heading and the menu, so write no page heading, menu or page wrapper of your own.`);else if(e.id===`contact`||e.id===`support`){let t=e.id===`contact`?`Contact`:`Support`;i.push(`It ships with my app and has its own form — do not create a page or a form for it, and do not change the questions its form asks. Its content is one file: src/your-ai-workflow-firebase-os/microcomponents/${t}Content.tsx, with a default export. If it does not exist yet, write it and add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import ${t}Content from './${t}Content'; and registerMicrocomponent('${e.id}', ${t}Content); — never remove another page's lines from that file. Keep showing its form with <ContactPopup formId='${e.id}' />.`)}else{let n=e.config||{},r=Mn(String(n.contentKey||n.tabName||n.pageName||n.pageId||e.title||``))||`Page`,a=r.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();i.push(`It already exists and is already in the menu — do not create a page, a web address or a settings file for it. Its content is one file: src/your-ai-workflow-firebase-os/microcomponents/${r}Content.tsx, with a default export. If that file does not exist yet, write it and add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import ${r}Content from './${r}Content'; and registerMicrocomponent('${a}', ${r}Content); — never remove another page's lines from that file. If it already exists, change it in place and keep everything on it my words do not mention.`),t!==`public`&&i.push(yr);let o=String(n.form||``).trim();o&&o!==`__new__`&&i.push(`The page already has a form, '${o}' — show it with <ContactPopup formId='${o}' /> and never remake it; add a question to it where it is defined if the payment needs one.`)}let a=String(e.brief??e.config?.brief??``).trim();return a&&i.push(`The page is for: ${a}`),n&&i.push(xr),i}var wr=e=>`${e.path}${e.title?` (${e.title})`:``}`;function Tr(e,t,n=jr()){let r=[`Build ${e.length===1?`my payment`:`my payments`} into my app. ${tr}`],i=[],a=!1;for(let o of e){let e=fr(o,t);for(let t of e)i.includes(t)||i.push(t);let s=e.filter(e=>!or(e.audience)),c=s.length===1?s[0].path:``;r.push(...ar(o,c,n));let l=Zn(o);e.length&&r.push(`${l} goes on ${e.length===1?`this page`:`these pages`} of mine: ${e.map(wr).join(`, `)}.`);let u=o.pagesNote.trim();u&&(a=!0,r.push(`Here is where ${l} goes and what should appear for it, in my words: ${u}`))}if(i.length){r.push(`Here are the pages of mine this touches — every one of them already exists:`);for(let e of i)r.push(...Cr(e))}return a?r.push(`If my words name a page that does not exist yet, add it. ${Sr[0]}`,...Sr.slice(1)):r.push(`If the payments need a page my words do not name, make it the app's way. ${Sr[0]}`),r.push(vr,br),r.push(`Build all of it in one turn. Do not touch any page this request does not name, and never write Stripe, checkout, billing or email code of your own — the app has all of it.`),r.join(`
|
|
6
|
+
`)}var Er=[],Dr=!1,Or=e=>{Er=e},kr=()=>Er,Ar=e=>{Dr=e},jr=()=>Dr;function Mr(e){let t=[];for(let n of e)if(n.kind===`subscription`)for(let e of n.plans)for(let[r,i]of[[`monthly`,e.monthly],[`yearly`,e.yearly]]){if(!i.on)continue;let a=i.priceId.trim(),o=i.livePriceId.trim();Kn(o)&&Kn(a)&&a!==o&&t.push({product:n.name.trim()||`a subscription`,plan:e.name.trim()||`its plan`,word:r,from:a,to:o})}return t}function Nr(e=kr()){let t=Mr(e),n=[`My Stripe account has switched from test mode to live mode. I have already replaced the keys in Secrets — do not touch any keys or write any Stripe code of your own.`];return t.length?n.push(`In my pages, every <PayButton> with a priceId still carries a test price id. Swap each one for its live id and change nothing else about the button:`,...t.map(e=>`For ${e.product}, ${e.plan} (${e.word}): replace '${e.from}' with '${e.to}'.`),`Buttons that use amount={…} instead of a priceId need no change.`):n.push(`No price id in my pages needs to change — buttons that use amount={…} never had one.`),n.push(`Then rebuild the app so it runs with the live keys and ids.`),n.join(`
|
|
7
|
+
`)}var Pr=[{id:`home`,title:`Home`,path:`/`,audience:`public`},{id:`contact`,title:`Contact`,path:`/contact`,audience:`public`},{id:`dashboard`,title:`Dashboard`,path:`/dashboard`,audience:`user`},{id:`support`,title:`Support`,path:`/support`,audience:`user`}],Fr=new Set([`home`,`drive`,`assets`,`contact`,`guide`,`templates`,`setup`,`support`,`theme`,`page_order`,`tab_order`]),Ir={public:0,user:1,internal:2,admin:3},Lr=(e,t)=>{let n=String(e||``).trim();return n?n.startsWith(`/`)?n:`/${n}`:`/${t}`},Rr=e=>new Set((Array.isArray(e?.order)?e.order:[]).filter(e=>e&&typeof e==`object`&&e.removed).map(e=>String(e.id)));function zr(e,n,r,i,a=b()){let o=[...Pr];for(let{id:t,data:n}of e)Fr.has(t)||o.push({id:t,title:String(n?.pageName||n?.title||t),path:Lr(n?.route,t),brief:String(n?.brief||``),config:n,audience:`public`});for(let{id:e,data:r}of n)Fr.has(e)||o.push({id:e,title:String(r?.tabName||r?.title||e),path:Lr(r?.route,e),brief:String(r?.brief||``),config:r,audience:t.pa(r?.pageType)});for(let[e,n]of a){if(Fr.has(e)||o.some(t=>t.id===e))continue;let a=!!n.isPublic;if((a?r:i).has(e))continue;let s=n.config||{},c=Lr(s.route,e);o.some(e=>e.path===c)||o.push({id:e,title:String(a?s.pageName||s.pageTitle||s.title||e:s.tabName||s.tabTitle||s.title||e),path:c,brief:String(s.brief||``),config:s,audience:a?`public`:t.pa(s.pageType)})}return o.sort((e,t)=>(Ir[e.audience||`public`]??9)-(Ir[t.audience||`public`]??9)||e.title.localeCompare(t.title))}function Br(){let[e,n]=(0,r.useState)(null),[i,a]=(0,r.useState)(null),[s,c]=(0,r.useState)(new Set),[l,u]=(0,r.useState)(new Set);return(0,r.useEffect)(()=>{let e=e=>{let t=[];return e.forEach(e=>t.push({id:e.id,data:e.data()})),t},r=[(0,o.onSnapshot)((0,o.collection)(t.Ca,`sys_pages`),t=>n(e(t)),()=>n([])),(0,o.onSnapshot)((0,o.collection)(t.Ca,`sys_tabs`),t=>a(e(t)),()=>a([])),(0,o.onSnapshot)((0,o.doc)(t.Ca,`sys_configs`,`page_order`),e=>c(Rr(e.exists()?e.data():null)),()=>{}),(0,o.onSnapshot)((0,o.doc)(t.Ca,`sys_configs`,`tab_order`),e=>u(Rr(e.exists()?e.data():null)),()=>{})];return()=>r.forEach(e=>e())},[]),e===null||i===null?null:zr(e,i,s,l)}var Vr=new Set(`login.register.reset-password.verify.payment-complete.payment-cancelled.guide.templates.drive.users.inbox.payments.schedule.my-calendar.my-bookings.email.submissions.requests.assets.theme.pages.forms.settings.profile.billing.dashboard.setup.publish`.split(`.`)),Hr=e=>Vr.has(String(e||``).replace(/^\/+/,``).split(`/`)[0].toLowerCase()),Ur=e=>{let t=String(e||``).replace(/^\/+/,``);return Hr(t)?`The app already uses /${t} for a screen of its own.`:`Another page already lives at /${t}.`},Wr=`fbos_records_`,Gr=(e,t)=>`${Wr}${t||`guest`}_${e}`;function Kr(e,t){try{let n=localStorage.getItem(Gr(e,t));return n?JSON.parse(n):null}catch{return null}}function qr(e,t,n){try{localStorage.setItem(Gr(e,t),JSON.stringify(n))}catch{}}function Jr(e){try{let t=`_${e}`,n=[];for(let e=0;e<localStorage.length;e++){let r=localStorage.key(e)||``;r.startsWith(Wr)&&r.endsWith(t)&&n.push(r)}n.forEach(e=>localStorage.removeItem(e))}catch{}}var Yr=`Could not reach the server. Check your connection and try again.`;async function Xr(e,n,r=!1){try{let i=r?await t.Sa?.currentUser?.getIdToken().catch(()=>null):null,a=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,...i?{Authorization:`Bearer ${i}`}:{}},body:JSON.stringify(n)}),o=await a.json().catch(()=>({}));return!a.ok||o?.success===!1?typeof o?.error==`string`&&o.error||`The email could not be sent.`:null}catch{return Yr}}function Zr(e,t={}){return Xr(`/api/email/notify`,{template:e,data:t})}function Qr(e,t,n,r={}){return Xr(`/api/email/send`,{template:e,collection:t,docId:n,data:r},!0)}function $r(e,t,n,r={}){return Xr(`/api/email/compose`,{to:e,subject:t,message:n,...r},!0)}async function ei(){try{let e=await(await fetch(`/api/email/status`)).json();return{configured:e?.configured===!0&&e?.enabled!==!1,from:e?.from??null,error:null}}catch{return{configured:!1,from:null,error:Yr}}}var ti=`sys_bookingpages`,ni=(e,t=``,n=``)=>({id:e,title:t,intro:``,photo:``,schedules:[],enabled:!0,memberId:n,createdAt:Date.now()}),ri=e=>e.normalize(`NFKD`).replace(/[\u0300-\u036f]/g,``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,48);function ii(e,t){let n=ri(e)||`page`;if(!t.includes(n))return n;for(let e=2;;e++){let r=`${n}-${e}`;if(!t.includes(r))return r}}var ai=e=>`/meet/${e}`;function oi(e,t){let n=t&&typeof t==`object`?t:{};return{id:e,title:String(n.title||``),intro:String(n.intro||``),photo:String(n.photo||``),schedules:Array.isArray(n.schedules)?n.schedules.filter(e=>typeof e==`string`||typeof e==`number`).map(String).filter(Boolean):[],enabled:n.enabled!==!1,memberId:String(n.memberId||``),createdAt:Number(n.createdAt)||0}}var si=(e,t,n)=>n?e:e.filter(e=>!!t&&e.memberId===t),ci=(e,t)=>e.schedules.map(e=>t.find(t=>t.id===e)).filter(e=>!!e),li=(e,n)=>ci(e,n).filter(t.Wt),ui=(e,t)=>({...e,schedules:e.schedules.includes(t)?e.schedules.filter(e=>e!==t):[...e.schedules,t]});function di(e,n){if(!e.title.trim())return`Give the page a name — usually the name of whoever it is for.`;if(!e.schedules.length)return`Tick at least one meeting to offer on this page.`;if(!li(e,n).length){let r=ci(e,n);return r.length?`${t.Mn(r[0])} is not taking bookings — switch it on above, or tick a different meeting.`:`The meetings picked for this page no longer exist — tick one that does.`}return``}var fi=e=>e.title.trim()||`Booking page`;function pi(){let[e,n]=(0,r.useState)({loading:!0,pages:[]});return(0,r.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(t.Ca,ti),e=>{let t=[];e.forEach(e=>t.push(oi(e.id,e.data()))),t.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)||e.id.localeCompare(t.id)),n({loading:!1,pages:t})},()=>n({loading:!1,pages:[]}));return()=>e()},[]),e}async function mi(e){try{let{id:n,...r}=e;return await(0,o.setDoc)((0,o.doc)(t.Ca,ti,n),{...r,updatedAt:Date.now()}),null}catch(e){return console.error(`Could not save the booking page`,e),`The page could not be saved — it is saved by whoever it belongs to, so make sure you are signed in as them or as an admin, and try again.`}}async function hi(e){try{return await(0,o.deleteDoc)((0,o.doc)(t.Ca,ti,e)),null}catch(e){return console.error(`Could not remove the booking page`,e),`It could not be removed — a page is removed by whoever it belongs to, or by an admin.`}}async function gi(e,n){if(e===n.id)return mi(n);let r=await mi(n);if(r)return r;try{await(0,o.deleteDoc)((0,o.doc)(t.Ca,ti,e))}catch(e){return console.error(`Could not remove the old booking page`,e),`The page moved, but its old address is still live — remove it and try again.`}return null}var _i=(e,n)=>[...e.map(e=>({path:t.Qt(e.id),id:e.id,kind:`link`,title:t.In(e)})),...n.map(e=>({path:ai(e.id),id:e.id,kind:`page`,title:fi(e)}))],vi=[],yi=e=>{vi=e},bi=()=>vi,xi=e=>(Array.isArray(e?.bookingLinks)?e.bookingLinks:[]).filter(e=>typeof e==`string`).map(e=>e.trim()).filter(Boolean),Si=e=>String(e?.bookingLinksNote||``).trim(),Ci=(e,t)=>e.includes(t)?e.filter(e=>e!==t):[...e,t],wi=(e,t=bi())=>xi(e).map(e=>t.find(t=>t.path===e)).filter(e=>!!e),Ti=`Never build a calendar, a time picker, a list of free times, a booking form or a schedule question because of one of those links, and never make a bookings collection of your own — the page each one opens already does all of that, inside my app. What the link says and where it sits on the page are yours to decide from my words. If my words ask for it to open in a pop-up, a panel or a window of its own rather than as a page, show that same address inside an overlay on this page — an <iframe> of it filling a dialog, with a close button — and still build no part of the booking yourself.`;function Ei(e,t=bi(),n){let r=wi(e,t).filter(e=>!n||n.includes(e.path));if(!r.length)return[];let i=r.map(e=>e.kind===`link`?`Put a link on this page to ${e.title} — my app's own booking page for that meeting, at ${e.path}. Link to that exact address with bookingPath('${e.id}') from 'your-ai-workflow-firebase-os'; it opens the booking page my app already has and the visitor books there.`:`Put a link on this page to ${e.title} — the booking page I made on my Schedule screen, at ${e.path}, which offers every meeting on it. Link to that exact address with meetPath('${e.id}') from 'your-ai-workflow-firebase-os'; it opens the page my app already has and the visitor books there.`);i.push(Ti);let a=Si(e);return a&&i.push(`Here is where those links should sit on this page and how they should open: ${a}`),i}var Di=(e,t=bi())=>{let n=t.find(t=>t.path===e);return`This page no longer links to ${n?n.title:`the booking page`} at ${e} — take that link off the page, and leave the booking page itself as it is.`},Oi=e=>`${t.In(e)} · ${t.Bn(e.slotMinutes)}`,ki=e=>{let n=t.in(e);return n?`${t.pn(e)} · ${n}`:t.pn(e)};function Ai({schedules:e,selected:n,onPick:a,placeholder:o=`Pick a schedule`,mode:s=`meetings`}){let[l,u]=(0,r.useState)(!1),d=s===`hours`,f=e=>d?t.pn(e):t.In(e),p=e=>d?ki(e):Oi(e),m=e=>d?t.gn(e):t.Wt(e),h=e=>d?t.hn(e)?`Unfinished on the Schedule screen`:``:e.enabled?t.Nn(e)?`Unfinished on the Schedule screen`:``:`Turned off on the Schedule screen`;if(e.length===0)return(0,i.jsxs)(`p`,{className:t.$,children:[d?`No hours yet`:`No schedule yet`,` — add `,d?`a week`:`one`,` on the`,` `,(0,i.jsx)(c.Link,{to:`/schedule`,className:`text-accent font-bold hover:underline`,children:`Schedule screen`}),` first.`]});let g=n.map(t=>e.find(e=>e.id===t)).filter(e=>!!e);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsxs)(`div`,{className:`w-full min-h-11 flex items-center gap-2 px-3 py-1.5 rounded-[var(--input-radius,0.75rem)] border bg-[var(--panel-bg)] transition-all duration-300 console-field ${l?`border-accent`:`border-[var(--panel-border)] hover:border-accent/40`}`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-wrap items-center gap-1.5`,children:[g.length===0&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>u(e=>!e),className:`text-[14px] text-foreground/35 text-left cursor-pointer`,children:o}),g.map(e=>(0,i.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 h-7 pl-2.5 pr-1.5 rounded-lg bg-accent/10 border border-accent/20 text-[12.5px] font-semibold text-foreground max-w-full`,children:[(0,i.jsx)(`span`,{className:`truncate`,children:f(e)}),(0,i.jsx)(`button`,{type:`button`,"aria-label":`Remove ${f(e)}`,onClick:()=>a(e.id),className:`w-4 h-4 rounded-md flex items-center justify-center text-foreground/50 hover:text-red-500 hover:bg-red-500/10 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})})]},e.id))]}),(0,i.jsx)(`button`,{type:`button`,"aria-label":l?`Close the list of schedules`:`Open the list of schedules`,"aria-expanded":l,onClick:()=>u(e=>!e),className:`w-8 h-8 shrink-0 rounded-lg flex items-center justify-center text-foreground/40 hover:text-foreground hover:bg-foreground/[0.05] transition-colors cursor-pointer`,children:(0,i.jsx)(t.Pi,{className:`w-4 h-4 transition-transform ${l?`rotate-180`:``}`})})]}),l&&(0,i.jsx)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60 px-2 py-1.5`,role:`listbox`,"aria-label":`Schedules`,"aria-multiselectable":!0,children:e.map(e=>{let r=n.includes(e.id),o=h(e);return(0,i.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":r,"aria-label":f(e),onClick:()=>a(e.id),className:`w-full flex items-center gap-2.5 px-2 py-2 text-left cursor-pointer rounded-xl hover:bg-foreground/[0.04] transition-colors ${m(e)?``:`opacity-70`}`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${r?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:r&&(0,i.jsx)(t.Fi,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate min-w-0`,children:p(e)}),o&&(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 whitespace-nowrap shrink-0 max-sm:hidden`,children:o})]},e.id)})}),(0,i.jsx)(`span`,{className:t.$,children:d?`One person’s hours each — picking a second week of theirs replaces the first.`:`One schedule per person — picking a second one of theirs replaces the first.`})]})}var ji=!1,Mi=e=>{ji=e},Ni=()=>ji,Pi=!1,Fi=e=>{Pi=e},Ii=()=>Pi,Li=[{id:`home`,title:`Home`,path:`/`,type:`public`,isSystem:!0,enabled:!0},{id:`contact`,title:`Contact`,path:`/contact`,type:`public`,isSystem:!0,enabled:!0},{id:`dashboard`,title:`Dashboard`,path:`/dashboard`,type:`user`,isSystem:!0,enabled:!0},{id:`support`,title:`Support`,path:`/support`,type:`user`,isSystem:!0,enabled:!0},{id:`profile`,title:`Profile`,path:`/profile`,type:`user`,isSystem:!0,enabled:!0},{id:`payments`,title:`Payments`,path:`/payments`,type:`admin`,isSystem:!0,enabled:!0},{id:`schedule`,title:`Schedule`,path:`/schedule`,type:`admin`,isSystem:!0,enabled:!0},{id:`email`,title:`Email`,path:`/email`,type:`admin`,isSystem:!0,enabled:!0},{id:`assets`,title:`Assets`,path:`/assets`,type:`admin`,isSystem:!0,enabled:!0}],Ri=new Set([`home`,`dashboard`,`profile`]),zi=e=>[...e.filter(e=>!e.isSystem||Li.some(t=>t.id===e.id)),...Li.filter(t=>!e.some(e=>e.id===t.id))],Bi={public:`Anyone`,user:`Members`,internal:`Your team`,admin:`Admins only`},Vi={public:`Website Pages`,tabs:`Tabs`},Hi=[{value:`user`,label:`Members`},{value:`internal`,label:`Your team`},{value:`admin`,label:`Admins only`}],Ui=e=>{let n=t.ba(e),r=n.filter(t.ua);if(!r.length)return[];let i=r.map(e=>vt(e)).join(` or `),a=t._a(e);return a?[`This page is only for the people I have marked ${i}: the app turns everybody else away at the address itself, so never write a guard, a redirect or a sign-in check of your own on it.`,`Whatever everybody marked ${i} SHARES on this page — one list they all read, add to and edit — goes in collections whose names begin role_${a}_: role_${a}_projects, role_${a}_notes, whatever it needs. My security rules open those to the people marked ${i}, to my admins, and to nobody else, and every one of them reads and writes the SAME records there.`,`Whatever belongs to ONE of them and the others must not see — their own documents, their own answers — stays in the ordinary user_ collections, where each person only ever reads the records that carry their own uid — the ones they added, and the ones my admins put there for them. Nothing anybody marked ${i} has to read may sit in a mem_, admin_ or pub_ collection: mem_ and admin_ answer them with a permission error, and pub_ is the open internet.`]:[`${n.includes(`user`)?`This page is for the people I have marked ${i} as well as everybody else who signs in.`:n.includes(`internal`)?`This page is for the people I have marked ${i} and for my team, and for nobody else who signs in.`:`This page is only for the people I have marked ${i}, and for nobody else who signs in.`} The app decides who may open it — never write a guard, a redirect or a sign-in check of your own on it.`,`Its data stays in the ordinary user_ collections, where each person only ever reads the records that carry their own uid — the ones they added, or ones my admins put there for them. So nothing on this page is shared between the people who can open it: two of them on the same page see two different lists. Never write a query that reads other people's records here — it is refused, not empty. If what I described needs ONE list they all share, say so and tell me the page has to be kept for a single role instead.`]},Wi=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),Gi=e=>{let t=e.map(e=>String(e.name||``).trim()).filter(Boolean).map(Wi);return[{key:`admin`,re:/\b(admins?|administrators?|only i|only me|just me|myself|nobody but me)\b/gi},{key:`team`,re:/\b(my team|the team|our team|team members?|teammates?|staff|colleagues?|internal(?: users?| members?| people| staff)?)\b/gi},...t.length?[{key:`role`,re:RegExp(`\\b(${t.join(`|`)})s?\\b`,`gi`)}]:[],{key:`named`,re:/\b(clients?|customers?|suppliers?|vendors?|partners?|patients?|students?|tenants?|contractors?|subscribers?)\b/gi},{key:`guest`,re:/\b(guests?|visitors?|the public|anyone not signed in)\b/gi},{key:`member`,re:/\b(members?|free users?|signed[- ]in (?:users?|people|visitors?))\b/gi}]},Ki=(e,t=_t())=>{let n=` ${String(e||``)} `,r=[];for(let e of Gi(t)){let t=n;n=n.replace(e.re,` `),n!==t&&r.push(e.key)}return r},qi=/\b(only|cannot|can not|can'?t|must not|should ?n[o’']?t|not allowed|no access|hidden from|kept from|never sees?|does ?n[o’']?t see|do not see|read[ -]only|view only)\b/i,Ji=/[^.!?;\n]+/g,Yi=(e,t=_t())=>{let n=String(e||``);return n.trim()?Ki(n,t).length>1?!0:(n.match(Ji)||[]).some(e=>Ki(e,t).length>0&&qi.test(e)):!1},Xi=/\b(assign(?:ed|s|ing|ment|ments)?|allocated|responsible for|each of (?:my|our|the) (?:team|staff|people|users)|their own records?)\b/i,Zi=`Then show each person only the sections that are theirs: read const { userRole } = useAuth() from 'your-ai-workflow-firebase-os' — 'admin' is one of my admins, 'internal' is my team, a role of my own arrives as that role's own plain word, and anything else is an ordinary member. Leave a section OUT of the page for somebody it is not for rather than rendering it: a section that reads a collection that person may not read answers with a permission error, and a permission error is never an empty list — never draw it as “nothing here yet”.`,Qi=`Only the groups my words actually name, and only INSIDE the page: never invent a group or a role word of your own, never add a check for anybody I did not mention, and never guard the page itself, redirect anyone or test whether they are signed in — who may open this page is my app’s decision and it is already made.`,$i=`Anything one group must not see is its OWN document in one of those collections, never a field sitting beside what they do see: whoever may read a document reads every field of it. And where my words say a group may look at something without changing it, or may remove a record without editing it, build them exactly those buttons and leave the others out of their view.`,ea=[`Where my words say each of my team sees only what is assigned to them, those records go in a user_ collection with the assignee’s own uid on every document — my rules then show each of them their own and nobody else’s, and a colleague cannot so much as list them. Read them back with a query on that uid, never by fetching the collection and filtering afterwards.`,`Handing a record to somebody else is an ADMIN’s doing: only an admin may write a document carrying another person’s uid, so put the assigning where an admin does it, and never build a team member a button that assigns a record to a colleague — it answers with a permission error.`],ta=(e,n,r=String(n?.brief||``),i=!1)=>{if(!Wa(e,n))return[];let a=t.pa(n?.pageType);if(a===`admin`)return[];let o=_t();if(!i&&!Yi(r,o))return[];let s=a===`internal`,c=s?``:t._a(n),l=c?vt(c,o):``,u=[`What I say about this page gives different people different things to see on it. Build that by WHERE each thing is kept, before anything else: ${c?`what everybody marked ${l} shares in role_${c}_ collections and what belongs to one of them in user_ collections, as above, and — the third space — what only my admins may ever see, in admin_ collections`:`${s?`what my whole team works on stays in mem_ collections, `:``}what only my admins may ever see goes in admin_ collections, and what belongs to ONE person alone goes in user_ collections with that person’s own uid on every document`}. My security rules hold those apart by themselves, so a thing kept in the right place is really kept from everybody else — a section merely hidden in the code is not kept from anybody, because the database is still open to them.`,`My admins read every document in all of those collections, so where my words give my admins the whole list it is the same query with nobody’s uid on it — never a second copy of the records kept somewhere else.`];return!s&&!c&&!t.ba(n).some(t.ua)&&u.push(`There is no space on this page that every member shares: a list they could all read would have to be a pub_ one, open to the whole internet. So keep to per-person records unless my words ask for something I would not mind a stranger reading.`),!s&&t.ba(n).includes(`internal`)&&u.push(`My team can open this page too, but on it they are like everybody else who signs in: each of them reads only the records that carry their own uid, never anybody else’s — only my admins read everybody’s. Where my words give my team other people’s records, build that for my admins alone and tell me my team cannot have it on this page.`),u.push(Zi,Qi,$i),s&&Xi.test(r)&&u.push(...ea),c&&Ki(r,o).includes(`team`)&&u.push(`One thing this page cannot do: the people I have marked internal do not read role_${c}_ collections at all — only the people marked ${l} and my admins do. So anything my TEAM has to see belongs on a team page of its own rather than here, and on this page “my team” means my admins.`),u},na=e=>{if(!e?.pageType)return[];let n=e=>e===`user`?0:e===`internal`?1:e===`admin`?3:2,r=[...new Set([...t.aa(e),`admin`])].sort((e,t)=>n(e)-n(t));return r.length>1?r:[]},ra=(e,t)=>e===`user`?`Members`:e===`internal`?`Your team`:e===`admin`?`You and your admins`:vt(e,t),ia={user:`See and change only what they added themselves.`,internal:`See every job and move it along, but never delete one.`,admin:`Everything — and only we see what each job was charged.`,role:`See their own projects and the shared price list, and add notes — never delete anything.`},aa=e=>{let t=e?.canDo&&typeof e.canDo==`object`?e.canDo:{},n={};for(let r of[...na(e)].sort()){let e=String(t[r]??``).trim();e&&(n[r]=e)}return n},oa=e=>e===`user`?`Members (everybody who signs in)`:e===`internal`?`My team`:e===`admin`?`Me and my admins`:`The people I have marked ${vt(e)}`,sa=`What each of them may do on this page, in my own words — build each group exactly the sections, and the add, change and delete buttons, its line gives it. A group I say nothing about here is yours to decide:`,ca=`What each of them may do on this page has changed. This is the whole of it now, in place of what I said before — build each group exactly the sections, and the add, change and delete buttons, its line gives it:`,la=(e,t=sa)=>{let n=aa(e),r=na(e).filter(e=>n[e]);return r.length?[t,...r.map(e=>`${oa(e)}: ${n[e]}`)]:[]},ua=(e,n=[])=>{let r=`Optional — for each, what they see here and what they can add, change or delete. Whatever you skip, your assistant decides.`;if(t.pa(e?.pageType)!==`user`)return r;let i=t._a(e);if(i)return`Only the people you have marked ${vt(i,n)} and your admins can open this page — mark them on your Users screen. ${r}`;let a=t.ba(e),o=a.filter(t.ua);return o.length?`${o.map(e=>vt(e,n)).join(` and `)} ${o.length>1?`are`:`is`} ticked alongside another audience, so this page cannot hold a list they all share — everybody who opens it keeps only what they added themselves. For one shared list, tick a single role and nothing else. ${r}`:a.includes(`internal`)?`Your team opens this page too, but here each of them keeps only their own records, like any member — only you and your admins see everybody's. For one list your whole team shares, tick Your team alone. ${r}`:r},da=e=>e.draft?`draft`:e.hidden?`hidden`:`live`,fa={draft:`Draft`,live:`Live`,hidden:`Hidden`},pa={draft:`Nothing is saved yet. Give it a name and the page is created.`,live:`This page is live at its web address and listed in the menu.`,hidden:`This page still exists at its web address, but it is out of the menu.`},ma=e=>(e||``).trim().toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9_-]/g,``),ha=e=>String(e||``).replace(/^\/+/,``).replace(/[^a-zA-Z0-9_-]/g,`_`).toLowerCase();function ga(e){let n=ma(e.address);if(!n)throw Error(`A page needs a web address.`);let r=ha(`/`+n),i=e.type===`public`,a={form:e.form||``,formFields:e.formFields||``,formButton:e.formButton||``,formSpot:e.formSpot||``,formWish:e.formWish||``};e.images?.length&&(a.images=e.images.filter(e=>e.url).map(e=>({url:e.url,where:e.where||``})),a.imageNotes=e.imageNotes||``),e.booking?.schedules?.length&&(a.booking={schedules:e.booking.schedules,party:t.Wn(e.booking),ask:e.booking.ask||``,how:e.booking.how||``});let o=i?{route:`/`+n,pageName:e.name,pageTitle:e.name,...a,brief:e.about,contentKey:r}:{route:`/`+n,tabName:e.name,tabTitle:e.name,iconName:e.iconName||``,template:wa.some(t=>t.value===e.template)?e.template:`none`,...a,brief:e.about,pageType:e.type,contentKey:r};return o.form===`__new__`&&(o.form=Vo(o),o.formIsNew=!0),{id:r,config:o,isPublic:i}}async function _a(e){let{id:n,config:r,isPublic:i}=ga(e);await(0,o.setDoc)((0,o.doc)(t.Ca,i?`sys_pages`:`sys_tabs`,n),r);let a=i?`page_order`:`tab_order`,s=await(0,o.getDoc)((0,o.doc)(t.Ca,`sys_configs`,a)),c=(s.exists()?s.data()?.order:null)||[];return c.some(e=>(typeof e==`string`?e:String(e?.id))===n)||await(0,o.setDoc)((0,o.doc)(t.Ca,`sys_configs`,a),{order:[...c,{id:n,hidden:!1}]}),n}var va=(e,t,n,r)=>{let i=e.findIndex(e=>e.id===t);if(i===-1)return null;let a=r&&e[0]?.id===r?1:0,o=n===`up`?Math.max(a,i-1):Math.min(e.length-1,i+1);if(o===i||o<a)return null;let s=[...e],[c]=s.splice(i,1);return s.splice(o,0,c),s},ya=()=>Object.fromEntries(b()),ba=(e,n=!1)=>{let r={};for(let[i,a]of Object.entries(ya())){let o=!!a.isPublic;if(o!==e)continue;let s=a.config||{};!n&&s.enabled===!1||(r[i]={id:i,title:o?s.pageName||s.pageTitle||s.title||i:s.tabName||s.tabTitle||s.title||i,path:s.route?s.route.startsWith(`/`)?s.route:`/`+s.route:`/`+i,type:o?`public`:t.pa(s.pageType),isSystem:!1,enabled:s.enabled!==!1,fromFile:!0})}return r};function xa({roles:e,picked:n,onChange:a,onCreateRole:o,busy:s}){let[c,l]=(0,r.useState)(!1),[u,d]=(0,r.useState)(``),[f,p]=(0,r.useState)(``),[m,h]=(0,r.useState)(!1),g=[...Hi,...e.map(e=>({value:e.id,label:e.name}))],_=e=>{let t=n.includes(e)?n.filter(t=>t!==e):[...n,e];t.length&&a(t)},v=async()=>{let r=yt(u,e);if(r){p(r);return}h(!0);try{let e=await o(u.trim());a([...n.filter(t.ua),e.id]),d(``),l(!1),p(``)}catch(e){p(e?.message||`The role could not be saved. Try again.`)}h(!1)};return(0,i.jsx)(`div`,{className:`shrink-0 min-w-0 max-w-[14rem]`,onClick:e=>e.stopPropagation(),children:(0,i.jsx)(t.sr,{multiple:!0,compact:!0,portal:!0,direction:`auto`,className:`console-select`,ariaLabel:`Who can open this page`,values:n,options:g,onChange:_,footer:(0,i.jsx)(`div`,{className:`mt-1 pt-1 border-t border-[var(--panel-border)]/60`,children:c?(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 p-2`,children:[(0,i.jsx)(`input`,{autoFocus:!0,value:u,disabled:m,placeholder:`Client`,"aria-label":`Name the role`,onChange:e=>{d(e.target.value),f&&p(``)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),v()),e.key===`Escape`&&(e.preventDefault(),l(!1),p(``))},className:t.et}),f&&(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:f}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(t.Q,{onClick:v,disabled:m,children:m?`Adding…`:`Add role`}),(0,i.jsx)(t.Q,{onClick:()=>{l(!1),p(``)},children:`Cancel`})]})]}):(0,i.jsxs)(`div`,{role:`option`,"aria-selected":!1,onClick:()=>l(!0),className:`flex items-center gap-2 px-3 py-2.5 text-[13px] font-semibold text-accent hover:bg-foreground/5 cursor-pointer`,style:{borderRadius:`calc(var(--input-radius, 0.75rem) - 0.25rem)`},children:[(0,i.jsx)(t.Hr,{className:`w-3.5 h-3.5 shrink-0`}),`Custom role…`]})}),disabled:s,placeholder:`Pick who`})})}var Sa=`Add it here — a name and what you would like to see on it — then copy the sentence for your assistant.`,Ca=`Add it here, then copy the sentence for your assistant.`,wa=[{value:`none`,label:`From scratch`},{value:`board`,label:`Board`},{value:`table`,label:`Table`},{value:`calendar`,label:`Calendar`},{value:`drive`,label:`Files`}],Ta=[`board`,`table`,`calendar`,`drive`],Ea={board:{is:`a board`,keeps:`its board frame and the card editor that is already in it`,open:`actions.openInlineEditor(columnId)`},table:{is:`a table`,keeps:`its table frame and the row and column controls that are already in it`,open:`actions.addRow()`},calendar:{is:`a calendar`,keeps:`its calendar frame — the month heading, Today, and the arrows — and the add-event form that is already in it`,open:`actions.openAddModal()`},drive:{is:`a file library`,keeps:`its file frame and the upload box that is already in it`,open:`openUploadModal()`}},Da=e=>{let t=Ea[e];return t?`This page already works as ${t.is} and it stays one: it keeps ${t.keeps}, already styled to match my app. Design only what fills it, and open the one that is already there with ${t.open}. Never build your own add, edit or upload form on this page — one exists, and yours will not match.`:``},Oa=e=>Xe(e,1)[0]||``,ka=(e,t)=>t?.contentKey||t?.tabName||t?.pageName||t?.pageId||e.title,Aa=(e,t)=>`src/your-ai-workflow-firebase-os/microcomponents/${Mn(ka(e,t))||`Page`}Content.tsx`,ja=(e,t)=>{let n=String(t?.route||``).trim();return n?n.startsWith(`/`)?n:`/`+n:e.path||``},Ma=(e,n,r=[])=>ja(e,n).replace(/^\/+/,``)?String(n?.brief||``).trim()?Ho(n)?`Say what the forms should ask for, and this sentence is ready to copy.`:Jo(n)||cs(n,r)||t.Jt(n,t.bn(),t.yn()):`Say what you would like to see on this page, and this sentence is ready to copy.`:`Give this page a name and it will be created — then this sentence is ready to copy.`,Na=e=>{let t=e=>e.map(e=>({url:String(e?.url||``).trim(),where:String(e?.where||``).trim()})).filter(e=>e.url);if(Array.isArray(e?.images))return t(e.images);let n=String(e?.imageUrl||``).trim();return n?[{url:n,where:String(e?.imageWhere||``).trim()}]:[]},Pa=e=>Array.isArray(e?.images)?e.images.map(e=>({url:String(e?.url||``),where:String(e?.where||``)})):Na(e),Fa=e=>String(e?.imageNotes||``).trim(),Ia=e=>{let t=Na(e);if(!t.length)return[];if(t.some(({where:e})=>e))return t.map(({url:e,where:t})=>t?`Use this picture of mine on the page: ${e} — where it goes: ${t}. Keep its proportions and give it a short description for screen readers. Do not swap it for a placeholder or a picture of your own.`:`Use this picture of mine on the page: ${e} — put it where it works best in your design, keep its proportions, and give it a short description for screen readers. Do not swap it for a placeholder or a picture of your own.`);let n=t.map(({url:e},t)=>`${t+1}: ${e}`).join(`; `),r=Fa(e);return[`Use these pictures of mine on the page, numbered the way I refer to them — ${n}. Keep their proportions, give each a short description for screen readers, and never swap one for a placeholder or a picture of your own.`,r?`Here is how the pictures go: ${r}`:`Put each picture where it works best in your design.`]},La=e=>{if(!Array.isArray(e?.imagesSent))return[];let t=new Set(e.imagesSent.map(String));return Na(e).filter(({url:e})=>!t.has(e))},Ra=e=>{let t=La(e);if(!t.length)return[];let n=Na(e),r=t.map(e=>`${n.findIndex(t=>t.url===e.url)+1}: ${e.url}`).join(`; `),i=Fa(e);return[`I have added ${t.length===1?`a picture`:`pictures`} to the page's gallery, numbered the way I refer to them — ${r}. Use ${t.length===1?`it`:`them`} on the page: keep the proportions, give each a short description for screen readers, and never swap one for a placeholder or a picture of your own.`,i?`Here is how the pictures go: ${i}`:`Put each where it works best in your design, unless my words below say where.`]},za=e=>Array.isArray(e?.imagesSent)?Ra(e):Ia(e),Ba=e=>!e||typeof e!=`object`?!1:Object.entries(e).some(([e,t])=>e===`sent`||e===`imagesSent`?!1:Array.isArray(t)?t.length>0:t&&typeof t==`object`?Object.keys(t).length>0:String(t??``).trim()!==``),Va=`Make it match the rest of my app: style with the app’s own theme styles so it looks right in light and dark. Do not pick your own colors. Build it from the app’s own pieces — import { SectionHeading, Card, Button } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button — so nothing gets a look of its own. Do not add a dropdown, a filter, a picker or a switch I did not ask for. If something I asked for needs a dropdown, it is CustomSelect from the same import (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme. Everything must be readable: an icon or word on a button takes the button’s own text color — give it no color of its own, so there is never a dark icon on a colored button — and nothing anywhere is light on light or dark on dark. The design should be minimal, modern and clean and match the app.`,Ha=`Keep it matching the rest of my app: style with the app’s own theme styles so it looks right in light and dark. Do not pick your own colors. Anything new you draw uses the app’s own pieces — import { SectionHeading, Card, Button } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button. Do not add a dropdown, a filter, a picker or a switch I did not ask for. If something I asked for needs a dropdown, it is CustomSelect from the same import (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme. Everything must be readable: an icon or word on a button takes the button’s own text color — give it no color of its own, so there is never a dark icon on a colored button — and nothing anywhere is light on light or dark on dark.`,Ua=`If the page opens with a hero, make it the full height of the first screen (min-h-screen on that one section — never a fixed height, never overflow hidden), add visual elements that give it wow factor, and end it where the next section begins: the rest of the page comes after it, never inside it.`,Wa=(e,t)=>e?.type?e.type!==`public`:!!t?.pageType,Ga=[`Everything below the page heading is yours to design however you like — one clean column of sections using the full width. Never stack panels inside panels, never let sections overlap, and when the content grows tall let the page scroll.`,Ua],Ka=`This page is a screen INSIDE my app, not a page of my website: it opens for somebody who has already signed in, under the heading and the menu the app draws itself, inside the app’s own panel. So it never opens like a landing page — no full-height hero, no headline selling my app to a visitor, no marketing sections, and no page heading, menu, background or wrapper of your own. Begin with the thing the page is FOR, at the top, where somebody who came to use it will reach it without scrolling; anything explaining it goes after that, short. Below that the design is yours: one clean column of sections across the full width, never a panel inside a panel, never sections that overlap, and when it grows tall let it scroll.`,qa=(e,t,n=[])=>{let r=ja(e,t),i=String(t?.tabName||t?.pageName||``).trim(),a=i===`New page`?``:i,o=String(t?.template||``),s=String(t?.form||``).trim(),c=String(t?.brief||``).trim(),l=t?.pageType?`private`:`public`,u=Mn(ka(e,t))||`Page`,d=u.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase(),f=[`My app already has a page${a?` called ${a}`:``} at ${r}. It is already made and it is already in the menu — do not create a page, a web address or a settings file for it, and do not edit any other file.`,`Write one file: ${Aa(e,t)}, with a default export. That file is what the page shows.`,`Then add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts so the app loads your file: import ${u}Content from './${u}Content'; and registerMicrocomponent('${d}', ${u}Content); — registerMicrocomponent is imported there from 'your-ai-workflow-firebase-os'. Never remove another page's lines from that file.`,Va,...Wa(e,t)?[Ka]:Ga,Ja];f.push(...Ui(t));let p=la(t);f.push(...ta(e,t,[c,...p].join(`
|
|
8
|
+
`),p.length>0)),f.push(...p),Ta.includes(o)&&f.push(Da(o));let m=co(t);return m?f.push(...uo(t,l)):s?f.push(...fo(t,s)):io(c)&&f.push(ao(t,l)),f.push(...po(t,m)),f.push(...oo(t,l)),f.push(...Ei(t)),f.push(...Yo(t)),f.push(...ts(e,t)),f.push(...Ia(t)),f.push(`Here is what I would like on it: ${c||`___`}`),f.push(...ms(t,n)),f.join(`
|
|
9
|
+
`)},Ja=`Anything I have not decided below — the section titles, the words on the buttons, the layout, where the pictures and the form go — decide yourself and build it finished; do not stop to ask me.`,Ya=/^\s*(name|page name|address|web address|route|url|heading|title|forms?)\s*(?::|\s[-–—]\s)\s*(.*)$/i,Xa=e=>{let t={name:``,address:``,heading:``,rest:``},n=[];for(let r of String(e||``).split(`
|
|
10
|
+
`)){let e=r.match(Ya),i=e?e[1].toLowerCase():``;if(!e||i===`form`||i===`forms`){n.push(r);continue}let a=e[2].trim();i===`name`||i===`page name`?t.name=a:i===`heading`||i===`title`?t.heading=a:t.address=a}return t.rest=n.join(`
|
|
11
|
+
`).trim(),t},Za={public:{name:`Photos`,describe:`A gallery of my work, newest first, with a short line about me at the top and a Get in touch button at the bottom.`,form:`Ask for their name, email and what they need, at the bottom of the page under a Get in touch button. After they send it, thank them and say I answer within a day. And a second one at the top, Join the newsletter, that asks only for an email.`,payments:`A Book button under each session. After they pay, thank them here and say I will be in touch to set a time.`},user:{name:`My albums`,describe:`A private gallery with albums, where each person sees only their own. Use a camera icon in the menu.`,form:`A new album — its name and a line about it. After it is sent, open the album. And Report a problem — what went wrong, with a screenshot.`,payments:`A Pay button on each plan. After they pay, unlock the videos for them right here.`},internal:{name:`Clients`,describe:`A list of every client — name, what we are doing for them, the next step and its date — that anyone on the team can add to. Use a briefcase icon in the menu.`,form:`Add a client — their name, company and what they need. After it is sent, add them to the list. And Log a call — the client, the date and what was said.`,payments:`Every sale as a row — who, what, when — newest first, with the total this month at the top.`},admin:{name:`Invoices`,describe:`Every invoice — who, how much, paid or not — with totals per month at the top. Use a receipt icon in the menu.`,form:`Add an invoice — the client, the amount and the due date. After it is sent, add it to the list unpaid. And Record a payment — the invoice and the amount received.`,payments:`Every sale as a row — who, what, when — newest first, with the total this month at the top.`}},Qa={visitor:`For new clients to book an intro call. Explain what the session covers first, and say I will confirm by email.`,ask:`What they need help with, their phone number, and whether they have worked with us before.`,team:`Every booking as a row — who, with whom, when — soonest first.`},$a={how:`Every booking made on this page appears there, newest first.`,newPage:`A page for my team with every booking made here — who, when, what for — newest first.`},eo=`Show the albums three to a row, put a search box above them, and take the prices off.`,to=`Ask for a phone number too, and add a second form at the bottom, Join the newsletter, that asks only for an email.`,no=e=>{let t=String(e||``).match(/\b(?:icon\s*(?::|is|of|should be|could be)?\s*(?:a|an|the)?\s*([a-z][a-z-]*)|(?:a|an|the)\s+([a-z][a-z-]*)\s+icon)\b/i),n=(t?.[1]||t?.[2]||``).toLowerCase();return!n||[`in`,`for`,`on`,`that`,`of`,`the`,`menu`].includes(n)?``:Xe(n,1)[0]||``},ro=e=>{let t=String(e||``).match(/^\s*(?:heading|title)\s*(?::|\s[-–—]\s)\s*(.+)$/im);return t?t[1].trim():``},io=e=>/\bforms?\b/i.test(e),ao=(e,t)=>{let n=Vo(e)||`page`;return`If my words below ask for a form, create it as one more file, src/your-ai-workflow-firebase-os/configs/${n}Form.config.ts, the way my app's instructions describe a form, with systemName '${n}' and formType '${t}', and show it on the page with <ContactPopup formId='${n}' /> — never build a form out of your own inputs. If they ask for more than one, each further form is one more file in that same shape, named after the page's id plus one lowercase word for what it is (${n}newsletterForm.config.ts, systemName '${n}newsletter'). If they name a form my app already has, show that one under its own id and do not make another. What each asks is in my words; where it goes and what its button says are yours to decide.`},oo=(e,n,r=String(e?.brief||``))=>{if(!t.Cn(r)||_s(e).schedules.length>0)return[];let i=t.yn().filter(t.Wt);if(!i.length)return[];let a=t.Sn(i);if(rs(e))return[`If my words below ask for bookings to be shown, this page is where my team follows the times people book with ${a}. ${t.Nt}`];let o=String(e?.form||``).trim()||Vo(e)||`page`,s=i.length>1;return[`If my words below ask for booking, people book ${t.Ln(i)} on this page${s?` — whichever my words name, or all of them if I did not say`:``}; how long a booking lasts is set by the schedule, so never state or ask for a length. ${t.St}`,`The question goes in the page's form; if the page has none, create one as src/your-ai-workflow-firebase-os/configs/${o}Form.config.ts, the way my app's instructions describe a form, with systemName '${o}' and formType '${n}', asking their name and their email. Add exactly this question to it, copied as it is${s?`, keeping only the schedules my words name`:``}: ${t.Pn(i.map(e=>e.id))}`,...t.Yn(i)?[t.Jn()]:[],t.vt]},so=e=>String(e?.formWish||``).trim(),co=e=>String(e?.form||``)===`__new__`||!!e?.formIsNew||!String(e?.form||``).trim()&&!!so(e),lo=e=>{let t=_o(e);return!!String(e?.form||``).trim()||co(e)||!!t?.formWish||!!t?.form},uo=(e,t)=>{let n=String(e?.form||``),r=n!==`__new__`&&n||Vo(e)||`page`,i=so(e),a=String(e?.formFields||``).trim(),o=String(e?.formButton||``).trim(),s=String(e?.formSpot||``).trim();if(i)return[`The page needs the forms my words below describe — one, or several. If my words below name a form my app already has, show that one with <ContactPopup formId='…' /> under its own id and do not make another. Otherwise create the first as one more file, src/your-ai-workflow-firebase-os/configs/${r}Form.config.ts, the way my app's instructions describe a form, with systemName '${r}' and formType '${t}', and each further one as one more file in that same shape, named after the page's id plus one lowercase word for what it is (${r}newsletterForm.config.ts, systemName '${r}newsletter'). Show each on the page with <ContactPopup formId='…' /> under its own systemName — never build a form out of your own inputs. Where each goes on the page and what its button says are yours to decide.`,`Here is what the forms should ask, and what happens after: ${i}`];let c=[`The page needs a form of its own. Create it as one more file, src/your-ai-workflow-firebase-os/configs/${r}Form.config.ts, the way my app's instructions describe a form, with systemName '${r}' and formType '${t}'. It should ask for: ${a||`___`}`,`Show that form on the page with <ContactPopup formId='${r}' /> — never build a form out of your own inputs.`];return o&&c.push(`The form opens from a button that says ${o} — make that button part of the page's design, not an afterthought.`),s&&c.push(`Where the form belongs on the page: ${s}`),c},fo=(e,t,n=!1)=>{let r=n?[`The page already shows my form ${zo(t)} with <ContactPopup formId='${t}' /> — keep showing it, and change how it works here as my words say. Never write a form by hand.`]:[`Show my form ${zo(t)} on it with <ContactPopup formId='${t}' /> — never write a form by hand.`],i=so(e),a=String(e?.formButton||``).trim(),o=String(e?.formSpot||``).trim();return i&&r.push(n?`Here is what should change about the form here: ${i}`:`Here is how the form should work on this page: ${i}`),a&&r.push(`The form opens from a button that says ${a} — make that button part of the page's design, not an afterthought.`),o&&r.push(`Where the form belongs on the page: ${o}`),r},po=(e,n)=>{let r=rs(e),i=t.Xt(e,t.bn(),r,t.yn());if(!i.length||r)return i;let a=String(e?.form||``).trim();if(co(e)||n)return i;let o=_o(e)?.formWish?Vo(e)||`page`:``;if(a||o){let e=a||o;return[o&&!a?`The page already has its own form, src/your-ai-workflow-firebase-os/configs/${e}Form.config.ts — add the question to that form where it is defined (if the page has several and my words name one, to that one), keeping its systemName exactly as it is.`:`The page's form is '${e}' — add the question to that form where it is defined, keeping its id exactly '${e}'.`,...i]}let s=t.Dn(e)?.ask.trim()||``,c=`their name (text) and their email (email)`;return[...uo({...e,form:Bo,formFields:String(e?.formFields||``).trim()||(s?`${c}, and ${s}`:c)},e?.pageType?`private`:`public`),...i]},mo={formWish:``,form:``,booking:{schedules:[],party:`each`,ask:``,how:``},bookingLinks:[],bookingLinksNote:``,links:[],emails:[],paymentIds:[],paymentNote:``,roles:[],canDo:{},prefix:``},ho=e=>{let t={};if(!e||typeof e!=`object`)return t;for(let n of Object.keys(e).sort()){let r=String(e[n]??``).trim();r&&(t[n]=r)}return t},go=(e,n)=>{let r=_s(n);return{formWish:so(n),form:String(n?.form||``).trim(),booking:{schedules:r.schedules,party:r.party,ask:r.ask.trim(),how:r.how.trim()},bookingLinks:xi(n),bookingLinksNote:Si(n),links:cr(n).filter(e=>e.pageId).map(e=>({pageId:e.pageId,how:e.how.trim()})),emails:qo(n).map(e=>({...e,what:e.what.trim()})),paymentIds:Qo(e,n).map(e=>e.id),paymentNote:$o(n),roles:n?.pageType?t.ba(n):[],canDo:aa(n),prefix:n?.pageType?t.ma(n):``}},_o=e=>{let n=e?.sent;if(!n||typeof n!=`object`)return null;let r=_s({booking:n.booking});return{formWish:String(n.formWish||``).trim(),form:String(n.form||``).trim(),booking:{schedules:r.schedules,party:r.party,ask:r.ask.trim(),how:r.how.trim()},bookingLinks:xi(n),bookingLinksNote:Si(n),links:Array.isArray(n.links)?n.links.map(e=>({pageId:String(e?.pageId||``),how:String(e?.how||``).trim()})).filter(e=>e.pageId):[],emails:qo({emails:n.emails}).map(e=>({...e,what:e.what.trim()})),paymentIds:Array.isArray(n.paymentIds)?n.paymentIds.map(String):[],paymentNote:String(n.paymentNote||``).trim(),roles:t.ia(n.roles),canDo:ho(n.canDo),prefix:String(n.prefix||``)}},vo=(e,t)=>JSON.stringify(e)===JSON.stringify(t),yo=e=>{let t=String(e?.form||``).trim();return t!==`__new__`&&t||Vo(e)||`page`},bo=e=>(Uo.find(t=>t.id===e)?.label||`that email`).replace(/^./,e=>e.toLowerCase()),xo=(e,n,r,i)=>{let a=go(e,n),o=n?.pageType?`private`:`public`,s=rs(n),c=[],l=!1,u=!1;if(a.form!==i.form||a.formWish&&a.formWish!==i.formWish){l=!0;let e=!!i.form||!!i.formWish;if(a.form||a.formWish)if(co(n))if(e){let e=yo(n);c.push(`The page's own forms already exist as files — the first as src/your-ai-workflow-firebase-os/configs/${e}Form.config.ts with systemName '${e}', any further one named after the page's id plus one lowercase word for what it is. Change them where they are defined, keeping each systemName exactly as it is, and keep showing each on the page with <ContactPopup formId='…' />. A form my words add is one more file in that same shape, with formType '${o}'. Never build a form out of your own inputs.`,`Here is what should change about the forms: ${a.formWish}`)}else c.push(...uo(n,o)),u=!0;else a.form&&c.push(...fo(n,a.form,a.form===i.form));else c.push(`Take the form off this page: stop showing it here, and leave the form itself where it is defined.`)}vo(a.booking,i.booking)||(l=!0,a.booking.schedules.length?c.push(...po(n,u)):c.push(s?`This page no longer follows bookings — take the list of bookings off it.`:`Take booking off this page: remove the 'schedule' question from its form and every trace of the picker. The schedules themselves stay on my Schedule screen.`));let d=a.bookingLinks.filter(e=>!i.bookingLinks.includes(e)),f=i.bookingLinks.filter(e=>!a.bookingLinks.includes(e)),p=a.bookingLinksNote!==i.bookingLinksNote&&a.bookingLinks.length>0;if(d.length||f.length||p){l=!0,d.length?c.push(...Ei(n,bi(),d)):p&&a.bookingLinksNote&&c.push(`Here is where the booking links on this page should sit now and how they should open: ${a.bookingLinksNote}`);for(let e of f)c.push(Di(e))}let m=a.links.filter(e=>!i.links.some(t=>t.pageId===e.pageId&&t.how===e.how)),h=i.links.filter(e=>!a.links.some(t=>t.pageId===e.pageId));if(m.length||h.length){l=!0,m.length&&c.push(...ms(n,r,m.map(e=>e.pageId)));for(let e of h){let t=lr(e.pageId,r);t&&c.push(`This page is no longer linked to the page at ${t.path} — take that connection off this page, and leave that page as it is.`)}}let g=a.emails.filter(e=>!i.emails.some(t=>vo(t,e))),_=i.emails.filter(e=>!a.emails.some(t=>t.kind===e.kind));if(g.length||_.length){l=!0,c.push(...Yo({...n,emails:g}));for(let e of _)c.push(`Stop the email this page sends to ${bo(e.kind)} — remove that call, and nothing else changes.`)}let v=i.roles.some(t.ua),y=a.roles.some(t.ua),b=!vo(a.roles,i.roles)&&(v||y),x=!!i.prefix&&!!a.prefix&&a.prefix!==i.prefix;(b||x)&&(l=!0,y&&b?c.push(...Ui(n)):x&&!(v&&b)?c.push(`Who can open this page has changed, and its records now belong in ${a.prefix} collections rather than ${i.prefix} ones — read and write those from here on. Whatever is already saved in the ${i.prefix} collections stays where it is; do not move it unless I ask.`):c.push(`This page is no longer kept for one of my own roles, so its data goes back to the ordinary ${t.ma(n)} collections — read and write those from here on. Whatever is already saved in the role_ collections stays where it is; do not move it unless I ask.`)),!vo(a.canDo,i.canDo)&&Object.keys(a.canDo).length&&(l=!0,c.push(...la(n,ca)));let S=Qo(e,n).filter(e=>!i.paymentIds.includes(e.id)),C=i.paymentIds.filter(e=>!a.paymentIds.includes(e)),w=a.paymentNote!==i.paymentNote&&a.paymentIds.length>0;if(S.length||C.length||w){l=!0,S.length?c.push(...ts(e,n,S)):w&&a.paymentNote&&c.push(`Here is what should appear for the payments on this page now: ${a.paymentNote}`);for(let e of C){let t=kr().find(t=>t.id===e);c.push(s?`This page no longer follows ${t?Zn(t):`that payment`} — take it off the page.`:`Take ${t?Zn(t):`that payment`} off this page — its Pay button goes, and nothing else changes.`)}}return{changed:l,lines:c}},So=(e,n)=>Jo(e)||cs(e,n)||t.Jt(e,t.bn(),t.yn()),Co=(e,t={title:``,path:``},n=[],r=_o(e)??go(t,e),i=String(e?.pageChange||``),a=Ra(e).length>0)=>So(e,n)||(i.trim()||a||xo(t,e,n,r).changed?``:`Say what you would like changed on this page, and this sentence is ready to copy.`),wo=(e,t,n=[])=>{let r=ja(e,t),i=String(t?.tabName||t?.pageName||``).trim(),a=i===`New page`?``:i,o=String(t?.pageChange||``).trim(),s=t?.pageType?`private`:`public`,c=[`My app already has a page${a?` called ${a}`:``} at ${r}, and the file it shows already exists: ${Aa(e,t)}.`,`Change that one file. Do not create a page, a web address, a settings file or a second content file, do not add or remove anything in registry.ts, and do not edit any other file — except the page's own form, where it is defined, when the change is about the form, and except what this request asks for by name below.`,Ha,...Wa(e,t)?[Ka]:[Ua],`Keep everything on the page that I have not asked you to change.`],l=Da(String(t?.template||``));l&&c.push(l);let u=_o(t)??go(e,t),d=xo(e,t,n,u).lines;c.push(...d),!lo(t)&&io(o)&&c.push(ao(t,s));let f=!vo(aa(t),u.canDo)&&Object.keys(aa(t)).length>0;return c.push(...ta(e,t,[o,...f?la(t):[]].join(`
|
|
12
|
+
`),f)),c.push(...oo(t,s,o)),c.push(...Ra(t)),(o||!d.length)&&c.push(`Here is what I would like changed: ${o||`___`}`),c.join(`
|
|
13
|
+
`)},To={home:{title:`Change the home page`,ask:`What would you like on the home page?`,example:`A big heading that says Bright Studio, a photo of the shop under it, and a Get in touch button.`,changeAsk:`What would you like changed on the home page?`,changeExample:`Make the heading bigger, and put the Get in touch button under the photo.`,lead:[`My app already has a home page, and it is one file: src/your-ai-workflow-firebase-os/Home.tsx. Change that one file — do not create a page, a web address, a settings file or a HomeContent.tsx, and do not edit any other file except what this request asks for by name below.`,`Keep its named export exactly as it is: export function Home. Making it a default export breaks my site.`,Ha,Ua,`Keep every heading at the size it already has and keep the space at the top of the page as it is — a bigger title or moved spacing is how this page stops matching the rest of my app.`,`Keep everything on the page that I have not asked you to change.`]},contact:{title:`Change the contact page`,ask:`What would you like on the contact page?`,example:`A line saying we answer within a day, our opening hours, and the form under them.`,changeAsk:`What would you like changed on the contact page?`,changeExample:`Add a map under the opening hours, and say we are closed on Sundays.`,lead:[`My app already has a contact page at /contact and a contact form. Do not create a page, do not create a form, and do not change the questions the form asks unless this request says so by name below.`,`Change what the page shows by writing one file: src/your-ai-workflow-firebase-os/microcomponents/ContactContent.tsx, with a default export. Then add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import ContactContent from './ContactContent'; and registerMicrocomponent('contact', ContactContent); — never remove another page's lines from that file.`,`Show my form with <ContactPopup formId='contact' /> — add isInline to build it into the page instead of opening it as a pop-up. Never build a form out of your own inputs.`,Ha,`Keep everything on the page that I have not asked you to change.`]},dashboard:{title:`Change the dashboard`,ask:`What would you like on the dashboard?`,example:`Three boxes across the top: bookings today, bookings this week, and unread messages.`,changeAsk:`What would you like changed on the dashboard?`,changeExample:`Add a fourth box for sales this month, and list the latest five messages under the boxes.`,lead:[`My app already has a dashboard at /dashboard — the screen a signed-in person lands on. Do not create a page, a web address or a settings file for it, do not touch src/App.tsx, and do not edit any other file except what this request asks for by name below.`,`Fill it by writing one file: src/your-ai-workflow-firebase-os/microcomponents/DashboardContent.tsx, with a default export. Then add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import DashboardContent from './DashboardContent'; and registerMicrocomponent('dashboard', DashboardContent); — never remove another page's lines from that file.`,`It draws inside the dashboard’s own panel, under the welcome heading and the menu, so do not write a page heading, a menu or a page wrapper of your own.`,Ha]},support:{title:`Change the support page`,ask:`What would you like on the support page?`,example:`A short list of the questions we get asked most, above the form.`,changeAsk:`What would you like changed on the support page?`,changeExample:`Add a question about refunds to the list, and move the form above it.`,lead:[`My app already has a support page at /support and a support form. Do not create a page, do not create a form, and do not change the questions the form asks unless this request says so by name below.`,`Change what the page shows by writing one file: src/your-ai-workflow-firebase-os/microcomponents/SupportContent.tsx, with a default export. Then add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import SupportContent from './SupportContent'; and registerMicrocomponent('support', SupportContent); — never remove another page's lines from that file.`,`Show my form with <ContactPopup formId='support' /> — add isInline to build it into the page instead of opening it as a pop-up. Never build a form out of your own inputs.`,Ha,`Keep everything on the page that I have not asked you to change.`]}},Eo=(e,t)=>{let n=Li.find(t=>t.id===e)?.type||`public`;return{...t||{},contentKey:e,...n===`public`?{}:{pageType:n},...e===`contact`||e===`support`?{form:e}:{}}},Do=e=>{let t=Li.find(t=>t.id===e);return{id:e,title:t?.title||e,path:t?.path||`/${e}`}},Oo=(e,t,n=[])=>{let r=To[e];if(!r)return``;let i=Do(e),a=Eo(e,t),o=String(t?.pageWish||``).trim(),s=a.pageType?`private`:`public`,c=_o(a),l=xo(i,a,n,c??mo).lines;return!lo(a)&&io(o)&&l.push(ao(a,s)),l.push(...oo(a,s,o)),l.push(...za(a)),(o||!l.length)&&l.push(`Here is what I would like ${c?`changed`:`on the page`}: ${o||`___`}`),[...r.lead,...l].join(`
|
|
14
|
+
`)},ko=(e,t,n=[])=>{let r=Eo(e,t);return Co(r,Do(e),n,_o(r)??mo,String(t?.pageWish||``),za(r).length>0)},Ao=(e,t)=>{let n=e=>{let{_uiKey:t,pageType:n,route:r,contentKey:i,built:a,imagesSent:o,sent:s,...c}=e||{};return c},r=n(e),i=n(t),a=new Set([...Object.keys(r),...Object.keys(i)]),o=(e,t)=>e&&typeof e==`object`?JSON.stringify(e)===JSON.stringify(t):(e??``)===(t??``);for(let e of a)if(!o(r[e],i[e]))return!0;return!1},jo=(e,t)=>{let n=ya(),r=n[e.id]||(t?.contentKey?n[String(t.contentKey)]:void 0)||Object.entries(n).find(([t,n])=>{let r=n.config||{},i=r.route?r.route.startsWith(`/`)?r.route:`/`+r.route:`/`+t;return!!e.path&&i===e.path})?.[1];return r?r.config||{}:null},Mo=(e,n)=>{let{_uiKey:r,...i}=e||{};return{...i,...t.ra(n)}},No=`w-6 h-5 rounded-md flex items-center justify-center text-foreground/35 hover:text-foreground hover:bg-foreground/[0.07] transition-colors cursor-pointer`,Po=`max-sm:hidden sm:inline-flex items-center gap-1.5 text-[11px] font-semibold text-foreground/45 border border-[var(--panel-border)] bg-foreground/[0.02] px-2 py-[3px] rounded-full`,Fo={draft:`text-foreground/55 border-[var(--panel-border)] bg-foreground/[0.03]`,live:`text-emerald-500 border-emerald-500/25 bg-emerald-500/[0.07]`,hidden:`text-foreground/45 border-[var(--panel-border)]/70 bg-transparent`},Io={draft:`bg-foreground/30`,live:`bg-emerald-500 shadow-[0_0_5px] shadow-emerald-500/60`,hidden:`bg-foreground/25`};function Lo({status:e}){return(0,i.jsxs)(`span`,{title:pa[e],className:`inline-flex items-center gap-1.5 text-[11px] font-semibold px-2.5 py-[3px] rounded-full border ${Fo[e]}`,children:[(0,i.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full shrink-0 ${Io[e]}`}),fa[e]]})}var Ro=e=>{let t=typeof window<`u`?window.location.host:``;return t?`${t}${e}`:e},zo=e=>e.replace(/[_-]+/g,` `).replace(/^./,e=>e.toUpperCase()),Bo=`__new__`,Vo=e=>String(e?.contentKey||``).toLowerCase().replace(/-+/g,`_`),Ho=e=>co(e)&&!so(e)&&!String(e?.formFields||``).trim(),Uo=[{id:`notify`,label:`Let me know when something happens here`,ask:`What should I be told about?`,hint:`In your own words — you get an email each time it happens.`,placeholder:`Every new booking, with the name and the time they picked`,look:`notification`},{id:`confirm`,label:`Send the person a confirmation`,ask:`What should the confirmation say?`,hint:`Sent to whoever wrote in or booked, right after. It only reaches people who are signed in.`,placeholder:`Thanks, your booking is in — I will confirm the time within a day.`,look:`text`},{id:`send`,label:`Send emails from my account`,ask:`What should be sent, and to whom?`,hint:`Your team writes the email on this page and it goes out from your address — to a customer, a client, anyone.`,placeholder:`A message to a customer, picked from the list of people who booked, written on the spot`,look:`text`,team:!0}],Wo=e=>Uo.filter(t=>!t.team||or(e)),Go=[{value:`text`,label:`Simple text`},{value:`notification`,label:`Notification`}],Ko=e=>e.look===`text`||e.look===`notification`?e.look:Uo.find(t=>t.id===e.kind)?.look||`text`,qo=e=>{let t=e?.emails;if(!Array.isArray(t))return[];let n={owner:`notify`,confirm:`confirm`};return t.map(e=>typeof e==`string`?{kind:n[e]||e,what:``}:{kind:String(e?.kind||``),what:String(e?.what||``),...e?.look===`text`||e?.look===`notification`?{look:e.look}:{}}).filter(e=>Uo.some(t=>t.id===e.kind))},Jo=e=>{if(!Ni())return``;for(let t of qo(e))if(!t.what.trim())return`Say what the email should be about, and this sentence is ready to copy.`;return``},Yo=e=>{if(!Ni())return[];let t=rs(e),n=[];for(let r of qo(e)){let e=r.what.trim();if(!e)continue;let i=Ko(r)===`notification`;r.kind===`notify`?n.push(i?`Email me when something happens on this page, with the app's own emailOwner('heads_up', { title, summary, details }) right after it happens — title says what happened in a few words, summary one line under it, details an object of the facts worth seeing ({ Name: name, Time: slot } and the like). It arrives as a notification card in my app's own look. Never write email code of your own. Here is what I want to hear about: ${e}`:`Email me when something happens on this page, with the app's own emailOwner('heads_up', { title, summary, look: 'text' }) right after it happens — title says what happened in a few words, summary the details in plain sentences. It arrives as a simple text email in my app's own look. Never write email code of your own. Here is what I want to hear about: ${e}`):r.kind===`confirm`?n.push(i?`When a SIGNED-IN person sends something on this page, email them a confirmation with the app's own emailPerson('submission_received', collection, docId, { note, look: 'notification', details }) right after it saves, putting the words below in note and what they sent in details as an object ({ Date: date, Guests: guests } and the like). It arrives as a notification card in my app's own look. Skip it silently for someone who is not signed in — their saved record is not theirs to read. Here is what the confirmation should say: ${e}`:`When a SIGNED-IN person sends something on this page, email them a confirmation with the app's own emailPerson('submission_received', collection, docId, { note }) right after it saves, putting the words below in note. It arrives as a simple text email in my app's own look. Skip it silently for someone who is not signed in — their saved record is not theirs to read. Here is what the confirmation should say: ${e}`):r.kind===`send`&&t&&n.push(i?`This page lets my team send an email to anyone from the app. Build the address, subject and message fields from the app's own pieces and send with the app's own emailAnyone(to, subject, message, { look: 'notification', details }) — details an object of the facts the email is about ({ Order: order, Date: date } and the like), from fields on this page; it resolves to null when sent, or to a message to show; it only works for a signed-in team member or admin, which is who this page is for. It arrives as a notification card in my app's own look: the subject as its headline, the message under it, the details in a box. Never write email code of your own. Here is what should be sent, and to whom: ${e}`:`This page lets my team send an email to anyone from the app. Build the address, subject and message fields from the app's own pieces and send with the app's own emailAnyone(to, subject, message) — it resolves to null when sent, or to a message to show; it only works for a signed-in team member or admin, which is who this page is for. It arrives as a simple text email in my app's own look, so send the words as typed. Never write email code of your own. Here is what should be sent, and to whom: ${e}`)}return n},Xo=(e=kr())=>e.filter(e=>Yn(e)),Zo=(e,t)=>({id:String(e.id||t?.contentKey||``),title:e.title,path:e.path,config:t}),Qo=(e,t,n=kr())=>{let r=Zo(e,t);return r.id?Xo(n).filter(e=>pr(e,r)):[]},$o=e=>String(e?.paymentNote||``).trim(),es=e=>{let t=e.map(Zn);return t.length<=1?t.join(``):`${t.slice(0,-1).join(`, `)} and ${t[t.length-1]}`},ts=(e,t,n)=>{if(!Ii())return[];let r=n??Qo(e,t);if(!r.length)return[];let i=[];if(rs(t))i.push(`This page is where my team follows what ${es(r)} sold. ${xr}`);else{i.push(`This page sells ${es(r)}. ${tr}`);for(let n of r)i.push(...ar(n,ja(e,t)))}let a=$o(t);return a&&i.push(`Here is what should appear for the payments on this page: ${a}`),i},ns=(e,t=``)=>{let n=e.config,r=[],i=String(e.brief??n?.brief??``).trim();i&&r.push(`The page at ${e.path} is for: ${i}`);let a=String(t||``).trim(),o=a?`Here is what I would like on the page at ${e.path}: ${a}`:``,s=()=>o?[...r,o]:r;if(e.id===`home`)return r.push(`The home page is one file: src/your-ai-workflow-firebase-os/Home.tsx — put what I sell there by changing that one file. Keep its named export exactly as it is: export function Home. Never create a HomeContent.tsx, and do not edit any other file for it.`),s();if(e.id===`dashboard`)return r.push(`The dashboard's content is one file: src/your-ai-workflow-firebase-os/microcomponents/DashboardContent.tsx, with a default export. If it does not exist yet, write it and add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import DashboardContent from './DashboardContent'; and registerMicrocomponent('dashboard', DashboardContent); — never remove another page's lines from that file. It draws inside the dashboard's own panel, under the welcome heading and the menu, so do not write a page heading, a menu or a page wrapper of your own.`),s();if(!n)return s();let c={title:e.title,path:e.path},l=Mn(ka(c,n))||`Page`,u=l.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();r.push(`If it is empty, build it by writing one file: ${Aa(c,n)}, with a default export, then add two lines to src/your-ai-workflow-firebase-os/microcomponents/registry.ts: import ${l}Content from './${l}Content'; and registerMicrocomponent('${u}', ${l}Content); — registerMicrocomponent is imported there from 'your-ai-workflow-firebase-os', and never remove another page's lines from that file. If it is already built, that file exists — change it, and leave registry.ts as it is.`);let d=String(n.template||``);Ta.includes(d)&&r.push(Da(d));let f=String(n.form||``).trim(),p=co(n);return p?(so(n)||String(n.formFields||``).trim())&&r.push(...uo(n,n.pageType?`private`:`public`)):f&&r.push(...fo(n,f)),r.push(Ja),r.push(...Yo(n)),r.push(...Ia(n)),r.push(...po(n,p)),r.push(...Ei(n)),s()},rs=e=>or(t.pa(e?.pageType)),is=e=>lo(e),as=(e,t)=>`On ${e}, do this exactly the way my app's instructions describe: while an admin has the page open, mirror each entry once into that page's own collection, keeping the source id on the copy — never read user_submissions or user_requests on a screen a non-admin can open. Mirror only the entries THIS page's form sent: my Inbox holds every form in my app, so skip any entry whose formId does not start with '${t}'. A time somebody booked is never in there at all — meetings come from useBookings() and nowhere else.`,os=(e,t)=>e.pageId?lr(e.pageId,t):void 0,ss=(e,t)=>e.pageId?os(e,t)?e.how.trim()?``:`Say how the two pages connect, and this sentence is ready to copy.`:`The page this one linked to was deleted. Pick another, and this sentence is ready to copy.`:`Make or pick the page this one links to — or unlink it — and this sentence is ready to copy.`,cs=(e,t)=>{for(let n of cr(e)){let e=ss(n,t);if(e)return e}return``},ls=e=>{switch(e){case`admin`:return{kind:`admin-only`,who:`only admins`};case`internal`:return{kind:`internal`,who:`only my team and admins`};case`user`:return{kind:`signed-in`,who:`only people who are signed in`};default:return{kind:`public`,who:`anyone`}}},us={public:0,user:1,internal:2,admin:3},ds=e=>e?.pageType?t.pa(e.pageType):`public`,fs=e=>({user:`user_`,internal:`mem_`,admin:`admin_`})[e]||`pub_`,ps=(e,t)=>{let n=ds(e),r=t.audience||`public`;if(us[n]===us[r])return[`They connect through the app's own database and nothing else: what this page saves is what the page at ${t.path} reads, live, from the same place. Never write a backend, an export or a copy of the data for it.`];let i=us[n]>us[r]?{path:`this page`,audience:n}:{path:`the page at ${t.path}`,audience:r},a=i.audience===n?{path:`the page at ${t.path}`,audience:r}:{path:`this page`,audience:n},o=fs(i.audience);return[`The two pages are for different people, so they cannot share one collection: a ${ls(a.audience).kind} page cannot read ${o} collections — the security rules answer with a permission error. Keep a public copy instead: ${i.path} saves to its own ${o} collection AND writes the same change to a pub_ copy on every add, edit and delete, under the same document id, and while it is open copies across any entry that has no copy yet; ${a.path} reads ONLY the pub_ copy. Put in the copy only what ${ls(a.audience).who} should see — never a person's name, email or message. Never name a mem_, admin_ or user_ collection in the code of ${a.path}, and never write a backend or an export for it.`]};function ms(e,n,r){let i=[],a=is(e);for(let o of cr(e)){if(r&&!r.includes(o.pageId))continue;let s=os(o,n),c=o.how.trim();if(!s||!c)continue;let l=s.audience===`admin`,u=or(s.audience),d=ls(s.audience);i.push(`This page is linked to the ${d.kind} page at ${s.path}, which ${d.who} can open. Build both pages of the link in this one request — this page and the one at ${s.path}. That page's web address and menu entry already exist — do not create a web address or a settings file for it, and do not change who can open it.`),i.push(`Here is how the two pages are linked: ${c}`),i.push(...ps(e,s));let f=t.xn(s.path,s.config,t.bn(),rs(e),t.yn());f&&i.push(f),a&&u&&!l&&i.push(`Entries from the form on this page land in the Inbox collections, which only admins may read. ${as(s.path,yo(e))}`),i.push(`For the page at ${s.path}:`),i.push(...ns(s))}return i.length&&i.push(`Do not touch any page this request does not name.`),i}var hs=(e,t,n,r)=>{let i=new Set([e.id]),a=String(t?.contentKey||``).trim();a&&i.add(a);let o=[];for(let t of n)t.id!==e.id&&cr(r[t.id]).some(e=>e.pageId&&i.has(e.pageId))&&o.push(t.title);return o};function gs({images:e,notes:n,onChange:r,onNotes:a,onBlur:o}){let s=e.filter(e=>e.url),c=e=>r(s.filter((t,n)=>n!==e));return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[s.length>0&&(0,i.jsx)(`div`,{className:`flex flex-wrap gap-2.5`,"aria-label":`Your pictures`,children:s.map((e,n)=>(0,i.jsxs)(`div`,{className:`relative w-20 h-20 rounded-xl overflow-hidden border border-[var(--panel-border)] bg-[var(--panel-bg)]`,children:[(0,i.jsx)(`img`,{src:e.url,alt:`Picture ${n+1}`,className:`w-full h-full object-cover`}),(0,i.jsx)(`span`,{"aria-hidden":!0,className:`absolute top-1 left-1 min-w-[20px] h-5 px-1.5 rounded-full bg-background/90 text-[11px] font-bold text-foreground flex items-center justify-center`,children:n+1}),(0,i.jsx)(`button`,{type:`button`,"aria-label":`Remove picture ${n+1}`,title:`Remove this picture`,onClick:()=>c(n),className:`absolute top-1 right-1 w-5 h-5 rounded-full bg-background/90 text-foreground/60 hover:text-red-500 flex items-center justify-center cursor-pointer transition-colors`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})})]},`${e.url}-${n}`))}),(0,i.jsx)(ct,{label:s.length?`Add another picture`:`A picture for this page`,hint:s.length?void 0:`Optional — every picture you add gets a number, so you can say below where each one goes.`,value:``,onChange:e=>{e&&r([...s,{url:e,where:``}])},tips:s.length?void 0:lt}),s.length>0&&(0,i.jsx)(t.dt,{label:`How should the pictures be used?`,hint:`Optional — say it by number. Anything you leave out, your assistant decides.`,value:n,onChange:a,onBlur:o,placeholder:`1 across the top behind the heading, 2 and 3 side by side under it`})]})}var _s=e=>{let n=e?.booking&&typeof e.booking==`object`?e.booking:{};return{schedules:t.fn(t.Gn(n),t.bn(),t.yn()),party:t.Wn(n),ask:String(n.ask||``),how:String(n.how||``)}};function vs({title:e,hint:t,action:n,children:r}){return(0,i.jsxs)(`section`,{className:`flex flex-col gap-3 pt-4 border-t border-[var(--panel-border)]/50`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 ml-1`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0`,children:[(0,i.jsx)(`h4`,{className:`text-[13px] font-bold text-foreground/85 tracking-tight`,children:e}),t&&(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug max-sm:hidden`,children:t})]}),n]}),r]})}function ys({booking:e,team:n,schedules:r,onChange:a,onAsk:o,onHow:s,onBlur:c}){let l=e.schedules.length>0,u=t.Zt(e,r,t.yn()),d=!n&&t.Yn(u),f={each:`A visitor picks one of ${t.Sn(u)}, then one of that person’s own free times.`,all:`Only the times ${t.Sn(u)} are ALL free are offered, and one booking goes in every one of their calendars.`,choose:`The page offers both — the visitor chooses whether it is with one of ${t.Sn(u)} or all of them, then picks a time.`};return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(Ai,{mode:`hours`,schedules:r,selected:e.schedules,onPick:n=>a({...e,schedules:t.An(e.schedules,n,r)}),placeholder:n?`Pick whose hours your team follows here`:`Pick whose hours this page is built on`}),d&&(0,i.jsx)(t.ct,{label:`If people book here, who is it with?`,hint:f[e.party],value:e.party,onChange:t=>a({...e,party:t||`each`}),options:t.yt,allowEmpty:!1}),l&&(0,i.jsx)(t.dt,{label:n?`What should your team see here?`:`How will these hours be used on this page?`,hint:n?`Every booking, who, when — or a rota, a shift board, who is in on Thursday.`:`A rota, who is free on Thursday, a page people book time on — anything built on those hours. The times come from the week itself and change with it, so say who it is for, what they read first, and what happens after.`,value:e.how,onChange:s,onBlur:c,placeholder:n?Qa.team:Qa.visitor}),l&&!n&&(0,i.jsx)(t.dt,{label:`If people book time here, what should they be asked?`,hint:`Optional — leave it empty and nothing is booked on this page unless your words above ask for it. In your own words, not fields: their name and their email are always taken, and a visitor already signed in is never asked for them.`,value:e.ask,onChange:o,onBlur:c,placeholder:Qa.ask})]})}function bs({targets:e,attached:n,note:r,onToggle:a,onNote:o,onBlur:s}){return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60 px-2 py-1.5`,role:`group`,"aria-label":`Booking links on this page`,children:e.map(e=>{let r=n.includes(e.path);return(0,i.jsxs)(`button`,{type:`button`,role:`checkbox`,"aria-checked":r,"aria-label":`${e.title} — ${e.path}`,onClick:()=>a(e.path),className:`w-full flex items-center gap-2.5 px-2 py-2 text-left cursor-pointer rounded-xl hover:bg-foreground/[0.04] transition-colors`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${r?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:r&&(0,i.jsx)(t.Fi,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,i.jsxs)(`span`,{className:`flex-1 min-w-0 flex flex-col`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate`,children:e.title}),(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 truncate`,children:e.path})]})]},e.path)})}),n.length>0&&(0,i.jsx)(t.dt,{label:`Where should it sit on the page, and how should it open?`,hint:`Optional — the booking page itself is already made; this is only what leads to it here.`,value:r,onChange:o,onBlur:s,placeholder:`A button under the opening hours that says Book time with me, and it opens in a pop-up over the page.`})]})}function xs({products:e,ticked:n,team:r,note:a,onToggle:o,onNote:s,onBlur:l}){return e.length?(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60 px-2 py-1.5`,role:`group`,"aria-label":`Payments on this page`,children:e.map(e=>{let r=n.includes(e.id);return(0,i.jsxs)(`button`,{type:`button`,role:`checkbox`,"aria-checked":r,"aria-label":Qn(e),onClick:()=>o(e),className:`w-full flex items-center gap-2.5 px-2 py-2 text-left cursor-pointer rounded-xl hover:bg-foreground/[0.04] transition-colors`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${r?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:r&&(0,i.jsx)(t.Fi,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate min-w-0`,children:Qn(e)})]},e.id)})}),n.length>0&&(0,i.jsx)(t.dt,{label:r?`What should your team see here?`:`How will paying work here?`,hint:r?`Every sale, who, what, when — laid out the way your team reads it.`:`The prices and the buttons come from the Payments screen — say where the button sits, what surrounds it, and what happens after they pay.`,value:a,onChange:s,onBlur:l,placeholder:r?Za.internal.payments:Za.public.payments})]}):(0,i.jsxs)(`p`,{className:t.$,children:[`Nothing to sell yet — describe what you sell on the`,` `,(0,i.jsx)(c.Link,{to:`/payments`,className:`text-accent font-bold hover:underline`,children:`Payments screen`}),` first.`]})}function Ss({emails:e,audience:n,onChange:a,onBlur:o}){let s=Wo(n),c=s.map(e=>({value:e.id,label:e.label})),[l,u]=(0,r.useState)(!1),d=e.length?l?[...e,{kind:``,what:``}]:e:[{kind:``,what:``}],f=(e,t)=>{u(!1),a(d.map((n,r)=>r===e?{kind:t,what:n.what}:n).filter(e=>!!e.kind),!0)},p=(e,t)=>a(d.map((n,r)=>r===e?{...n,what:t}:n).filter(e=>!!e.kind),!1),m=(e,t)=>a(d.map((n,r)=>r===e?{...n,look:t}:n).filter(e=>!!e.kind),!0),h=!l&&e.length>0&&e.length<s.length;return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[d.map((e,n)=>{let r=s.find(t=>t.id===e.kind),a=c.filter(t=>t.value===e.kind||!d.some(e=>e.kind===t.value));return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5`,children:[(0,i.jsx)(t.ct,{label:n===0?`Would you like to add emails to this page?`:`Another email`,value:e.kind,onChange:e=>f(n,e),options:a,placeholder:`No`}),r&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.dt,{label:r.ask,hint:r.hint,value:e.what,onChange:e=>p(n,e),onBlur:o,placeholder:r.placeholder}),(0,i.jsx)(t.ct,{label:`How should it look?`,hint:`Simple text reads like a note: a greeting, your words, a sign-off. Notification is a card: a headline, a line under it and the facts in a box. Both carry your logo, name and colours from the Theme screen.`,value:Ko(e),onChange:e=>m(n,e),options:Go,allowEmpty:!1})]})]},n)}),h&&(0,i.jsx)(`div`,{className:`flex`,children:(0,i.jsx)(t.Q,{icon:t.Hr,onClick:()=>u(!0),children:`Another email`})})]})}var Cs=`__new_linked_page__`,ws=t.ta.map(e=>({value:e,label:Bi[e]})),Ts=e=>ma(e.address)||ma(e.name),Es=(e,t,n)=>{let r=Ts(e);return!(!e.name.trim()||!r||n(r)||!t.trim()||e.form===`__new__`&&!e.formFields.trim())},Ds=(e,t=``)=>{let n=ws.some(t=>t.value===e.type)?e.type:`internal`;return{name:e.name.trim(),address:Ts(e),type:n,about:e.about.trim()||t.trim(),iconName:e.iconName||(n===`public`?``:no(e.about)||Oa(e.name)),template:e.template,form:e.form,formFields:e.formFields.trim(),formButton:e.formButton.trim(),formSpot:e.formSpot.trim(),formWish:e.formWish.trim(),images:e.images,imageNotes:e.imageNotes.trim(),booking:e.booking}};function Os({draft:e,taken:n,schedules:a,onEdit:o,onSave:s,onBlur:c}){let[l,u]=(0,r.useState)(``),d=ws.some(t=>t.value===e.type)?e.type:`internal`,f=or(d),p=Za[d],m=Ts(e),h=()=>e.name.trim()?!m||n(m)?(u(m?`${Ur(m)} Pick a different name.`:`Use a name with a letter or a number in it.`),!1):(u(``),!0):(u(`Give the new page a name, for example Bookings`),!1);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-4`,children:[(0,i.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4`,children:[(0,i.jsx)(t.ft,{label:`Name of the new page`,hint:m?`It will live at /${m}.`:`What it is called in the menu.`,value:e.name,onChange:e=>{o({name:e}),l&&u(``)},onBlur:()=>{h(),c()},error:l,placeholder:`Bookings`}),(0,i.jsx)(t.ct,{label:`Who can open it`,hint:`Anyone is your public website. Members is everybody who registers; Your team is everyone you have marked internal, plus admins.`,value:d,onChange:e=>s({type:e}),options:ws,allowEmpty:!1})]}),(0,i.jsx)(t.dt,{label:`What is on the new page?`,hint:`In your own words. Whatever you skip, your assistant decides.`,value:e.about,onChange:e=>o({about:e}),onBlur:c,placeholder:$a.newPage}),(0,i.jsx)(t.Z,{label:`Its pictures`,children:(0,i.jsx)(gs,{images:e.images,notes:e.imageNotes,onChange:e=>s({images:e}),onNotes:e=>o({imageNotes:e}),onBlur:c})}),(0,i.jsx)(t.dt,{label:`Its forms`,hint:`Optional — as many as you like: what each asks, where it sits and what happens after. Or name forms you already have.`,value:e.formWish,onChange:e=>o({formWish:e}),onBlur:c,placeholder:p.form}),(0,i.jsx)(t.Z,{label:`Schedules on it`,hint:f?`Optional — whose hours the team follows there.`:`Optional — whose working hours it is built on, one person each.`,children:(0,i.jsx)(ys,{booking:e.booking,team:f,schedules:a,onChange:e=>s({booking:e}),onAsk:t=>o({booking:{...e.booking,ask:t}}),onHow:t=>o({booking:{...e.booking,how:t}}),onBlur:c})})]})}function ks({link:e,links:n,index:a,targets:o,self:s,schedules:c,onPatch:l,onBlur:u,onRemove:d,taken:f,onCreatePage:p}){let[m,h]=(0,r.useState)(!1),[g,_]=(0,r.useState)(``),v=os(e,o),y=o.filter(e=>!ur(s.id,e)&&!(s.contentKey&&ur(s.contentKey,e))&&(e.id===v?.id||!n.some((t,n)=>n!==a&&os(t,o)?.id===e.id))),b=e.pageId?v?.id||e.pageId:e.draft?Cs:``,x=e=>{l(e===`__new_linked_page__`?{pageId:``,draft:sr()}:{pageId:e,draft:void 0},!0)},S=async()=>{if(e.draft){h(!0),_(``);try{l({pageId:await p(Ds(e.draft,e.how)),draft:void 0},!0)}catch(e){console.error(`Failed to create the linked page:`,e),_(`The page could not be created. Check its web address and try again.`)}h(!1)}},C=!!e.draft&&Es(e.draft,e.how,f),w=v?.title||e.draft&&e.draft.name.trim()||(e.draft?`A new page`:`A linked page`);return(0,i.jsxs)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 px-4 pt-3 pb-1`,children:[(0,i.jsx)(`span`,{className:`flex-1 min-w-0 text-[13px] font-semibold text-foreground/75 truncate`,children:w}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Unlink ${w}`,onClick:d,children:`Unlink`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 px-4 pb-4 pt-2`,children:[(0,i.jsx)(t.ct,{label:`Which page is it linked to?`,hint:b?void 0:`One of your pages — or a new one, made right here.`,value:b,onChange:x,options:[{value:Cs,label:`+ A new page, made right here`},...y.map(e=>({value:e.id,label:`${e.title} — ${e.path}`}))],placeholder:`Pick a page`}),!!e.pageId&&!v&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500`,children:`The page this one linked to was deleted. Pick another, or unlink it.`}),e.draft&&(0,i.jsx)(Os,{draft:e.draft,taken:f,schedules:c,onEdit:t=>l({draft:{...e.draft,...t}},!1),onSave:t=>l({draft:{...e.draft,...t}},!0),onBlur:u}),(!!v||!!e.draft)&&(0,i.jsx)(t.dt,{label:`How are the two pages linked?`,hint:`In your own words — what made here should show up there, and what happens after. It goes into the sentence below.`,value:e.how,onChange:e=>l({how:e},!1),onBlur:u,placeholder:$a.how}),!!g&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500`,children:g}),e.draft&&(0,i.jsx)(`div`,{className:`flex pt-1`,children:(0,i.jsx)(t.Q,{icon:t.Hr,busy:m,disabled:!C,onClick:S,children:`Create and link it`})})]})]})}function As({links:e,targets:n,self:r,schedules:a,onChange:o,onBlur:s,taken:c,onCreatePage:l}){let u=(t,n,r)=>o(e.map((e,r)=>{if(r!==t)return e;let i={...e,...n};return i.draft||delete i.draft,i}),r),d=t=>o(e.filter((e,n)=>n!==t),!0),f=()=>o([...e,{pageId:``,how:``}],!0),p=e.every(e=>!!os(e,n));return e.length?(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.map((t,o)=>(0,i.jsx)(ks,{link:t,links:e,index:o,targets:n,self:r,schedules:a,onPatch:(e,t)=>u(o,e,t),onBlur:s,onRemove:()=>d(o),taken:c,onCreatePage:l},o)),p&&(0,i.jsx)(`div`,{className:`flex`,children:(0,i.jsx)(t.Q,{icon:t.Hr,onClick:f,children:`Link another page`})})]}):(0,i.jsx)(`div`,{className:`flex`,children:(0,i.jsx)(t.Q,{icon:t.Hr,onClick:f,title:`Another of your pages that shows what happens here — usually one only your team can open`,children:`Link a page`})})}var js=[`pageType`,`roles`,`alsoTeam`],Ms=e=>Object.fromEntries(js.filter(t=>e&&t in e).map(t=>[t,e[t]]));function Ns({page:e,config:n,saving:a,onSave:o,addressTaken:s,actions:c,footer:l,isNew:u,quick:d,system:f,linkTargets:p,onCreateLinkedPage:m,products:h,onTogglePayment:g,customRoles:_,onCreateRole:v}){let y=e.type===`public`,b=or(e.type),x=y?`pageName`:`tabName`,S=y?`pageTitle`:`tabTitle`,C=Za[e.type],[w,T]=(0,r.useState)(()=>({...n||{}})),[E,D]=(0,r.useState)(``),[O,k]=(0,r.useState)(``),A=ma(String(w.route??``).replace(/^\/+/,``)),[j,M]=(0,r.useState)(A),N=(e,t)=>T(n=>({...n,[e]:t})),P=t=>{let r={...n||{},...w,...Ms(n),...t};!d&&!f&&!r.sent&&(r.sent=go(e,n||{})),delete r._uiKey,T(e=>({...e,...t,...r.sent&&!e.sent?{sent:r.sent}:{}})),o(r)},F=e=>{(n||{})[e]!==w[e]&&P({[e]:w[e]})},I=String(w[x]??``).trim(),L=ma(j)||ma(I),R=()=>{if(!I){D(`Give the page a name — ${C.name}`);return}if(!L){D(`Use a name with a letter or a number in it.`);return}let t=A||L;if(!A&&s(e.id,t)){D(`${Ur(t)} Pick a different name or address.`);return}D(``);let r={[x]:I},i=String(w[S]??``).trim();(!i||i===String(n?.[x]??``).trim())&&(r[S]=I),!y&&!String(w.iconName??``).trim()&&(r.iconName=no(String(w.brief??``))||Oa(I)),A||(r.route=`/`+t,M(t)),Object.keys(r).some(e=>(n||{})[e]!==r[e])?P(r):T(e=>({...e,...r}))},z=()=>{let t=ma(j);if(!j.trim()){M(A),k(``);return}if(!t){k(`Use an address with a letter or a number in it.`);return}if(M(t),t===A){k(``);return}if(s(e.id,t)){k(`${Ur(t)} Pick a different address.`);return}k(``),A&&P({route:`/`+t})},B=()=>{let e=String(w.brief??``),t={brief:e},r=ro(e);if(r&&(t[S]=r),!y){let n=String(w.iconName??``).trim(),r=no(e)||(n?``:Oa(String(w[x]??``)));r&&r!==n&&(t.iconName=r)}Object.keys(t).some(e=>(n||{})[e]!==t[e])&&P(t)},V=String(w.pageChange??``),H=Xa(V),U=ma(H.address)||A,W=()=>{if(H.address&&!ma(H.address)){D(`Use an address with a letter or a number in it.`);return}if(U!==A&&s(e.id,U)){D(`${Ur(U)} Pick a different address.`);return}D(``);let t={pageChange:V};if(H.name&&(t[x]=H.name),H.heading&&(t[S]=H.heading),U!==A&&(t.route=`/`+U),!y){let e=String(w.iconName??``).trim(),n=no(V);n&&n!==e&&(t.iconName=n)}Object.keys(t).some(e=>(n||{})[e]!==t[e])?P(t):T(e=>({...e,...t}))},G=d?A||L:U,ee=f?{...n||{},...w}:{...n||{},...w,...Ms(n),...d?{}:{pageChange:H.rest,...H.name?{[x]:H.name}:{},...H.heading?{[S]:H.heading}:{}},route:G?`/`+G:``,contentKey:n?.contentKey||G||void 0},K=t.bn(),q=_s(w),J=bi(),Y=xi(w),X=cr(w),te=Qo({id:e.id,title:e.title,path:e.path},w,h).map(e=>e.id),ne=!!f&&(e.id===`contact`||e.id===`support`),re=_o(n),Z=f?!!re:!d,Q=ne||!!re?.formWish||!!re?.form||Z&&!!(so(n)||String(n?.form||``).trim()),ie=ne?{label:Z?`What would you like changed about the ${e.title.toLowerCase()} form here?`:`How should the ${e.title.toLowerCase()} form work here?`,hint:Z?`Optional — in your own words. Anything you do not mention stays as it is.`:`This page has its form already — say where it sits and what happens after someone sends it.`,placeholder:Z?`Ask for their phone number too, and move it under the opening hours.`:`Build it into the page under our opening hours, and after sending say we answer within a day.`}:Z&&Q?{label:`What would you like changed about the forms?`,hint:`Optional — in your own words; anything you do not mention stays as it is. One more form is described here too.`,placeholder:to}:{label:`What forms should the page have, and what does each ask?`,hint:`Optional — as many as you like, one after the other: what each asks, where it sits and what happens after. Every answer lands in your Inbox. Or name forms you already have.`,placeholder:C.form},ae=(0,i.jsx)(gs,{images:Pa(w),notes:String(w.imageNotes??``),onChange:e=>{if(d||f){P({images:e});return}let t=Pa(w).map(e=>e.url).filter(Boolean);P({images:e,imagesSent:Array.isArray(w.imagesSent)?w.imagesSent:t})},onNotes:e=>N(`imageNotes`,e),onBlur:()=>F(`imageNotes`)}),oe=(0,i.jsxs)(i.Fragment,{children:[l?.(ee),(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 pt-2 border-t border-[var(--panel-border)]/60`,children:[(0,i.jsx)(t.it,{saving:a}),(0,i.jsx)(`div`,{className:`flex flex-wrap items-center gap-2 ml-auto`,children:c})]})]}),se=f?(0,i.jsx)(t.dt,{label:f.ask,hint:`In your own words. Everything you do not mention stays as it is.`,value:String(w.pageWish??``),onChange:e=>N(`pageWish`,e),onBlur:()=>F(`pageWish`),placeholder:f.example}):d?(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 sm:gap-4`,children:[(0,i.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4`,children:[(0,i.jsx)(t.ft,{label:`Name`,hint:u?`The page is created the moment you leave this box.`:void 0,value:String(w[x]??``),onChange:e=>{N(x,e),E&&D(``)},onBlur:R,error:E,placeholder:C.name}),(0,i.jsx)(t.ft,{label:`Web address`,hint:u?`Made from the name unless you write one.`:void 0,prefix:`/`,value:j,onChange:e=>{M(e),O&&k(``)},onBlur:z,error:O,placeholder:ma(I)||ma(C.name)})]}),(0,i.jsx)(t.dt,{label:`What is on the page?`,hint:y?`In your own words — what it shows, what it says, what people do there. Whatever you skip, your assistant decides.`:`In your own words — what it shows, what people do there, and the icon it gets in the menu. Whatever you skip, your assistant decides.`,value:String(w.brief??``),onChange:e=>N(`brief`,e),onBlur:B,placeholder:C.describe})]}):(0,i.jsx)(t.dt,{label:`What would you like changed?`,hint:`In your own words — anything you do not mention stays as it is. To rename or move the page, add a line of its own: Name: Gallery, Address: /gallery or Heading: Our gallery.`,value:V,onChange:e=>{N(`pageChange`,e),E&&D(``)},onBlur:W,error:E,placeholder:eo}),ce={...w,...Ms(n)},le=na(ce),ue=()=>{JSON.stringify(n?.canDo||{})!==JSON.stringify(w.canDo||{})&&P({canDo:w.canDo||{}})};return(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-5`,children:[se,!f&&le.length>0&&(0,i.jsx)(vs,{title:`Who can do what`,hint:ua(ce,_),children:le.map(e=>(0,i.jsx)(t.dt,{label:ra(e,_),value:String(w.canDo?.[e]??``),onChange:t=>T(n=>({...n,canDo:{...n.canDo||{},[e]:t}})),onBlur:ue,placeholder:ia[t.ua(e)?`role`:e]},e))}),(0,i.jsx)(vs,{title:`Pictures`,hint:`Optional — upload each one; it gets a number you can refer to.`,children:ae}),(0,i.jsx)(vs,{title:`Forms`,hint:ie.hint,children:(0,i.jsx)(t.dt,{label:ie.label,value:String(w.formWish??``),onChange:e=>N(`formWish`,e),onBlur:()=>F(`formWish`),placeholder:ie.placeholder})}),(0,i.jsx)(vs,{title:`Schedules`,hint:b?`Optional — whose hours your team follows here. Weeks are kept on the Schedule screen.`:`Optional — whose working hours this page is built on, one person each. Then say what it does with them: a rota, who is in on Thursday, or a page people book time on.`,children:(0,i.jsx)(ys,{booking:q,team:b,schedules:K,onChange:e=>P({booking:e}),onAsk:e=>N(`booking`,{...q,ask:e}),onHow:e=>N(`booking`,{...q,how:e}),onBlur:()=>F(`booking`)})}),J.length>0&&(0,i.jsx)(vs,{title:`Booking links`,hint:`Optional — a booking link or booking page you already made. That exact one opens; nothing is rebuilt.`,children:(0,i.jsx)(bs,{targets:J,attached:Y,note:String(w.bookingLinksNote??``),onToggle:e=>P({bookingLinks:Ci(Y,e)}),onNote:e=>N(`bookingLinksNote`,e),onBlur:()=>F(`bookingLinksNote`)})}),m&&(0,i.jsx)(vs,{title:`Linked pages`,hint:`Optional — another of your pages that shows what happens here, usually one only your team can open. One copy of the sentence builds both.`,children:(0,i.jsx)(As,{links:X,targets:p,self:{id:e.id,contentKey:String(n?.contentKey||(d?G:``)||``)},schedules:K,taken:e=>s(`__new_linked_page__`,e),onCreatePage:m,onChange:(e,t)=>t?P({links:e}):N(`links`,e),onBlur:()=>F(`links`)})}),Ni()&&(0,i.jsx)(vs,{title:`Emails`,hint:`Optional — what this page should email, and what about. Receipts and sale alerts are switched on the payment itself, on the Payments screen.`,children:(0,i.jsx)(Ss,{emails:qo(w),audience:e.type,onChange:(e,t)=>t?P({emails:e}):N(`emails`,e),onBlur:()=>F(`emails`)})}),Ii()&&!u&&g&&(0,i.jsx)(vs,{title:`Payments`,hint:b?`Optional — tick the payments your team follows here: who paid, for what, when.`:`Optional — tick what is sold on this page. The prices and the buttons come from the Payments screen.`,children:(0,i.jsx)(xs,{products:h,ticked:te,team:b,note:String(w.paymentNote??``),onToggle:g,onNote:e=>N(`paymentNote`,e),onBlur:()=>F(`paymentNote`)})}),oe]})}function Ps(){let{userRole:e}=t.Qi(),n=(0,c.useLocation)(),[a,s]=(0,r.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_pages`);if(e)return zi(JSON.parse(e))}}catch{}return Li}),[l,u]=(0,r.useState)(()=>{try{return sessionStorage.getItem(`fbos_pages_expandedId`)||null}catch{return null}}),d=(0,r.useRef)(l),[f,p]=(0,r.useState)(null),m=e=>{let t=typeof window<`u`?window.location.origin:``;navigator.clipboard?.writeText(`${t}${e.path}`),p(e.id),setTimeout(()=>p(null),2e3)},[h,g]=(0,r.useState)(!1),[_,v]=(0,r.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_page_configs`);if(e)return JSON.parse(e)}}catch{}return{}}),[y,b]=(0,r.useState)({}),[x,S]=(0,r.useState)(()=>{try{let e=localStorage.getItem(`fbos_swr_page_briefs`);if(e)return JSON.parse(e)}catch{}return{}}),C=(0,r.useRef)(x);(0,r.useEffect)(()=>{C.current=x},[x]),(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(t.Ca,`sys_configs`,`page_briefs`),e=>{let t=e.exists()?e.data():{};S(t);try{localStorage.setItem(`fbos_swr_page_briefs`,JSON.stringify(t))}catch{}},()=>{}),[]);let{schedules:w}=t._(),{pages:T}=pi();yi(_i(w,T)),(0,r.useEffect)(()=>{let e=!1;return ei().then(t=>{e||Mi(t.configured)}),()=>{e=!0}},[]);let[E,D]=(0,r.useState)(()=>kr());(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.collection)(t.Ca,Nn),e=>{let t=[];e.forEach(e=>{e.id!==`_settings`&&t.push(Gn(e.id,e.data()))}),t.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)),Or(t),D(t)},()=>{}),[]),Fi(X().configured);let O=Tt(),k=e=>bt(e),A=async(e,n)=>{let r={...C.current[e]||{},...n};S(t=>({...t,[e]:r})),b(t=>({...t,[e]:!0}));try{await(0,o.setDoc)((0,o.doc)(t.Ca,`sys_configs`,`page_briefs`),{[e]:r},{merge:!0})}catch(e){console.error(`Could not save the page answers`,e)}b(t=>({...t,[e]:!1}))},[j,M]=(0,r.useState)({}),N=e=>M(t=>({...t,[e]:(t[e]||0)+1})),[P,F]=(0,r.useState)({}),[I,L]=(0,r.useState)(null),[R,z]=(0,r.useState)(null),[B,V]=(0,r.useState)(!1),H=(0,r.useRef)(null);(0,r.useEffect)(()=>{function e(e){H.current&&!H.current.contains(e.target)&&g(!1)}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let[U,W]=(0,r.useState)(new Set),[G,ee]=(0,r.useState)(new Set),[K,q]=(0,r.useState)([]),[J,Y]=(0,r.useState)([]),te=e=>(e||[]).map(e=>typeof e==`string`?{id:e,hidden:!1}:{id:String(e.id),hidden:!!e.hidden,...e.removed?{removed:!0}:{}});(0,r.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.doc)(t.Ca,`sys_configs`,`page_order`),e=>{let t=te(e.exists()&&e.data().order||[]);q(t),W(new Set(t.filter(e=>e.hidden).map(e=>e.id)))}),n=(0,o.onSnapshot)((0,o.doc)(t.Ca,`sys_configs`,`tab_order`),e=>{let t=te(e.exists()&&e.data().order||[]);Y(t),ee(new Set(t.filter(e=>e.hidden).map(e=>e.id)))});return()=>{e(),n()}},[]),(0,r.useEffect)(()=>{let e=n.pathname.split(`/pages/`)[1]?.split(`/`)[0];e&&!l&&a.some(t=>t.id===e)&&u(e)},[n.pathname,a]),(0,r.useEffect)(()=>{d.current=l;try{l?sessionStorage.setItem(`fbos_pages_expandedId`,l):sessionStorage.removeItem(`fbos_pages_expandedId`)}catch{}},[l]);let ne=(0,r.useRef)(null);(0,r.useEffect)(()=>{let e=ne.current;if(!e)return;try{let t=sessionStorage.getItem(`fbos_pages_scrollY`);t&&(e.scrollTop=parseInt(t,10))}catch{}let t=()=>{try{sessionStorage.setItem(`fbos_pages_scrollY`,String(e.scrollTop))}catch{}};return e.addEventListener(`scroll`,t,{passive:!0}),()=>e.removeEventListener(`scroll`,t)},[]),(0,r.useEffect)(()=>{(async()=>{try{let[e,n]=await Promise.all([(0,o.getDocs)((0,o.collection)(t.Ca,`sys_pages`)),(0,o.getDocs)((0,o.collection)(t.Ca,`sys_tabs`))]),r=[`home`,`drive`,`assets`,`contact`,`guide`,`templates`,`setup`,`support`,`theme`,`page_order`,`tab_order`],i=[],a={};e.forEach(e=>{if(!r.includes(e.id)){let t=e.data();i.push({id:e.id,title:t.pageName||t.title||e.id,path:t.route||`/`+e.id,type:`public`,isSystem:!1,enabled:t.enabled!==!1}),a[e.id]=t}}),n.forEach(e=>{if(!r.includes(e.id)){let n=e.data(),r=t.pa(n.pageType);i.push({id:e.id,title:n.tabName||n.title||e.id,path:n.route||`/`+e.id,type:r,isSystem:!1,enabled:n.enabled!==!1}),a[e.id]=n}});let c=ya(),l={...ba(!0,!0),...ba(!1,!0)};for(let[e,t]of Object.entries(l)){if(a[e])continue;let n=i.find(e=>e.path===t.path);if(n){n.fromFile=!0;continue}i.push(t),a[e]=c[e]?.config||{}}s(e=>{let t=zi(e.filter(e=>(e.isSystem||e.id.startsWith(`draft_`))&&e.id!==`drive`)),n=i.filter(e=>!t.some(t=>t.id===e.id)),r=[...t,...n];return typeof window<`u`&&localStorage.setItem(`fbos_swr_pages`,JSON.stringify(r)),r}),v(e=>{let t={...e,...a};return typeof window<`u`&&localStorage.setItem(`fbos_swr_page_configs`,JSON.stringify(t)),t})}catch(e){console.error(`Error loading custom pages`,e)}})()},[]);let re=async(e,n,r)=>{if(n.route&&!n.route.startsWith(`/`)&&(n.route=`/`+n.route),!String(n.route||``).replace(/^\/+/,``).trim()){v(t=>({...t,[e]:n}));return}let i=a.find(t=>t.id===e),c=r||i?.type||n.pageType||(e.startsWith(`pub_`)?`public`:void 0),l=c===`public`?`sys_pages`:`sys_tabs`;c&&c!==`public`?n.pageType=c:delete n.pageType;let f=Object.fromEntries(Object.entries(n).filter(([e,t])=>t!==void 0)),p=n.route?ha(n.route):e;f.contentKey||=p,n={...n,contentKey:f.contentKey},f.form===`__new__`&&(f.form=Vo(f),f.formIsNew=!0,n={...n,form:f.form,formIsNew:!0}),b(t=>({...t,[e]:!0,[p]:!0}));try{if(p!==e&&p.trim()!==``&&p!==`draft`){try{let{deleteDoc:n}=await import(`firebase/firestore`);await n((0,o.doc)(t.Ca,l,e))}catch{}await(0,o.setDoc)((0,o.doc)(t.Ca,l,p),f),s(t=>t.map(t=>t.id===e?{...t,id:p,_uiKey:t._uiKey||e,path:n.route,title:n.pageName||n.tabName||n.title||t.title}:t)),d.current===e&&(u(p),window.history.replaceState(null,``,`/pages/${p}`)),v(t=>{let r={...t};return r[p]=n,delete r[e],r});let r=c===`public`,i=r?`page_order`:`tab_order`,a=r?K:J;if(!a.some(e=>e.id===p)){let n=[...a.filter(t=>t.id!==e),{id:p,hidden:!1}];try{await(0,o.setDoc)((0,o.doc)(t.Ca,`sys_configs`,i),{order:n})}catch(e){console.error(`Failed to update tab order:`,e)}}}else await(0,o.setDoc)((0,o.doc)(t.Ca,l,e),f),v(t=>({...t,[e]:n})),s(t=>t.map(t=>t.id===e?{...t,path:n.route||t.path,title:n.pageName||n.tabName||n.title||t.title}:t))}catch(t){console.error(`Failed to save ${e} config:`,t)}finally{setTimeout(()=>{b(t=>({...t,[e]:!1,[p]:!1}))},500)}},Z=e=>{let t=`draft_`+Math.floor(Math.random()*1e5),n={id:t,title:`New page`,path:``,type:e,isSystem:!1,enabled:!0},r=e===`public`?{route:``,pageName:``,pageTitle:``,form:``,formWish:``,brief:``,imageNotes:``}:{route:``,tabName:``,tabTitle:``,iconName:``,template:`none`,form:``,formWish:``,brief:``,imageNotes:``,pageType:e};s(e=>[...e,n]),v(e=>({...e,[t]:r})),u(t),g(!1),setTimeout(()=>{document.getElementById(`page-${t}`)?.scrollIntoView?.({behavior:`smooth`,block:`center`})},100)},Q=e=>e.id.startsWith(`draft_`);if(e!==`admin`)return(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:(0,i.jsx)(Tn,{})});let ie=async(e,n,r)=>{let i=r===`public`,c=i?`page_order`:`tab_order`,l=i?K:J,u=(i?U:G).has(e);s(a.map(t=>t.id===e?{...t,enabled:u}:t));let d=[...l],f=d.findIndex(t=>t.id===e);f===-1?d.push({id:e,hidden:!0}):d[f]={...d[f],hidden:!u},await(0,o.setDoc)((0,o.doc)(t.Ca,`sys_configs`,c),{order:d})},ae=e=>!!e.fromFile&&(e.type===`public`?K:J).some(t=>t.id===e.id&&t.removed),oe=async(e,n)=>{let r=_[e.id],i=t.ra(n);if(vo(t.aa(r||{pageType:e.type}),t.aa(i)))return;let a=e.type;if(s(t=>t.map(t=>t.id===e.id?{...t,type:i.pageType}:t)),Q(e)){v(t=>({...t,[e.id]:{...t[e.id]||{},...i}}));return}b(t=>({...t,[e.id]:!0}));let c=Mo(r,n);(e.fromFile||r?.built)&&r&&!r.sent&&(c.sent=go(e,r));try{await(0,o.setDoc)((0,o.doc)(t.Ca,`sys_tabs`,e.id),c,{merge:!0}),v(t=>t[e.id]?{...t,[e.id]:{...t[e.id],...i,...c.sent?{sent:c.sent}:{}}}:t)}catch(t){console.error(`Failed to change who can open ${e.id}:`,t),s(t=>t.map(t=>t.id===e.id?{...t,type:a}:t))}finally{b(t=>({...t,[e.id]:!1}))}},se=(e,t)=>{if(!t){if(Q({id:e})){s(t=>t.filter(t=>t.id!==e)),v(t=>{let n={...t};return delete n[e],n}),l===e&&u(null);return}L(e)}},ce=async()=>{if(I){V(!0);try{let{deleteDoc:e,collection:n,getDocs:r,doc:i,getDoc:o,query:c,where:d}=await import(`firebase/firestore`),{ref:f,deleteObject:p}=await import(`firebase/storage`),m=a.find(e=>e.id===I),h=m?.type===`public`?`sys_pages`:`sys_tabs`;if(h===`sys_tabs`&&m){let a=_[I];if(!a)try{let e=await o(i(t.Ca,`sys_tabs`,I));e.exists()&&(a=e.data())}catch{}let s=(a?.tabName||a?.pageId||I).toLowerCase().replace(/[^a-z0-9]+/g,`_`),l=t._a(a),u=l?`role_${l}_${s}_records`:``,m=[`admin_${s}_records`,`mem_${s}_records`,`user_${s}_records`,...u?[u]:[]],h={[`admin_${s}_records`]:{prefix:`admin_files`,driveCollection:`admin_files`},[`mem_${s}_records`]:{prefix:`mem_files`,driveCollection:`mem_files`},[`user_${s}_records`]:{prefix:`user_files`,driveCollection:`user_files`},...u?{[u]:{prefix:`role_${l}_files`,driveCollection:`role_${l}_files`}}:{}},g=[];for(let i of m)g.push((async()=>{try{let a=await r(n(t.Ca,i)),o=h[i],s=[];for(let i of a.docs){let a=i.data();a.recordType===`file`&&a.downloadURL&&o&&s.push((async()=>{try{let i=`${o.prefix}%2F`,s=a.downloadURL.split(i)[1]?.split(`?`)[0];s&&await p(f(t.Ta,`${o.prefix}/${decodeURIComponent(s)}`)).catch(()=>{});let l=await r(c(n(t.Ca,o.driveCollection),d(`downloadURL`,`==`,a.downloadURL)));await Promise.all(l.docs.map(t=>e(t.ref)))}catch(e){console.error(`Error deleting storage file:`,e)}})())}await Promise.all(s),await Promise.all(a.docs.map(t=>e(t.ref))),Jr(i)}catch(e){console.error(`Error cleaning up collection ${i}:`,e)}})());for(let i of[`admin_files`,`mem_files`,`user_files`])g.push((async()=>{try{let a=await r(c(n(t.Ca,i),d(`sourceTab`,`==`,s)));await Promise.all(a.docs.map(async n=>{let r=n.data();if(r.downloadURL)try{let e=`${i}%2F`,n=r.downloadURL.split(e)[1]?.split(`?`)[0];n&&await p(f(t.Ta,`${i}/${decodeURIComponent(n)}`)).catch(()=>{})}catch{}await e(n.ref)}))}catch{}})());await Promise.all(g)}await e(i(t.Ca,h,I));let g=h===`sys_pages`?`page_order`:`tab_order`,v=h===`sys_pages`?K:J,{setDoc:y}=await import(`firebase/firestore`),b=m?.fromFile?[...v.filter(e=>e.id!==I),{id:I,hidden:!0,removed:!0}]:v.filter(e=>e.id!==I);await y(i(t.Ca,`sys_configs`,g),{order:b}),s(e=>e.filter(e=>e.id!==I)),l===I&&u(null)}catch(e){console.error(`Error deleting page:`,e)}V(!1),L(null)}},le=async(e,n)=>{if(e.isSystem)return;let r=e.type===`public`,i=r?`page_order`:`tab_order`,s=[...r?K:J];a.filter(e=>e.type===`public`===r&&!e.isSystem&&!s.some(t=>t.id===e.id)).forEach(e=>s.push({id:e.id,hidden:!1}));let c=va(s,e.id,n,r?`home`:void 0);if(c){r?q(c):Y(c);try{await(0,o.setDoc)((0,o.doc)(t.Ca,`sys_configs`,i),{order:c})}catch(e){console.error(`Failed to reorder pages:`,e)}}},ue=(e,t)=>{if(Hr(t))return!0;let n=t.replace(/[^a-zA-Z0-9_-]/g,`_`).toLowerCase();return a.some(r=>{if(r.id===e)return!1;let i=String(_[r.id]?.route??r.path??``).replace(/^\/+/,``).toLowerCase();return i!==``&&i===t||r.id===n})},de=e=>e===`admin`?An:e===`internal`?jn:e===`public`?On:kn,fe=async()=>{let e=a.find(e=>e.id===R);if(!e){z(null);return}F(t=>({...t,[e.id]:!0}));let n=_[e.id]||{};if(e.isSystem){try{await(0,o.setDoc)((0,o.doc)(t.Ca,`sys_configs`,`page_briefs`),{[e.id]:(0,o.deleteField)()},{merge:!0}),S(t=>{let n={...t};return delete n[e.id],n}),N(e.id)}catch(e){console.error(`Failed to clear the page answers`,e)}F(t=>({...t,[e.id]:!1})),z(null);return}let r=jo(e,n);if(r)try{await(0,o.deleteDoc)((0,o.doc)(t.Ca,e.type===`public`?`sys_pages`:`sys_tabs`,e.id)),v(t=>({...t,[e.id]:r})),s(t=>t.map(t=>t.id===e.id?{...t,fromFile:!0,title:r.pageName||r.tabName||r.pageTitle||r.tabTitle||r.title||t.title,path:r.route?r.route.startsWith(`/`)?r.route:`/`+r.route:t.path}:t))}catch(e){console.error(`Failed to reset the page`,e)}else await re(e.id,{...de(e.type),...n.contentKey?{contentKey:n.contentKey}:{}});F(t=>({...t,[e.id]:!1})),z(null)},pe=[...Pr.map(e=>({...e,config:Eo(e.id,x[e.id])})),...a.filter(e=>!e.isSystem&&!Q(e)&&!ae(e)).map(e=>({id:e.id,title:e.title,path:e.path,brief:String(_[e.id]?.brief||``),config:_[e.id],audience:e.type}))],me=async e=>{let{id:t,config:n,isPublic:r}=ga(e);return await _a(e),s(r=>r.some(e=>e.id===t)?r:[...r,{id:t,title:e.name,path:n.route,type:e.type,isSystem:!1,enabled:!0}]),v(e=>({...e,[t]:n})),(r?q:Y)(e=>e.some(e=>e.id===t)?e:[...e,{id:t,hidden:!1}]),t},he=Xo(E),ge=async(e,n)=>{let r=e.isSystem?Eo(e.id,C.current[e.id]):_[e.id],i={id:e.id,title:e.title,path:e.path,config:r};!e.isSystem&&r&&(r.built||e.fromFile)&&!r.sent&&re(e.id,{...r,sent:go(i,r)});let a={...n,pageIds:mr(n,i)},s=E.map(e=>e.id===n.id?a:e);Or(s),D(s);try{await(0,o.setDoc)((0,o.doc)(t.Ca,Nn,n.id),{pageIds:a.pageIds},{merge:!0})}catch(e){console.error(`Could not save which pages the payment goes on`,e)}},_e=e=>{for(let t of cr(e)){if(!t.pageId)continue;let e=a.find(e=>!e.isSystem&&!Q(e)&&(e.id===t.pageId||String(_[e.id]?.contentKey||``)===t.pageId)),n=e?_[e.id]:void 0;!e||!n||n.built||e.fromFile||re(e.id,{...n,built:!0,formWish:``,imagesSent:Na(n).map(e=>e.url),sent:go(e,n)})}},ve=[{id:`public`,title:Vi.public,icon:t.di,description:`On your website and in the site menu — open to everyone, signed in or not.`,filter:e=>e.type===`public`,defaultType:`public`},{id:`tabs`,title:Vi.tabs,icon:t.$r,description:`In the dashboard, behind sign-in. Who opens each one — Members, your team, admins, or a role of your own — is set on its own row.`,filter:e=>e.type!==`public`,defaultType:`user`}];return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(we,{children:`Your Pages`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/pages`]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsxs)(`div`,{className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background`,children:[(0,i.jsxs)(`div`,{className:`flex items-start justify-between gap-3 sm:gap-6 mb-4 pb-4 md:mb-6 md:pb-6 border-b border-[var(--panel-border)]/50 relative z-10 shrink-0 px-4 pt-4 sm:px-6 sm:pt-6 md:px-10 md:pt-10`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`div`,{className:`flex items-center min-h-[40px]`,children:(0,i.jsx)(`h2`,{className:`text-lg md:text-xl font-extrabold text-foreground tracking-tight leading-tight truncate`,children:`Your pages`})}),(0,i.jsxs)(`p`,{className:`text-[12.5px] md:text-[14px] font-medium text-foreground/60 leading-relaxed max-w-3xl`,children:[(0,i.jsx)(`span`,{className:`md:hidden`,children:`Add a page, say what goes on it, paste the sentence into your assistant.`}),(0,i.jsx)(`span`,{className:`max-md:hidden`,children:`Add a page here, say what you would like on it, and copy the sentence it writes into your assistant's chat. Renaming, reordering, hiding and deleting all happen right here.`})]})]}),(0,i.jsx)(`div`,{className:`relative z-50 shrink-0 flex items-center gap-1`,children:(0,i.jsxs)(`div`,{className:`relative`,children:[(0,i.jsx)(t.cr,{variant:`secondary`,onClick:()=>g(!h),className:`w-10 h-10 p-0 border-transparent bg-transparent hover:bg-foreground/5 rounded-xl flex items-center justify-center shrink-0 transition-colors group cursor-pointer`,title:`Add a page`,children:(0,i.jsx)(t.Hr,{className:`w-4 h-4 text-foreground/60 group-hover:text-foreground transition-colors`})}),(0,i.jsx)(t.pr,{children:h&&(0,i.jsxs)(t.fr.div,{ref:H,initial:{opacity:0,y:10,scale:.95},animate:{opacity:1,y:0,scale:1},exit:{opacity:0,y:10,scale:.95},className:`absolute top-full mt-2 right-0 w-56 glass-popover border border-[var(--panel-border)] rounded-2xl p-2 z-50 flex flex-col gap-1`,children:[(0,i.jsx)(`span`,{className:`px-3 pt-1 pb-2 text-[10px] font-bold uppercase tracking-widest text-foreground/40`,children:`Add a page to`}),ve.map(e=>(0,i.jsx)(`button`,{onClick:()=>Z(e.defaultType),className:`text-left px-3 py-2 text-[13px] font-bold text-foreground/70 hover:text-foreground hover:bg-foreground/5 rounded-lg transition-colors cursor-pointer`,children:e.title},e.id))]})})]})})]}),(0,i.jsx)(`div`,{ref:ne,className:`px-4 sm:px-6 md:px-10 pb-6 md:pb-10 flex flex-col pt-6 sm:pt-7 md:pt-9 gap-4 overflow-y-auto relative min-h-[400px]`,children:ve.map((e,n)=>{let r=a.filter(e.filter).filter(e=>!ae(e)),o=e.id===`public`?K:J,s=r.sort((e,t)=>{if(e.id===`home`)return-1;if(t.id===`home`)return 1;let n=o.findIndex(t=>t.id===e.id),r=o.findIndex(e=>e.id===t.id);return n===-1&&r===-1?0:n===-1?1:r===-1?-1:n-r}),d=e.icon,p=e=>e.type===`public`?U.has(e.id):G.has(e.id),h=s.filter(e=>!p(e)),g=s.filter(e=>p(e)),b=(n,r)=>{let o=n.isSystem?To[n.id]:void 0,s=l===n.id,d=Q(n),p=da({draft:d,hidden:r}),h=!n.isSystem||!!o,g=!n.isSystem&&!d&&(!!n.fromFile||!!_[n.id]?.built),b=n.isSystem?[]:hs(n,_[n.id],a,_),S=()=>{u(n.id),window.history.replaceState(null,``,`/pages/${n.id}`)},w=()=>{u(null),window.history.replaceState(null,``,`/pages`)},T=e=>{if(n.isSystem){let e=C.current[n.id]||{};A(n.id,{pageWish:``,formWish:``,imagesSent:Na(e).map(e=>e.url),sent:go(n,Eo(n.id,e))}),_e(e),N(n.id);return}let t=_[n.id];if(t){let r=Na(t).map(e=>e.url),i=go(n,t),a=e===`build`?{...t,built:!0,formWish:``,imagesSent:r,sent:i}:{...t,pageChange:``,formWish:``,imagesSent:r,sent:i};v(e=>({...e,[n.id]:a})),re(n.id,a),_e(t)}N(n.id)},E=()=>{let e=_[n.id];if(!e)return;let t={...e,built:!0,formWish:``,imagesSent:Na(e).map(e=>e.url),sent:go(n,e)};v(e=>({...e,[n.id]:t})),re(n.id,t),N(n.id)};return(0,i.jsxs)(`div`,{id:`page-${n.id}`,onClick:()=>{h&&(s?w():S())},className:`group flex flex-col p-3.5 sm:py-4 sm:px-5 glass-panel border transition-all rounded-2xl hover:shadow-sm ${h?`cursor-pointer hover:border-accent/40`:``} ${r?`opacity-60 bg-foreground/[0.01] border-[var(--panel-border)]/50`:`border-transparent hover:border-[var(--panel-border)]`}`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between w-full gap-2 sm:gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 flex-1 min-w-0`,children:[!n.isSystem&&!d&&(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex flex-col shrink-0`,onClick:e=>e.stopPropagation(),children:[(0,i.jsx)(`button`,{type:`button`,title:`Move up`,"aria-label":`Move ${n.title} up`,onClick:()=>le(n,`up`),className:No,children:(0,i.jsx)(t.ji,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`button`,{type:`button`,title:`Move down`,"aria-label":`Move ${n.title} down`,onClick:()=>le(n,`down`),className:No,children:(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5`})})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,i.jsx)(`h3`,{className:`text-[14.5px] font-bold text-foreground tracking-tight truncate`,children:n.title}),!n.isSystem&&(0,i.jsx)(Lo,{status:p}),n.fromFile&&(0,i.jsxs)(`span`,{className:Po,title:`Your assistant wrote this one as a file. Delete hides it and gives you the sentence that removes its files.`,children:[(0,i.jsx)(t.mi,{className:`w-3 h-3`}),` Written as a file`]}),b.length>0&&(0,i.jsxs)(`span`,{className:Po,title:`This page shows what happens on ${b.join(`, `)}.`,children:[(0,i.jsx)(t.ri,{className:`w-3 h-3`}),` Linked to `,b.join(`, `)]})]}),d&&(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 truncate`,children:`Not saved yet — give it a name`})]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2 shrink-0`,children:[!n.isSystem&&n.type!==`public`&&(0,i.jsx)(`div`,{className:`max-sm:hidden min-w-0`,children:(0,i.jsx)(xa,{roles:O,picked:t.aa(_[n.id]||{pageType:n.type}),busy:y[n.id],onChange:e=>oe(n,e),onCreateRole:k})}),!Ri.has(n.id)&&!d&&(0,i.jsx)(t.Q,{icon:r?t.hi:t.gi,compact:!0,title:r?`Show this page`:`Hide this page`,onClick:e=>{e.stopPropagation(),ie(n.id,n.isSystem,n.type)},children:r?`Show`:`Hide`}),h?(0,i.jsx)(`div`,{className:`p-1.5 transition-transform duration-300 text-foreground/40 shrink-0 ${s?`rotate-180`:``}`,children:(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5`})}):(0,i.jsx)(`div`,{className:`w-[24px] shrink-0`})]})]}),n.path&&s&&(0,i.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 mt-1.5`,onClick:e=>e.stopPropagation(),children:[(0,i.jsx)(c.Link,{to:n.path,className:`text-[12px] font-medium text-foreground/45 truncate underline decoration-foreground/20 underline-offset-2 hover:text-accent hover:decoration-accent transition-colors`,title:`Open this page`,children:Ro(n.path)}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>m(n),title:`Copy this link`,"aria-label":`Copy the link to ${n.title}`,className:`shrink-0 w-6 h-6 rounded-md flex items-center justify-center text-foreground/35 hover:text-foreground hover:bg-foreground/[0.07] transition-colors cursor-pointer`,children:f===n.id?(0,i.jsx)(t.Fi,{className:`w-3.5 h-3.5 text-accent`}):(0,i.jsx)(t.Si,{className:`w-3.5 h-3.5`})})]}),(0,i.jsxs)(t.pr,{children:[s&&o&&(0,i.jsx)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden mt-4 pt-4 border-t border-[var(--panel-border)]/50 pb-1`,onClick:e=>e.stopPropagation(),children:(0,i.jsx)(Ns,{page:n,config:x[n.id],saving:y[n.id],system:_o(x[n.id])?{ask:o.changeAsk,example:o.changeExample}:{ask:o.ask,example:o.example},onSave:e=>A(n.id,e),addressTaken:ue,linkTargets:pe,onCreateLinkedPage:me,products:he,onTogglePayment:e=>ge(n,e),customRoles:O,onCreateRole:k,footer:e=>(0,i.jsx)(at,{compact:!0,title:o.title,prompt:Oo(n.id,e,pe),locked:!!ko(n.id,e,pe),onCopied:()=>T(`change`)}),actions:Ba(x[n.id])?(0,i.jsx)(t.Q,{icon:t.Lr,tone:`danger`,compact:!0,title:`Start again`,busy:P[n.id],onClick:()=>z(n.id),children:`Reset`}):null},`${n.id}:${j[n.id]||0}`)}),s&&!n.isSystem&&_[n.id]&&(0,i.jsxs)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden mt-4 pt-4 border-t border-[var(--panel-border)]/50 pb-1`,onClick:e=>e.stopPropagation(),children:[!d&&(0,i.jsxs)(`div`,{className:`sm:hidden flex items-center justify-between gap-3 mb-5`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-semibold text-foreground/55`,children:`Spot in the menu`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,i.jsx)(t.Q,{icon:t.Wi,title:`Move up`,onClick:()=>le(n,`up`),children:`Up`}),(0,i.jsx)(t.Q,{icon:t.Ji,title:`Move down`,onClick:()=>le(n,`down`),children:`Down`})]})]}),!n.isSystem&&n.type!==`public`&&(0,i.jsxs)(`div`,{className:`sm:hidden flex items-center justify-between gap-3 mb-5`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-semibold text-foreground/55 shrink-0`,children:`Who can open this page`}),(0,i.jsx)(xa,{roles:O,picked:t.aa(_[n.id]||{pageType:n.type}),busy:y[n.id],onChange:e=>oe(n,e),onCreateRole:k})]}),(0,i.jsx)(Ns,{page:n,config:_[n.id],saving:y[n.id],isNew:d,quick:!g,onSave:e=>re(n.id,e),addressTaken:ue,linkTargets:pe,onCreateLinkedPage:me,products:he,onTogglePayment:e=>ge(n,e),customRoles:O,onCreateRole:k,footer:e=>g?(0,i.jsx)(at,{compact:!0,title:`Copy this to change the page`,prompt:wo(n,e,pe),locked:!!Co(e,n,pe),onCopied:()=>T(`change`)}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(at,{compact:!0,title:`Then copy this into your assistant’s chat`,description:d?void 0:`This one builds the page from scratch. Once it is copied, this row asks only what to change.`,prompt:qa(n,e,pe),locked:!!Ma(n,e,pe),onCopied:()=>T(`build`)}),!d&&(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-1`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/50`,children:`Already built this page with your assistant?`}),(0,i.jsx)(t.Q,{icon:t.yr,compact:!0,title:`This page is built — just change it`,onClick:E,children:`Just change it`})]})]}),actions:(0,i.jsxs)(i.Fragment,{children:[Ao(_[n.id],jo(n,_[n.id])??de(n.type))&&(0,i.jsx)(t.Q,{icon:t.Lr,tone:`danger`,compact:!0,title:`Reset this page`,busy:P[n.id],onClick:()=>z(n.id),children:`Reset`}),!n.isSystem&&(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Delete this page`,onClick:()=>se(n.id,n.isSystem),children:`Delete`})]})},`${n._uiKey||n.id}:${j[n.id]||0}`)]})]})]},`${e.id}-${n._uiKey||n.id}`)};return(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex flex-col relative`,children:(0,i.jsx)(t.at,{icon:d,title:e.title,description:e.description,children:s.length===0?(0,i.jsxs)(`div`,{className:`flex flex-col items-start sm:flex-row sm:items-center gap-3 rounded-2xl border border-dashed border-[var(--panel-border)] px-5 py-4`,children:[(0,i.jsx)(t.Q,{icon:t.Hr,onClick:()=>Z(e.defaultType),children:`Add a page`}),(0,i.jsxs)(`p`,{className:`text-[12.5px] text-foreground/55 font-medium leading-relaxed`,children:[(0,i.jsx)(`span`,{className:`sm:hidden`,children:Ca}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:Sa})]})]}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[h.map(e=>b(e,!1)),(0,i.jsx)(`div`,{className:`flex items-center rounded-2xl border border-dashed border-[var(--panel-border)] px-5 py-3`,children:(0,i.jsx)(t.Q,{icon:t.Hr,onClick:()=>Z(e.defaultType),children:`Add a page`})}),g.length>0&&(0,i.jsxs)(`details`,{className:`mt-4 group/details`,children:[(0,i.jsxs)(`summary`,{className:`text-[11px] font-bold uppercase tracking-wider text-foreground/40 cursor-pointer list-none flex items-center gap-2 select-none hover:text-foreground/70 transition-colors w-fit pb-1 ml-1 outline-none`,children:[(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 group-open/details:-rotate-180 transition-transform`}),`Hidden pages (`,g.length,`)`]}),(0,i.jsx)(`div`,{className:`flex flex-col gap-4 mt-4`,children:g.map(e=>b(e,!0))})]})]})})},e.id)})})]})]}),(0,i.jsx)(He,{isOpen:!!I,onCancel:()=>L(null),onConfirm:ce,title:`Delete this page?`,message:`The page and everything saved on it will be gone for good. This cannot be undone.`,confirmText:`Delete page`,isProcessing:B}),(0,i.jsx)(He,{isOpen:!!R,onCancel:()=>z(null),onConfirm:fe,title:a.find(e=>e.id===R)?.isSystem?`Start this page again?`:`Reset this page?`,message:(()=>{let e=a.find(e=>e.id===R);return e?.isSystem?`What you have written about this page is cleared, and the pictures you added with it, so you can describe it again from scratch. The page itself stays as your assistant last built it.`:e&&jo(e,_[e.id])?`Its settings go back to how your assistant built the page, and what you wrote about it is cleared. What people have saved on the page is kept.`:`Its name, heading, web address, icon and form go back to how they started, and what you wrote about it is cleared. What people have saved on the page is kept.`})(),confirmText:a.find(e=>e.id===R)?.isSystem?`Start again`:`Reset page`,isProcessing:!!R&&!!P[R]})]})}var Fs=new Set([`contact`,`support`]),Is=[{value:`text`,label:`Short text`},{value:`textarea`,label:`Long text`},{value:`email`,label:`Email`},{value:`tel`,label:`Phone`},{value:`number`,label:`Number`},{value:`date`,label:`Date`},{value:`currency`,label:`Money`},{value:`checkbox`,label:`Yes-no`},{value:`select`,label:`Choose one`},{value:`file`,label:`File upload`}],Ls={value:`schedule`,label:`A time to book`},Rs={age:`Age`},zs=e=>[...Is,Ls].find(t=>t.value===e)?.label||Rs[e||``]||`Short text`,Bs=(e,t=!1)=>{let n=t||e===`schedule`?[...Is,Ls]:Is;return n.some(t=>t.value===e)||!e?n:[...n,{value:e,label:zs(e)}]},Vs=(e,n)=>{let r=t.Gn(e).map(e=>{let r=n.find(t=>t.id===e);return r?t.In(r):``}).filter(Boolean);return r.length?r.join(`, `):`nothing picked yet`},Hs={public:`Anyone`,private:`Signed-in users`},Us=e=>(e||``).toLowerCase().trim().replace(/[^a-z0-9]+/g,`_`).replace(/^_+|_+$/g,``),Ws=(e,t)=>{if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}_${n}`);)n++;return`${e}_${n}`},Gs=(e,t,n)=>{if(!(!e.name||e.name===Us(e.label||``)))return e.name;let r=Us(t);return r?Ws(r,n.filter(t=>t!==e).map(e=>e.name)):``},Ks=()=>({name:``,type:`text`,label:``,placeholder:``,required:!1}),qs={firstForm:`Forms are made with their pages — add a page on the Pages screen and pick A new form made for this page. Every form then shows up here.`};function Js({choices:e,onChange:n}){return(0,i.jsx)(t.Z,{label:`Choices`,hint:`The options people pick from.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.length===0&&(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/40 font-medium px-1`,children:`No choices yet — add the first one.`}),e.map((r,a)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`text`,value:r,"aria-label":`Choice ${a+1}`,placeholder:`e.g. Under 1,000`,onChange:t=>n(e.map((e,n)=>n===a?t.target.value:e)),className:t.et}),(0,i.jsx)(t.Q,{icon:t._r,tone:`danger`,title:`Remove choice ${a+1}`,onClick:()=>n(e.filter((e,t)=>t!==a)),children:`Remove`})]},a)),(0,i.jsx)(`div`,{children:(0,i.jsx)(t.Q,{icon:t.Hr,onClick:()=>n([...e,``]),children:`Add choice`})})]})})}function Ys(){let{userRole:e}=t.Qi(),n=(0,c.useNavigate)(),a=t.ka(),s=()=>{let e=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},n={...t.dr,contact:a?.defaultConfigs?.contactForm||t.dr.contact,support:a?.defaultConfigs?.supportForm||t.dr.support};for(let[t,r]of Object.entries(e))n[t]=r;return n},[l,u]=(0,r.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_forms`);if(e)return JSON.parse(e)}let e={...t.dr,contact:a?.defaultConfigs?.contactForm||t.dr.contact,support:a?.defaultConfigs?.supportForm||t.dr.support},n=(typeof window<`u`?window.__FBOS_FORMS__:null)||{};for(let[t,r]of Object.entries(n))e[t]=r;let r={};for(let[t,n]of Object.entries(e)){let e=JSON.parse(JSON.stringify(n));e._uiKey=Math.random().toString(36).substring(7),r[t]=e}return r}catch{return{}}}),[d,f]=(0,r.useState)(()=>!(typeof window<`u`&&localStorage.getItem(`fbos_swr_forms`))),[p,m]=(0,r.useState)({}),[h,g]=(0,r.useState)(null),[_,v]=(0,r.useState)(new Set),y=Ve(),{schedules:b}=t._(),[x,S]=(0,r.useState)({}),[C,w]=(0,r.useState)(null),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)({}),k=(0,r.useRef)({}),A=(e,t)=>{k.current={...k.current,[e]:t},O(k.current)};(0,r.useEffect)(()=>{j()},[]);let j=async()=>{try{f(!0);let e=await(0,o.getDocs)((0,o.collection)(t.Ca,`sys_forms`)),n={},r=new Set;e.forEach(e=>{if(e.id!==`pubForm`&&e.id!==`userForm`){let t=e.data();t._uiKey=l[e.id]?._uiKey||t._uiKey||Math.random().toString(36).substring(7),n[e.id]=t,r.add(e.id)}}),v(r);try{await(0,o.deleteDoc)((0,o.doc)(t.Ca,`sys_forms`,`pubForm`)),await(0,o.deleteDoc)((0,o.doc)(t.Ca,`sys_forms`,`userForm`))}catch{}let i=s();for(let[e,t]of Object.entries(i))if(!n[e]){let r={...t};r._uiKey=l[e]?._uiKey||Math.random().toString(36).substring(7),n[e]=r}else if(n[e]._uiKey=l[e]?._uiKey||n[e]._uiKey||Math.random().toString(36).substring(7),!n[e].fields||n[e].fields.length===0){let t=i[e];n[e].fields=t.fields||[]}let a={};for(let e of Object.keys(i))n[e]&&(a[e]=n[e]);for(let e of Object.keys(n))a[e]||(a[e]=n[e]);let c=window.location.pathname.split(`/forms/`)[1]?.split(`/`)[0];c&&a[c]&&S({[c]:!0}),k.current={},O({}),u(a),typeof window<`u`&&localStorage.setItem(`fbos_swr_forms`,JSON.stringify(a))}catch(e){console.error(`Failed to load forms:`,e)}finally{f(!1)}},M=async(e,n)=>{let r={...n};l[e]?._uiKey&&(r._uiKey=l[e]._uiKey),delete r.submitPage,e===`contact`?(r.systemName=`contact`,r.formType=`public`):e===`support`&&(r.systemName=`support`,r.formType=`private`);let i=r.systemName||e;if(i!==e&&i.trim()!==``){u(t=>{let n={};for(let a of Object.keys(t))a===e?n[i]=r:n[a]=t[a];return n}),x[e]&&S(t=>{let n={};for(let r of Object.keys(t))r===e?n[i]=t[r]:n[r]=t[r];return n}),m(e=>({...e,[i]:!0}));try{await(0,o.setDoc)((0,o.doc)(t.Ca,`sys_forms`,i),r),await(0,o.deleteDoc)((0,o.doc)(t.Ca,`sys_forms`,e)),localStorage.setItem(`fbos_custom_form_${i}`,`true`),localStorage.removeItem(`fbos_custom_form_${e}`),localStorage.setItem(`fbos_form_${i}`,JSON.stringify(r)),localStorage.removeItem(`fbos_form_${e}`)}catch(e){console.error(`Failed to migrate form map ID:`,e)}finally{setTimeout(()=>{m(e=>({...e,[i]:!1}))},500)}}else{u(t=>({...t,[e]:r})),m(t=>({...t,[e]:!0}));try{await(0,o.setDoc)((0,o.doc)(t.Ca,`sys_forms`,e),r),localStorage.setItem(`fbos_custom_form_${e}`,`true`),localStorage.setItem(`fbos_form_${e}`,JSON.stringify(r))}catch(e){console.error(`Failed to save form:`,e)}finally{setTimeout(()=>{m(t=>({...t,[e]:!1}))},500)}}},N=(e,t,n)=>A(e,{...t,...n}),P=(e,t,n)=>{let r={...t,...n};A(e,r),M(e,r)},F=e=>{let t=k.current[e];t&&M(e,t)},I=(e,t,n)=>P(e,t,{fields:n}),L=async e=>{if(!Fs.has(e)){E(!0);try{await(0,o.deleteDoc)((0,o.doc)(t.Ca,`sys_forms`,e)),u(t=>{let n={...t};return delete n[e],n}),n(`/forms`)}catch(e){console.error(`Failed to delete form`,e)}finally{E(!1),w(null)}}},R=async e=>{if(!_.has(e)){w(null);return}E(!0);let n=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},r=Fs.has(e)||!!n[e]||!!a?.defaultConfigs?.[e]||!!a?.defaultConfigs?.[`${e}Form`];try{r?(m(t=>({...t,[e]:!0})),await(0,o.deleteDoc)((0,o.doc)(t.Ca,`sys_forms`,e)),localStorage.removeItem(`fbos_form_${e}`),localStorage.removeItem(`fbos_custom_form_${e}`),await j(),setTimeout(()=>m(t=>({...t,[e]:!1})),500)):await M(e,s().contact||s().support)}catch(e){console.error(`Reset failed:`,e)}finally{E(!1),w(null)}};if(e!==`admin`)return(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:(0,i.jsx)(Tn,{})});let z=e=>{S(t=>{let n={...t,[e]:!t[e]};if(n[e])window.history.replaceState(null,``,`/forms/${e}`);else{let e=Object.keys(n).filter(e=>n[e]);e.length>0?window.history.replaceState(null,``,`/forms/${e[0]}`):window.history.replaceState(null,``,`/forms`)}return n})},B=Object.keys(x).find(e=>x[e]),V=(e,n,r,a,o)=>{let s=(t,r)=>{let i=o.map((e,n)=>n===a?{...e,...t}:e);r?I(e,n,i):N(e,n,{fields:i})},c=t=>{let i=t===`schedule`?{type:t,look:`compact`,schedules:[]}:t===`select`?{type:t,options:r.options||[]}:{type:t};I(e,n,o.map((e,n)=>{if(n!==a)return e;let r={...e,...i};return t!==`schedule`&&(delete r.members,delete r.schedules,delete r.look,delete r.together),r}))},l=t=>{let r=a+t;if(r<0||r>=o.length)return;let i=[...o];[i[a],i[r]]=[i[r],i[a]],I(e,n,i)},u=r.type!==`checkbox`&&r.type!==`select`&&r.type!==`date`&&r.type!==`file`&&r.type!==`schedule`;return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)] p-4 sm:p-5 flex flex-col gap-5`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-2 flex-wrap`,children:[(0,i.jsxs)(`span`,{className:`text-[13px] font-bold text-foreground`,children:[`Question `,a+1,r.type===`schedule`&&(0,i.jsxs)(`span`,{className:`font-medium text-foreground/50`,children:[` · A time to book — `,Vs(r,b)]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,i.jsx)(t.Q,{icon:t.Wi,disabled:a===0,title:`Move up`,onClick:()=>l(-1),children:`Up`}),(0,i.jsx)(t.Q,{icon:t.Ji,disabled:a===o.length-1,title:`Move down`,onClick:()=>l(1),children:`Down`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,title:`Remove question ${a+1}`,onClick:()=>I(e,n,o.filter((e,t)=>t!==a)),children:`Remove`})]})]}),(0,i.jsx)(t.ft,{label:`Question`,hint:`What you are asking for, in the words the person will read.`,value:r.label||``,placeholder:`e.g. What is your budget?`,onChange:e=>s({label:e,name:Gs(r,e,o)},!1),onBlur:()=>F(e)}),(0,i.jsx)(t.ct,{label:`Kind of answer`,hint:`Sets the box people type into and what counts as a valid answer.`,value:r.type||`text`,options:Bs(r.type,b.length>0),allowEmpty:!1,onChange:c}),(0,i.jsx)(t.mt,{label:`Required`,hint:`On means the form cannot be sent until this is answered.`,hintWideOnly:!0,enabled:!!r.required,onChange:e=>s({required:e},!0)}),r.type===`select`&&(0,i.jsx)(Js,{choices:r.options||[],onChange:e=>s({options:e},!0)}),r.type===`schedule`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.Z,{label:`What can be booked`,hint:`Pick a schedule from the Schedule screen — one per person. Visitors see the free times in their own time zone; nobody can take a time twice.`,error:t.Gn(r).length?void 0:`Pick at least one schedule`,children:(0,i.jsx)(Ai,{schedules:b,selected:t.Gn(r),onPick:e=>{s({schedules:t.An(t.Gn(r),e,b)},!0)}})}),t.Yn(b.filter(e=>t.Gn(r).includes(e.id)))&&(0,i.jsx)(t.ct,{label:`Who is the booking with?`,hint:`One of them: the visitor picks a person, then one of that person's own times. All of them: only the times every one of them is free are offered, and one booking goes in all their calendars. Both: the visitor chooses.`,value:t.Wn(r),options:t.yt,allowEmpty:!1,onChange:e=>s({party:t.Wn({party:e}),together:e===`all`},!0)}),(0,i.jsx)(t.ct,{label:`How should the booking look?`,value:r.look||`compact`,options:t._t,allowEmpty:!1,onChange:e=>s({look:e===`calendar`?`calendar`:`compact`},!0)})]}),r.type===`file`&&(0,i.jsx)(t.ft,{label:`Words on the upload box`,hint:`What the box says before anything is picked. People can attach several files. Leave it empty for “Attach files”.`,value:r.placeholder||``,placeholder:`Attach files`,onChange:e=>s({placeholder:e},!1),onBlur:()=>F(e)}),r.type===`currency`&&(0,i.jsx)(t.ft,{label:`Currency symbol`,hint:`Shown inside the box, before the amount.`,value:r.currencySymbol||``,placeholder:`$`,onChange:e=>s({currencySymbol:e},!1),onBlur:()=>F(e)}),u&&(0,i.jsx)(t.ft,{label:`Example answer`,hint:`Faint grey text inside the box, to show people what you expect.`,value:r.placeholder||``,placeholder:`e.g. jane@example.com`,onChange:e=>s({placeholder:e},!1),onBlur:()=>F(e)})]},a)},H=(e,n)=>{let r=D[e]||n,a=Fs.has(e),o=r.formType||`public`,s=r.fields||[],c=_.has(e);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsxs)(t.at,{icon:t.Tr,title:`Basics`,description:`What people see at the top of this form and on its button.`,children:[(0,i.jsx)(t.ft,{label:`Form name`,hint:`The heading at the top of the form.`,value:r.title||``,placeholder:`e.g. Get in touch`,onChange:t=>N(e,r,{title:t}),onBlur:()=>F(e)}),(0,i.jsx)(t.ft,{label:`Button text`,hint:`The words on the button that sends the form.`,value:r.buttonName||r.submitText||``,placeholder:`e.g. Send message`,onChange:t=>N(e,r,{buttonName:t,submitText:t}),onBlur:()=>F(e)})]}),(0,i.jsx)(t.at,{icon:t.xr,title:`Who it is for`,description:`Who can fill this in, and where their answers land.`,children:(0,i.jsx)(t.ct,{label:`Who it is for`,hint:`Who can fill this in follows the page this form was made for, so it cannot change here. Changing it after answers arrive would file new answers under the wrong list in your Inbox.`,value:o,allowEmpty:!1,disabled:!0,options:[{value:`public`,label:`Anyone`},{value:`private`,label:`Signed-in users`}],onChange:t=>P(e,r,{formType:t})})}),(0,i.jsx)(t.at,{icon:t.Fr,title:`After sending`,description:`What happens the moment someone sends this form.`,children:(0,i.jsx)(t.ft,{label:`Where to send them next`,hint:`Leave this empty to show a thank-you message instead. Or give a web address, like /pricing, to take them there.`,value:r.redirectTo||``,placeholder:`/pricing`,onChange:t=>N(e,r,{redirectTo:t}),onBlur:()=>F(e)})}),(0,i.jsxs)(t.at,{icon:t.ti,title:`Questions`,description:`Everything this form asks for, in the order people answer it.`,actions:({open:n})=>(0,i.jsx)(t.Q,{icon:t.Hr,compact:!0,title:`Add a question`,onClick:()=>{n(),I(e,r,[...s,Ks()])},children:`Add question`}),children:[s.length===0?(0,i.jsx)(`p`,{className:`text-[12.5px] text-foreground/55 font-medium leading-relaxed`,children:`No questions yet. Add the first one with the button above.`}):s.map((t,n)=>V(e,r,t,n,s)),s.length>0&&(0,i.jsx)(`div`,{className:`flex justify-start`,children:(0,i.jsx)(t.Q,{icon:t.Hr,onClick:()=>I(e,r,[...s,Ks()]),children:`Add question`})})]}),(c||!a)&&(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 pt-1`,children:[c&&(0,i.jsx)(t.Q,{icon:t.Lr,tone:`danger`,compact:!0,title:`Reset this form`,onClick:()=>w({kind:`reset`,id:e}),children:`Reset this form`}),!a&&(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Delete this form`,onClick:()=>w({kind:`delete`,id:e}),children:`Delete this form`})]})]})};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(we,{children:`Forms`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/forms`,B?`/${B}`:``]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsxs)(`div`,{className:`flex flex-col glass-panel border-y sm:border border-[var(--panel-border)] rounded-none sm:rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background -mx-4 sm:mx-0`,children:[(0,i.jsx)(`div`,{className:`flex items-start justify-between gap-3 sm:gap-6 mb-4 pb-4 md:mb-4 md:pb-5 border-b border-[var(--panel-border)]/50 relative z-10 shrink-0 px-4 pt-5 sm:px-6 sm:pt-6 md:px-10 md:pt-8 bg-background/50`,children:(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-lg md:text-xl font-extrabold text-foreground tracking-tight leading-tight md:leading-7`,children:`Your forms`}),(0,i.jsxs)(`p`,{className:`text-[12.5px] md:text-[14px] font-medium text-foreground/60 mt-1 md:mt-2 leading-relaxed`,children:[(0,i.jsx)(`span`,{className:`md:hidden`,children:`Look a form over and touch it up. Answers arrive in your Inbox.`}),(0,i.jsx)(`span`,{className:`max-md:hidden`,children:`Look a form over and touch it up — its name, button text and questions. New forms are made on the Pages screen, with their page. Answers arrive in your Inbox.`})]})]})}),(0,i.jsx)(`div`,{className:`p-4 sm:p-6 md:px-8 md:pb-8 md:pt-3 flex flex-col gap-4 overflow-y-auto`,children:Object.keys(l).length===0&&!d?(0,i.jsx)(`div`,{className:`flex flex-col gap-4`,children:(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center gap-3 p-10 glass-panel rounded-3xl border border-[var(--panel-border)] border-dashed`,children:[(0,i.jsx)(t.zr,{className:`w-6 h-6 text-foreground/40`}),(0,i.jsx)(`p`,{className:`text-[13px] font-bold text-foreground/60`,children:`You have no forms yet.`}),(0,i.jsx)(`p`,{className:`text-[12.5px] text-foreground/55 font-medium leading-relaxed text-center max-w-md`,children:qs.firstForm})]})}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsx)(t.pr,{children:Object.entries(l).map(([e,n])=>{let r=D[e]||n,a=x[e],o=p[e],s=(r.fields||[]).length;return(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},exit:{opacity:0,y:-12},transition:{duration:.35,ease:`easeOut`},onClick:()=>z(e),className:`group flex flex-col p-3 px-4 glass-panel border transition-all rounded-2xl hover:shadow-sm cursor-pointer hover:border-accent/40 ${a?`border-[var(--panel-border)] bg-background/50`:`border-transparent hover:border-[var(--panel-border)]`} flex-shrink-0 ${r.enabled===!1?`opacity-40 grayscale bg-foreground/[0.01] border-[var(--panel-border)]/50`:``}`,children:[(0,i.jsxs)(`div`,{className:`flex flex-row justify-between w-full gap-2 ${y?`items-start`:`items-center`}`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-1 min-w-0 flex-1 pr-2 sm:pr-4`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`h3`,{className:`text-[14px] font-bold text-foreground break-words ml-1 leading-snug`,children:r.title||`Untitled form`}),o&&(0,i.jsx)(t.ei,{className:`w-3 h-3 animate-spin text-accent ml-2 shrink-0`})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 mt-1.5 ml-1`,children:[(0,i.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 text-[11px] font-semibold px-2.5 py-[3px] rounded-full border shrink-0 ${r.formType===`private`?`text-blue-500 border-blue-500/25 bg-blue-500/[0.07]`:`text-emerald-500 border-emerald-500/25 bg-emerald-500/[0.07]`}`,children:[(0,i.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full shrink-0 ${r.formType===`private`?`bg-blue-500`:`bg-emerald-500`}`}),Hs[r.formType||`public`]]}),(0,i.jsx)(`span`,{className:`max-sm:hidden text-[11px] font-medium text-foreground/45`,children:s===1?`1 question`:`${s} questions`})]})]}),y?(0,i.jsxs)(`div`,{className:`flex items-center gap-0.5 shrink-0 -mt-0.5 -mr-1.5`,children:[(0,i.jsx)(`button`,{type:`button`,title:`Preview this form`,"aria-label":`Preview this form`,onClick:e=>{e.stopPropagation(),g(r)},className:`w-8 h-8 flex items-center justify-center rounded-lg text-foreground/40 hover:text-accent hover:bg-foreground/5 transition-colors cursor-pointer`,children:(0,i.jsx)(t.hi,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{type:`button`,title:a?`Close this form`:`Open this form`,"aria-label":a?`Close this form`:`Open this form`,"aria-expanded":a,onClick:t=>{t.stopPropagation(),z(e)},className:`w-8 h-8 flex items-center justify-center rounded-lg text-foreground/40 hover:text-accent hover:bg-foreground/5 transition-colors cursor-pointer`,children:(0,i.jsx)(t.Pi,{className:`w-4 h-4 transition-transform duration-300 ${a?`rotate-180`:``}`})})]}):(0,i.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,i.jsx)(t.Q,{icon:t.hi,title:`Preview this form`,onClick:e=>{e.stopPropagation(),g(r)},children:`Preview`}),(0,i.jsx)(`button`,{type:`button`,title:a?`Close this form`:`Open this form`,"aria-label":a?`Close this form`:`Open this form`,"aria-expanded":a,onClick:t=>{t.stopPropagation(),z(e)},className:`w-9 h-9 flex items-center justify-center rounded-[var(--btn-radius,0.75rem)] text-foreground/40 hover:text-accent hover:bg-foreground/[0.06] transition-colors cursor-pointer`,children:(0,i.jsx)(t.Pi,{className:`w-4 h-4 transition-transform duration-300 ${a?`rotate-180`:``}`})})]})]}),(0,i.jsx)(t.pr,{children:a&&(0,i.jsx)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden mt-4 pt-4 border-t border-[var(--panel-border)]/50`,onClick:e=>e.stopPropagation(),children:H(e,n)})})]},n._uiKey||e)})}),d&&(0,i.jsxs)(`div`,{className:`flex items-center justify-center gap-3 p-6 glass-panel rounded-2xl border border-[var(--panel-border)]/40 bg-foreground/[0.01] mt-2 animate-pulse`,children:[(0,i.jsx)(t.ei,{className:`w-4 h-4 animate-spin text-accent`}),(0,i.jsx)(`span`,{className:`text-[12px] font-bold text-foreground/50 tracking-wider uppercase select-none`,children:`Loading your forms`})]})]})})]})]}),(0,i.jsx)(He,{isOpen:!!C,onCancel:()=>w(null),onConfirm:()=>{C&&(C.kind===`delete`?L(C.id):R(C.id))},title:C?.kind===`reset`?`Reset this form`:`Delete this form`,message:C?.kind===`reset`?`Undo every change made to ${l[C.id]?.title||C.id} and put it back the way it shipped. Answers already collected are kept.`:`Permanently delete ${C?l[C.id]?.title||C.id:``}. This cannot be undone. Answers already collected are kept.`,confirmText:C?.kind===`reset`?`Reset form`:`Delete form`,isProcessing:T}),h&&(0,i.jsx)(t.t,{formConfig:h,onClose:()=>g(null)})]})}function Xs({product:e,live:n,open:r,onToggle:a,onChange:o,onProceed:s}){let c=t=>o({...e,...t});if(!Yn(e,n))return(0,i.jsx)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] opacity-50`,"aria-disabled":`true`,children:(0,i.jsxs)(`div`,{className:`w-full flex items-center justify-between gap-3 px-4 py-3`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/60 truncate`,children:Qn(e)}),(0,i.jsx)(t.lt,{state:`off`,label:`Finish it above first`})]})});let l=dr(e),u=e.kind===`subscription`;return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:a,"aria-expanded":r,className:`w-full flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Qn(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(t.lt,{state:l?`off`:`saved`,label:l?`Question left`:`Described`}),(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${r?`rotate-180`:``}`})]})]}),r&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.dt,{label:`How will this payment work?`,hint:u?`Start to finish, in your own words — what someone does, pays, and gets. Worth saying if you care: what they tell you before paying (never their email — Stripe asks for that), what each plan unlocks, and what happens the moment they subscribe. Whatever you skip, your assistant decides.`:`Start to finish, in your own words — what someone does, pays, and gets. Worth saying if you care: what they tell you before paying (never their email — Stripe asks for that) and what happens after they pay. Whatever you skip, your assistant decides.`,value:e.how,onChange:e=>c({how:e}),placeholder:u?`People pick a plan and pay, and their member area unlocks the same minute — Basic gets the videos, Pro gets the videos and a monthly call.`:`People pick a time, tell me their phone number and what they need, pay, and the booking is theirs — it appears under Bookings with the session they chose.`}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5`,children:[(0,i.jsx)(t.mt,{label:`Email the buyer a confirmation`,hint:`Needs email set up on this screen.`,hintWideOnly:!0,enabled:e.emailReceipt,onChange:e=>c({emailReceipt:e})}),(0,i.jsx)(t.mt,{label:`Email me when someone buys`,hint:`Needs email set up on this screen.`,hintWideOnly:!0,enabled:e.notifyOwner,onChange:e=>c({notifyOwner:e})})]}),(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:[l?(0,i.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:l}):(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Described — press Proceed to say where it goes.`}),l?(0,i.jsx)(`span`,{}):(0,i.jsx)(t.Q,{icon:t.Ki,onClick:s,children:`Proceed`})]})]})]})}function Zs({products:e,live:n,openId:r,onToggle:a,onChange:o,onProceed:s}){return e===null?(0,i.jsx)(`p`,{className:t.$,children:`Loading your payments…`}):e.length===0?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Nothing here yet. Describe what you sell in the card above — each payment you add appears here with one question: how it works, start to finish.`}):(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.map(e=>(0,i.jsx)(Xs,{product:e,live:n,open:r===e.id,onToggle:()=>a(e.id),onChange:o,onProceed:()=>s(e.id)},e.id))})}var Qs=[{audience:`public`,label:`Pages for anyone`},{audience:`user`,label:`Pages for signed-in users`},{audience:`internal`,label:`Pages for your team`},{audience:`admin`,label:`Pages for admins only`}];function $s({row:e,on:n,onToggle:r}){return(0,i.jsxs)(`button`,{type:`button`,role:`checkbox`,"aria-checked":n,"aria-label":`${e.title} — ${e.path}`,onClick:r,className:`w-full flex items-center gap-2.5 px-2 py-2 text-left cursor-pointer rounded-xl hover:bg-foreground/[0.04] transition-colors`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${n?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:n&&(0,i.jsx)(t.Fi,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate min-w-0`,children:e.title}),(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/40 truncate shrink-0`,children:e.path})]})}function ec({product:e,pageRows:n,live:r,open:a,onToggle:o,onChange:s}){let l=t=>s({...e,...t});if(!(Yn(e,r)&&!dr(e)))return(0,i.jsx)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] opacity-50`,"aria-disabled":`true`,children:(0,i.jsxs)(`div`,{className:`w-full flex items-center justify-between gap-3 px-4 py-3`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/60 truncate`,children:Qn(e)}),(0,i.jsx)(t.lt,{state:`off`,label:`Describe it above first`})]})});let u=hr(e,n);return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:o,"aria-expanded":a,className:`w-full flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Qn(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(t.lt,{state:u?`off`:`saved`,label:u?`Where does it go?`:`Placed`}),(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${a?`rotate-180`:``}`})]})]}),a&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.Z,{label:`Which pages does it go on?`,hint:`Tick every page this payment touches — where it sells, and where your team sees what it sold.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[Qs.map(t=>{let r=n.filter(e=>(e.audience||`public`)===t.audience);return r.length?(0,i.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-widest text-foreground/40 px-1`,children:t.label}),(0,i.jsx)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60 px-2 py-1.5`,children:r.map(t=>(0,i.jsx)($s,{row:t,on:pr(e,t),onToggle:()=>l({pageIds:mr(e,t)})},t.id))})]},t.audience):null}),(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Pages you make on the`,` `,(0,i.jsx)(c.Link,{to:`/pages`,className:`text-accent font-bold hover:underline`,children:`Pages screen`}),` `,`appear here on their own.`]})]})}),(0,i.jsx)(t.dt,{label:`What should appear there?`,hint:`Optional — where the button goes, what surrounds it, what your team sees. Or a page to add, and who will see it: anyone, signed-in users, your team, or admins only. Whatever you skip, your assistant decides.`,value:e.pagesNote,onChange:e=>l({pagesNote:e}),placeholder:`On the home page, a Book button under each call. On the Sales page, every booking as a row — who, what, when.`}),(0,i.jsx)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:u?(0,i.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:u}):(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Placed — the request under these carries it.`})})]})]})}function tc({products:e,pageRows:n,live:r,openId:a,onToggle:o,onChange:s}){if(e===null||n===null)return(0,i.jsx)(`p`,{className:t.$,children:`Loading your pages…`});if(e.length===0)return(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Nothing here yet. Each payment you describe above appears here with one question: which pages it goes on.`});let c=gr(e,n,r),l=c?``:Tr(e,n,r);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.map(e=>(0,i.jsx)(ec,{product:e,pageRows:n,live:r,open:a===e.id,onToggle:()=>o(e.id),onChange:s},e.id))}),(0,i.jsx)(at,{title:`Copy this to wire everything in`,prompt:l,locked:l===``}),c?(0,i.jsx)(`span`,{className:t.$,children:c}):(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Ready — copy the request above into your assistant’s chat. Change any page later from its row on the Pages screen.`})]})}function nc({title:e,path:n,hint:a}){let[o,s]=(0,r.useState)(!1),c=t.Pt(n);return(0,i.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-2.5 rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)]`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/80 truncate`,children:e}),(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 truncate`,children:a||c})]}),(0,i.jsx)(t.Q,{icon:o?t.Fi:t.Si,compact:!0,title:`Copy the link to ${e}`,onClick:()=>{try{navigator.clipboard?.writeText(c)?.catch(()=>{})}catch{}s(!0),setTimeout(()=>s(!1),1500)},children:o?`Copied`:`Copy link`})]})}var rc=e=>ma(`pay-${Zn(e)}`)||`pay-${e.id}`,ic=e=>{let t=zn(e).map(e=>e.amount.trim()).filter(Boolean).join(` + `);return`${Zn(e)}${t?` — ${t}`:``}`};function ac(e,t,n){return[qa(t,n),`This page is the page of my payment link for ${Zn(e)} — everyone I send ${t.path} to lands here and pays here.`,...ar(e,t.path)].join(`
|
|
15
|
+
`)}function oc({product:e,open:n,onToggle:a,onChange:o,onRemove:s,onCustomise:c}){let[l,u]=(0,r.useState)(!1),[d,f]=(0,r.useState)(!1),[p,m]=(0,r.useState)(``),[h,g]=(0,r.useState)(``),_=e.customPath.trim(),v=_?_.startsWith(`/`)?_:`/${_}`:t.kn(e.id);return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 pr-3`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:a,"aria-expanded":n,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:ic(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(t.lt,{state:_?`saved`:`off`,label:_?`Your own page`:`Ready-made page`}),(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${n?`rotate-180`:``}`})]})]}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove the link to ${Zn(e)}`,onClick:()=>u(!0),children:`Remove`})]}),(0,i.jsx)(He,{isOpen:l,title:`Remove the link to ${Zn(e)}?`,message:`Its link stops working, and it leaves What you sell and every schedule it was attached to.`,confirmText:`Yes, remove it`,cancelText:`Keep it`,onCancel:()=>u(!1),onConfirm:()=>{u(!1),s()}}),n&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.Z,{label:`The link`,hint:`Send it to anyone. The page wears your theme and your app's name.`,children:(0,i.jsx)(nc,{title:Zn(e),path:v})}),(0,i.jsx)(t.ft,{label:`What is it called?`,value:zn(e)[0]?.name||``,onChange:t=>o({...e,items:[{...zn(e)[0]||{amount:``},name:t},...zn(e).slice(1)]}),placeholder:`A one-hour session`}),(0,i.jsx)(t.dt,{label:`A line or two about it`,hint:`Optional — what the buyer gets. Shown on the page.`,value:e.description,onChange:t=>o({...e,description:t}),placeholder:`One hour together on whatever you are stuck on.`}),(0,i.jsx)(t.ft,{label:`The price`,value:zn(e)[0]?.amount||``,onChange:t=>o({...e,items:[{...zn(e)[0]||{name:``},amount:t},...zn(e).slice(1)]}),placeholder:`25`,error:zn(e)[0]?.amount.trim()&&Bn(zn(e)[0].amount)===null?`Just a number, like 25.`:void 0}),!_&&!d&&!p&&(0,i.jsx)(t.Q,{icon:t.yr,onClick:()=>f(!0),children:`Customise this page`}),(d||p)&&(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-4`,children:[(0,i.jsx)(t.dt,{label:`What would you like on the page?`,hint:`Describe the page in your own words — what it says, what it shows, how it feels. Your assistant builds it; whatever you skip, it decides.`,value:e.customNote,onChange:t=>o({...e,customNote:t}),placeholder:`A warm page about the session: who it is for, what we cover, two testimonials, then the Pay button.`,rows:3}),h&&(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:h}),p?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(at,{title:`Ask your assistant`,description:`The page exists on the Pages screen now. Paste this into your assistant's chat; once it has built the page, tick the switch below and the link goes there.`,prompt:p}),(0,i.jsx)(t.mt,{label:`The page is built — send people there`,hint:`Until this is on, the link opens the ready-made page.`,enabled:!!e.customPath.trim(),onChange:t=>o({...e,customPath:t?`/${rc(e)}`:``})})]}):(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(t.Q,{icon:t.yr,disabled:!e.customNote.trim(),onClick:async()=>{g(``);let e=await c();if(typeof e==`string`){g(e);return}m(e.prompt)},children:`Make the page`}),(0,i.jsx)(t.Q,{onClick:()=>{f(!1),g(``)},children:`Never mind`})]})]}),_&&!p&&(0,i.jsx)(t.mt,{label:`The page is built — send people there`,hint:`The link opens ${v}. Change the page from its row on the Pages screen. Turn this off to go back to the ready-made page.`,enabled:!0,onChange:t=>o({...e,customPath:t?e.customPath:``})})]})]})}function sc({products:e,onChange:n,onRemove:a}){let[o,s]=(0,r.useState)(null),c=e.filter(e=>e.kind===`once`),l=()=>{let e={...Rn(`p_${Date.now().toString(36)}`),kind:`once`,items:[{name:``,amount:``}]};n(e),s(e.id)},u=async e=>{let t=rc(e),n=`Pay — ${Zn(e)}`,r={name:n,address:t,type:`public`,about:e.customNote.trim()};try{await _a(r)}catch(e){return console.error(`Could not make the page`,e),`The page could not be made — make sure you are signed in as an admin and try again.`}let{config:i}=ga(r),a={title:n,path:`/${t}`};return{path:a.path,prompt:ac(e,a,i)}};return(0,i.jsx)(t.at,{icon:t.ri,title:`Payment links`,description:`Every one-time payment has a page of its own you can send to anyone — a name, a line about it, a price.`,actions:({open:e})=>(0,i.jsx)(t.Q,{icon:t.Hr,title:`Add a payment link`,onClick:()=>{e(),l()},children:`Add a payment link`}),children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:c.length===0?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`No payment link yet. Add one here — it appears under What you sell too — or describe a one-time payment there and its link shows up here.`}):c.map(e=>(0,i.jsx)(oc,{product:e,open:o===e.id,onToggle:()=>s(o===e.id?null:e.id),onChange:n,onRemove:()=>a(e.id),onCustomise:()=>u(e)},e.id))})})}var cc=e=>e.trim()&&Bn(e)===null?`Just a number, like 25.`:void 0,lc=e=>/^price_[A-Za-z0-9]+$/.test(e.trim());function uc({item:e,index:n,onChange:r,onRemove:a,removable:o}){let s=cc(e.amount);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`text`,value:e.name,onChange:t=>r({...e,name:t.target.value}),placeholder:n===0?`A one-hour call`:`A two-hour call`,"aria-label":`Thing ${n+1} — its name`,className:`${t.et} flex-1 min-w-0`}),(0,i.jsx)(`input`,{type:`text`,inputMode:`decimal`,value:e.amount,onChange:t=>r({...e,amount:t.target.value}),placeholder:`25`,"aria-label":`Thing ${n+1} — its price`,className:`${t.et} w-24! shrink-0 text-right ${s?`border-red-500/50`:``}`}),o&&(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${e.name.trim()||`thing ${n+1}`}`,onClick:a,children:`Remove`})]}),s&&(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:s})]})}function dc({plan:e,index:n,onChange:r,onRemove:a}){let o=t=>r({...e,...t});return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-4`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,i.jsxs)(`span`,{className:`text-[11px] font-bold uppercase tracking-widest text-foreground/40`,children:[`Plan `,n+1]}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove this plan`,onClick:a,children:`Remove plan`})]}),(0,i.jsx)(t.ft,{label:`What is this plan called?`,value:e.name,onChange:e=>o({name:e}),placeholder:`Basic`}),(0,i.jsx)(t.ft,{label:`One line about it`,hint:`Optional — what a buyer gets on this plan.`,value:e.description,onChange:e=>o({description:e}),placeholder:`Up to 3 projects and email support`}),[[`monthly`,`Billed monthly`,`a month`],[`yearly`,`Billed yearly`,`a year`]].map(([r,a,s])=>(0,i.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 ml-1`,children:a}),(0,i.jsx)(t.pt,{enabled:e[r].on,onChange:t=>o({[r]:{...e[r],on:t}}),label:`${a} — plan ${n+1}`})]}),e[r].on&&(0,i.jsx)(t.ft,{label:`The price ${s}`,hint:`Just the number — 25 charges 25 ${s} in your Stripe account's currency.`,value:e[r].amount,onChange:t=>o({[r]:{...e[r],amount:t}}),placeholder:r===`monthly`?`25`:`250`,error:cc(e[r].amount)})]},r))]})}function fc({product:e,plan:n,index:r,live:a,onChange:o}){let s=a?`livePriceId`:`priceId`,c=(e,t)=>({...e,[s]:t}),l=(!n.monthly.on||lc(n.monthly[s]))&&(!n.yearly.on||lc(n.yearly[s])),u=e=>o({...n,...e}),d=e=>e.trim()&&!lc(e)?`A price id starts with price_ — copy it from the price you just made.`:void 0;return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:n.name.trim()||`Plan ${r+1}`}),(0,i.jsx)(t.lt,{state:l?`saved`:`off`,label:l?`Done`:a?`Waiting for its live ids`:`Waiting for its ids`})]}),(0,i.jsx)(`ol`,{className:`space-y-1.5 list-decimal list-inside text-[12.5px] font-medium text-foreground/60 leading-relaxed`,children:$n(e,n,a).map((e,t)=>(0,i.jsx)(`li`,{children:e},t))}),n.monthly.on&&(0,i.jsx)(t.ft,{label:a?`Paste the live monthly price id`:`Paste the monthly price id`,value:n.monthly[s],onChange:e=>u({monthly:c(n.monthly,e)}),placeholder:`price_…`,error:d(n.monthly[s])}),n.yearly.on&&(0,i.jsx)(t.ft,{label:a?`Paste the live yearly price id`:`Paste the yearly price id`,value:n.yearly[s],onChange:e=>u({yearly:c(n.yearly,e)}),placeholder:`price_…`,error:d(n.yearly[s])}),a&&(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:`Your test ids are kept — switch back to test mode on this screen and they are exactly where you left them.`})]})}function pc({product:e,open:n,live:a,onToggle:o,onChange:s,onRemove:c,onProceed:l}){let u=t=>s({...e,...t}),d=(t,n)=>u({plans:e.plans.map((e,r)=>r===t?n:e)}),f=Yn(e,a),p=Jn(e,a),[m,h]=(0,r.useState)(!1),g=Zn(e);return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 pr-3`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:o,"aria-expanded":n,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Qn(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[e.kind&&(0,i.jsx)(t.lt,{state:f?`saved`:`off`,label:f?`Ready`:`In progress`}),(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${n?`rotate-180`:``}`})]})]}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${g}`,onClick:()=>h(!0),children:`Remove`})]}),(0,i.jsx)(He,{isOpen:m,title:`Remove ${g}?`,message:`Its answer under How your payments work and its pages under Wire it into your pages go with it, and the request stops carrying it.`,confirmText:`Yes, remove it`,cancelText:`Keep it`,onCancel:()=>h(!1),onConfirm:()=>{h(!1),c()}}),n&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.ct,{label:`How is it paid?`,value:e.kind,onChange:t=>u({kind:t===`once`||t===`subscription`?t:``,plans:t===`subscription`&&!e.plans.length?[In()]:e.plans,items:t===`once`&&!e.items.length?[Ln()]:e.items}),options:[{value:`once`,label:`Once — one payment`},{value:`subscription`,label:`A subscription that renews`}],placeholder:`Choose one`}),e.kind===`once`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.Z,{label:`What are you selling?`,hint:`Each thing with its price — just the number: 25 charges 25 in your Stripe account's currency. Nothing to make in Stripe for a one-off.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.items.map((t,n)=>(0,i.jsx)(uc,{item:t,index:n,onChange:t=>u({items:e.items.map((e,r)=>r===n?t:e)}),onRemove:()=>u({items:e.items.filter((e,t)=>t!==n)}),removable:e.items.length>1},n)),(0,i.jsx)(t.Q,{icon:t.Hr,className:`self-start`,onClick:()=>u({items:[...e.items,Ln()]}),children:`Add another`})]})}),e.items.length>1&&(0,i.jsx)(t.ft,{label:`What do you call this group?`,hint:`Optional — one word for the lot, the way you would say it: Calls, The shop.`,value:e.name,onChange:e=>u({name:e}),placeholder:`Calls`})]}),e.kind===`subscription`&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.ft,{label:`What is the subscription called?`,value:e.name,onChange:e=>u({name:e}),placeholder:`Membership`}),(0,i.jsx)(t.dt,{label:`One line about it`,hint:`Optional — your assistant uses it on the page.`,value:e.description,onChange:e=>u({description:e}),placeholder:`Everything in the studio, every month.`}),(0,i.jsx)(t.Z,{label:`Its plans`,hint:`Each plan can be billed monthly, yearly, or both.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.plans.map((t,n)=>(0,i.jsx)(dc,{plan:t,index:n,onChange:e=>d(n,e),onRemove:()=>u({plans:e.plans.filter((e,t)=>t!==n)})},n)),(0,i.jsx)(t.Q,{icon:t.Hr,className:`self-start`,onClick:()=>u({plans:[...e.plans,In()]}),children:`Add a plan`})]})}),Xn(e)&&(0,i.jsx)(t.Z,{label:a?`Now make it in Stripe — live mode`:`Now make it in Stripe`,hint:a?`Live mode is a fresh Stripe catalogue: make each plan again with Test mode OFF, and paste the live ids it produces.`:`Five minutes in your Stripe dashboard. Each plan below says exactly what to do and takes the id it produces.`,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.plans.map((t,n)=>(0,i.jsx)(fc,{product:e,plan:t,index:n,live:a,onChange:e=>d(n,e)},n))})})]}),(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:[e.kind&&!f?(0,i.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:p}):e.kind?(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Ready — press Proceed to say how it works.`}):(0,i.jsx)(`span`,{}),f?(0,i.jsx)(t.Q,{icon:t.Ki,onClick:l,children:`Proceed`}):(0,i.jsx)(`span`,{})]})]})]})}function mc(){let[e,n]=(0,r.useState)(null),[a,s]=(0,r.useState)(!1),[c,l]=(0,r.useState)(null),[u,d]=(0,r.useState)(null),[f,p]=(0,r.useState)(null),[m,h]=(0,r.useState)(``),g=(0,r.useRef)(new Map),_=(0,r.useRef)(null),v=(0,r.useRef)(null),y=Br();(0,r.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(t.Ca,Nn),e=>{let t=!!e.docs.find(e=>e.id===Pn)?.data()?.liveMode;if(s(t),Ar(t),g.current.size)return;let r=[];e.forEach(e=>{e.id!==`_settings`&&r.push(Gn(e.id,e.data()))}),r.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)),n(r)},()=>n([]));return()=>e()},[]);let b=e=>{let n=g.current.get(e.id);n&&clearTimeout(n),g.current.set(e.id,setTimeout(async()=>{g.current.delete(e.id);try{let{id:n,...r}=e;await(0,o.setDoc)((0,o.doc)(t.Ca,Nn,n),r)}catch(e){console.error(`Could not save the product`,e)}},600))},x=e=>{n(t=>{let n=t||[];return n.some(t=>t.id===e.id)?n.map(t=>t.id===e.id?e:t):[...n,e]}),b(e)},S=()=>{let e=Rn(`p_${Date.now().toString(36)}`);n(t=>[...t||[],e]),l(e.id),b(e)},C=async r=>{let i=g.current.get(r);i&&(clearTimeout(i),g.current.delete(r));let a=(e||[]).find(e=>e.id===r);h(``),n(e=>(e||[]).filter(e=>e.id!==r)),c===r&&l(null),u===r&&d(null),f===r&&p(null);try{await(0,o.deleteDoc)((0,o.doc)(t.Ca,Nn,r))}catch(e){console.error(`Could not remove the product`,e),a&&n(e=>{let t=e||[];return t.some(e=>e.id===r)?t:[...t,a].sort((e,t)=>(e.createdAt||0)-(t.createdAt||0))}),h(`It could not be removed — make sure you are signed in as an admin and try again.`)}},w=e=>{l(null),d(e),_.current?.scrollIntoView({behavior:`smooth`,block:`start`})};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.at,{icon:t.Nr,title:`What you sell`,description:`Things paid for once, each with a price; or a subscription with plans and their Stripe ids.`,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:e===null?(0,i.jsx)(`p`,{className:t.$,children:`Loading what you sell…`}):(0,i.jsxs)(i.Fragment,{children:[e.length===0&&(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug px-1`,children:`Nothing here yet. Describe what you sell once — things paid for once need nothing from Stripe, and a subscription walks you through Stripe step by step — then say how it works in the section below, and where it goes in the last.`}),e.map(e=>(0,i.jsx)(pc,{product:e,open:c===e.id,live:a,onToggle:()=>l(c===e.id?null:e.id),onChange:x,onRemove:()=>C(e.id),onProceed:()=>w(e.id)},e.id)),!!m&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:m}),(0,i.jsx)(t.Q,{icon:t.Hr,className:`self-start`,onClick:S,children:`Add something you sell`})]})})}),(0,i.jsx)(`div`,{ref:_,children:(0,i.jsx)(t.at,{icon:t.vr,title:`How your payments work`,description:`One answer per payment: what someone does, pays, and gets. Which pages it goes on is the next card.`,children:(0,i.jsx)(Zs,{products:e,live:a,openId:u,onToggle:e=>d(u===e?null:e),onChange:x,onProceed:e=>{d(null),p(e),v.current?.scrollIntoView({behavior:`smooth`,block:`start`})}})})}),(0,i.jsx)(`div`,{ref:v,children:(0,i.jsx)(t.at,{icon:t.Ur,title:`Wire it into your pages`,description:`Each payment: tick the pages it goes on, say what should appear there — then copy one request that wires all of it.`,children:(0,i.jsx)(tc,{products:e,pageRows:y,live:a,openId:f,onToggle:e=>p(f===e?null:e),onChange:x})})}),(0,i.jsx)(sc,{products:e||[],onChange:x,onRemove:C})]})}var hc=r.default.createContext({}),gc=Object.defineProperty,_c=Object.getOwnPropertySymbols,vc=Object.prototype.hasOwnProperty,yc=Object.prototype.propertyIsEnumerable,bc=(e,t,n)=>t in e?gc(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,xc=(e,t)=>{for(var n in t||={})vc.call(t,n)&&bc(e,n,t[n]);if(_c)for(var n of _c(t))yc.call(t,n)&&bc(e,n,t[n]);return e},Sc=(0,r.forwardRef)((e,t)=>{let n=xc(xc({},r.useContext(hc)),e);return r.createElement(`svg`,xc({width:`1.5em`,height:`1.5em`,viewBox:`0 0 24 24`,strokeWidth:1.5,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,color:`currentColor`,ref:t},n),r.createElement(`path`,{d:`M22 12C22 17.5228 17.5228 22 12 22C10.1786 22 8.47087 21.513 7 20.6622L2 21.5L2.83209 16C2.29689 14.7751 2 13.4222 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`}),r.createElement(`path`,{d:`M12.9604 13.8683L15.0399 13.4624L17 14.2149V16.0385C17 16.6449 16.4783 17.1073 15.8901 16.9783C14.3671 16.6444 11.5997 15.8043 9.67826 13.8683C7.84859 12.0248 7.22267 9.45734 7.01039 8.04128C6.92535 7.47406 7.3737 7 7.94306 7H9.83707L10.572 8.96888L10.1832 11.0701`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`}))}),Cc=`aistudio`;function wc(){return Cc}function Tc(){let[e,t]=(0,r.useState)(wc);return[e,(0,r.useCallback)(e=>{t(e)},[])]}var Ec=`Set this project up for Your AI Firebase, and do only what is listed here.
|
|
29
16
|
|
|
30
17
|
1. If there is no app in this folder yet, create a Vite + React + TypeScript app in it.
|
|
31
18
|
2. Delete the starter demo — the counter, the logos, App.css, the sample markup. None of the template's own content stays.
|
|
@@ -60,7 +47,7 @@ GEMINI_API_KEY=""
|
|
|
60
47
|
Do not add routes to server.ts. Every route lives inside the package, so new features arrive with a version bump and this file never changes again.
|
|
61
48
|
7. Start it with npm run dev and tell me the address it prints.
|
|
62
49
|
|
|
63
|
-
Then stop. Do not build pages, write content files or change the theme — the app opens on its own Setup screen and carries on from there.`,
|
|
50
|
+
Then stop. Do not build pages, write content files or change the theme — the app opens on its own Setup screen and carries on from there.`,Dc=`fbos-setup-done`;function Oc(){try{localStorage.setItem(Dc,`yes`)}catch{}}var kc=`rules_version = '2';
|
|
64
51
|
service cloud.firestore {
|
|
65
52
|
match /databases/{database}/documents {
|
|
66
53
|
|
|
@@ -412,7 +399,7 @@ service cloud.firestore {
|
|
|
412
399
|
}
|
|
413
400
|
}
|
|
414
401
|
}
|
|
415
|
-
`,
|
|
402
|
+
`,Ac=`rules_version = '2';
|
|
416
403
|
service firebase.storage {
|
|
417
404
|
match /b/{bucket}/o {
|
|
418
405
|
|
|
@@ -576,15 +563,20 @@ service firebase.storage {
|
|
|
576
563
|
&& resource != null
|
|
577
564
|
&& hasOwnerMeta(resource)
|
|
578
565
|
&& resource.metadata.ownerId == request.auth.uid;
|
|
566
|
+
// Deleting follows the record, not the uploader. Since 1.14.6 every team
|
|
567
|
+
// member may delete every mem_ record, whoever added it, and the record
|
|
568
|
+
// is the only place the file's link lives — so a delete that stopped at
|
|
569
|
+
// the uploader left the file stranded behind a record already gone, out
|
|
570
|
+
// of everybody's reach and still on the owner's bill. Overwriting a file
|
|
571
|
+
// in place (update, above) stays the uploader's: nothing in the app does
|
|
572
|
+
// it, and it would change what a colleague's link serves.
|
|
579
573
|
allow delete: if folder.matches('^mem_.*')
|
|
580
|
-
&& isInternal()
|
|
581
|
-
&& resource != null
|
|
582
|
-
&& hasOwnerMeta(resource)
|
|
583
|
-
&& resource.metadata.ownerId == request.auth.uid;
|
|
574
|
+
&& isInternal();
|
|
584
575
|
|
|
585
576
|
// A page kept for one of your own roles — the same shape as mem_ above:
|
|
586
|
-
// everybody marked with the role reads every file there
|
|
587
|
-
// them
|
|
577
|
+
// everybody marked with the role reads every file there and may delete
|
|
578
|
+
// any of them, exactly as they may delete any record on the page; each
|
|
579
|
+
// of them may overwrite only what they put up themselves.
|
|
588
580
|
allow read: if isRoleFolder(folder) && hasFolderRole(folder);
|
|
589
581
|
allow create: if isRoleFolder(folder)
|
|
590
582
|
&& hasFolderRole(folder)
|
|
@@ -600,10 +592,7 @@ service firebase.storage {
|
|
|
600
592
|
&& hasOwnerMeta(resource)
|
|
601
593
|
&& resource.metadata.ownerId == request.auth.uid;
|
|
602
594
|
allow delete: if isRoleFolder(folder)
|
|
603
|
-
&& hasFolderRole(folder)
|
|
604
|
-
&& resource != null
|
|
605
|
-
&& hasOwnerMeta(resource)
|
|
606
|
-
&& resource.metadata.ownerId == request.auth.uid;
|
|
595
|
+
&& hasFolderRole(folder);
|
|
607
596
|
|
|
608
597
|
// The team's own public pictures. A booking page carries a photo of the
|
|
609
598
|
// person it is for, and since 1.14.18 that person makes the page
|
|
@@ -641,15 +630,20 @@ service firebase.storage {
|
|
|
641
630
|
&& underSizeCap(10 * 1024 * 1024)
|
|
642
631
|
&& allowedFileType();
|
|
643
632
|
|
|
644
|
-
// User-specific folders
|
|
633
|
+
// User-specific folders. user_avatars starts with user_ too, and until
|
|
634
|
+
// it was named here any verified account could drop a file at the path
|
|
635
|
+
// where somebody else's picture goes; the avatars have their own match
|
|
636
|
+
// above and answer to that alone.
|
|
645
637
|
allow create: if isVerified()
|
|
646
638
|
&& folder.matches('^user_.*')
|
|
639
|
+
&& folder != 'user_avatars'
|
|
647
640
|
&& underSizeCap(10 * 1024 * 1024)
|
|
648
641
|
&& allowedFileType()
|
|
649
642
|
&& hasOwnerMeta(request.resource)
|
|
650
643
|
&& request.resource.metadata.ownerId == request.auth.uid;
|
|
651
644
|
allow update: if isVerified()
|
|
652
645
|
&& folder.matches('^user_.*')
|
|
646
|
+
&& folder != 'user_avatars'
|
|
653
647
|
&& underSizeCap(10 * 1024 * 1024)
|
|
654
648
|
&& allowedFileType()
|
|
655
649
|
&& resource != null
|
|
@@ -669,10 +663,23 @@ service firebase.storage {
|
|
|
669
663
|
}
|
|
670
664
|
}
|
|
671
665
|
}
|
|
672
|
-
`,ku=[{key:`VITE_FIREBASE_API_KEY`,label:`API Key`,shownAs:`apiKey`},{key:`VITE_FIREBASE_AUTH_DOMAIN`,label:`Auth Domain`,shownAs:`authDomain`},{key:`VITE_FIREBASE_PROJECT_ID`,label:`Project ID`,shownAs:`projectId`},{key:`VITE_FIREBASE_STORAGE_BUCKET`,label:`Storage Bucket`,shownAs:`storageBucket`},{key:`VITE_FIREBASE_MESSAGING_SENDER_ID`,label:`Messaging Sender ID`,shownAs:`messagingSenderId`},{key:`VITE_FIREBASE_APP_ID`,label:`App ID`,shownAs:`appId`}];function Au(e){let t;try{if(t={BASE_URL:`/`,DEV:!1,MODE:`production`,PROD:!0,SSR:!1,VITE_ADMIN_EMAILS:void 0,VITE_FIREBASE_API_KEY:void 0,VITE_FIREBASE_APP_ID:void 0,VITE_FIREBASE_AUTH_DOMAIN:void 0,VITE_FIREBASE_MESSAGING_SENDER_ID:void 0,VITE_FIREBASE_PROJECT_ID:void 0,VITE_FIREBASE_STORAGE_BUCKET:void 0}?.[e],t&&typeof t==`string`&&t.trim()!==``)return t}catch{}try{if(t=(typeof window<`u`?window:globalThis)?.process?.env?.[e],t&&typeof t==`string`&&t.trim()!==``)return t}catch{}try{switch(e){case`VITE_FIREBASE_API_KEY`:t=void 0;break;case`VITE_FIREBASE_AUTH_DOMAIN`:t=void 0;break;case`VITE_FIREBASE_PROJECT_ID`:t=void 0;break;case`VITE_FIREBASE_STORAGE_BUCKET`:t=void 0;break;case`VITE_FIREBASE_MESSAGING_SENDER_ID`:t=void 0;break;case`VITE_FIREBASE_APP_ID`:t=void 0;break}if(t&&typeof t==`string`&&t.trim()!==``)return t}catch{}return``}function ju(e,t){let n=Au(e);if(n)return n;if(t?.firebaseConfig){let n={VITE_FIREBASE_API_KEY:`apiKey`,VITE_FIREBASE_AUTH_DOMAIN:`authDomain`,VITE_FIREBASE_PROJECT_ID:`projectId`,VITE_FIREBASE_STORAGE_BUCKET:`storageBucket`,VITE_FIREBASE_MESSAGING_SENDER_ID:`messagingSenderId`,VITE_FIREBASE_APP_ID:`appId`}[e];if(n&&t.firebaseConfig[n])return t.firebaseConfig[n]}return``}function Mu(e){let t=[],n=[],r=t=>ju(t,e);for(let{key:e,label:i}of ku){let a=r(e);a?a.trim()===``&&n.push(i):t.push(i)}let i=[...t,...n];return{allSet:i.length===0,missing:i,empty:n}}function Nu(){return Mu().allSet}var Pu=Ou;function Fu(e){let t=e.map(e=>e.trim().toLowerCase()).filter(Boolean).filter((e,t,n)=>n.indexOf(e)===t),n=t.length?t.map(e=>`'${e.replace(/'/g,``)}'`).join(`, `):`'your@email.com'`;return Du.replace(/(function adminEmails\(\) \{\s*return )\[[^\]]*\];/,`$1[${n}];`)}function Iu(e){return e.split(/[,\s]+/).map(e=>e.trim()).filter(Boolean)}var Lu=/^[^@\s]+@[^@\s]+\.[^@\s]+$/;function Ru({code:e,label:n,compact:a}){let[o,s]=r.default.useState(!1);return(0,i.jsxs)(t.fr.button,{whileHover:{scale:1.02},whileTap:{scale:.98},onClick:()=>{navigator.clipboard?.writeText(e),s(!0),setTimeout(()=>s(!1),2e3)},className:`inline-flex items-center font-bold transition-all shrink-0 cursor-pointer ${a?`gap-1.5 h-9 px-3 rounded-xl text-[12px] self-start sm:self-auto`:`gap-2 px-4 py-2 mt-2 rounded-xl text-[13px] tracking-wide`} ${o?`bg-emerald-500/10 text-emerald-500 border border-emerald-500/20`:`btn-secondary${a?``:` shadow-sm`}`}`,children:[o?(0,i.jsx)(t.zi,{className:a?`w-3.5 h-3.5`:`w-4 h-4`}):(0,i.jsx)(t.Ti,{className:a?`w-3.5 h-3.5`:`w-4 h-4`}),o?a?`Copied`:`Copied to Clipboard!`:n]})}function zu(e){let t=``;try{t=new URL(e).hostname}catch{t=``}let n=t===`localhost`||t===`127.0.0.1`||t.endsWith(`.local`);return{host:t,local:n}}function Bu(){let{host:e,local:t}=zu(typeof window>`u`?``:window.location.href);return e?(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl bg-background flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-3 px-4 py-3 mt-3`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`div`,{className:`text-[13.5px] font-bold text-foreground break-all sm:break-normal sm:truncate`,children:e}),(0,i.jsx)(`div`,{className:`text-[12.5px] text-foreground/50 font-medium`,children:t?`this machine — Firebase trusts it already, nothing to add`:`your app's address, read from this page`})]}),!t&&(0,i.jsx)(Ru,{compact:!0,code:e,label:`Copy the address`})]}):null}function Vu({name:e,shownAs:n,hint:a}){let[o,s]=r.default.useState(!1);return(0,i.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-3 px-4 py-3 border-b border-[var(--panel-border)]/40 last:border-0`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`div`,{className:`text-[13.5px] font-bold text-foreground break-all sm:break-normal sm:truncate`,children:e}),(0,i.jsx)(`div`,{className:`text-[12.5px] text-foreground/50 font-medium`,children:a??(0,i.jsxs)(i.Fragment,{children:[`the value Firebase labels `,n]})})]}),(0,i.jsxs)(`button`,{type:`button`,onClick:()=>{navigator.clipboard?.writeText(e),s(!0),setTimeout(()=>s(!1),2e3)},className:`inline-flex items-center gap-1.5 h-9 px-3 rounded-xl text-[12px] font-bold shrink-0 self-start sm:self-auto transition-all cursor-pointer active:scale-[0.98] ${o?`bg-emerald-500/10 text-emerald-500 border border-emerald-500/20`:`btn-secondary`}`,children:[o?(0,i.jsx)(t.zi,{className:`w-3.5 h-3.5`}):(0,i.jsx)(t.Ti,{className:`w-3.5 h-3.5`}),o?`Copied`:`Copy name`]})]})}var Hu=ku.map(({key:e,shownAs:t})=>e===`VITE_FIREBASE_STORAGE_BUCKET`?{name:e,value:`leave empty`,empty:!0}:{name:e,value:`paste ${t}`});function Uu({name:e,value:n,empty:r}){return(0,i.jsxs)(`div`,{className:`px-3 sm:px-4 py-1.5 flex flex-col gap-1 sm:grid sm:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_2.25rem] sm:gap-3 sm:items-center`,children:[(0,i.jsx)(`div`,{title:e,className:`text-[12.5px] sm:text-[13px] font-semibold text-foreground/80 break-all sm:truncate`,children:e}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 sm:contents`,children:[(0,i.jsx)(`div`,{className:`flex-1 min-w-0 h-9 px-3 flex items-center rounded-xl border text-[12.5px] sm:text-[13px] font-medium ${r?`border-dashed border-accent/40 text-accent`:`border-[var(--panel-border)]/60 text-foreground/45`}`,children:(0,i.jsx)(`span`,{className:`truncate`,children:n})}),(0,i.jsx)(`span`,{"aria-hidden":`true`,className:`w-9 h-9 shrink-0 rounded-xl flex items-center justify-center bg-foreground/[0.05] text-foreground/35`,children:(0,i.jsx)(t.yi,{className:`w-4 h-4`})})]})]})}function Wu(){return(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl overflow-hidden bg-background`,children:[(0,i.jsx)(`div`,{className:`max-sm:hidden sm:grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_2.25rem] gap-3 px-4 pt-3.5 pb-1`,children:[`Name`,`Value`].map(e=>(0,i.jsx)(`span`,{className:`text-[12.5px] font-semibold text-foreground/45`,children:e},e))}),(0,i.jsx)(`div`,{className:`py-2 sm:py-1.5`,children:Hu.map(e=>(0,i.jsx)(Uu,{...e},e.name))}),(0,i.jsx)(`div`,{className:`flex justify-end px-3 sm:px-4 py-3 border-t border-[var(--panel-border)]/40`,children:(0,i.jsx)(`span`,{"aria-hidden":`true`,className:`btn-secondary inline-flex items-center h-9 px-4 rounded-xl text-[12.5px] font-bold select-none`,children:`Apply`})})]})}function Gu(){let[e,n]=(0,r.useState)(``),[a,o]=(0,r.useState)(``),[s,c]=(0,r.useState)([]),[l,u]=(0,r.useState)(``),d=e=>{n(e),a&&(o(``),c([])),l&&u(``)},f=()=>{let t=Iu(e);if(t.length===0){u(`Type an email address first — it is what the rules will name.`);return}let n=t.filter(e=>!Lu.test(e));if(n.length>0){u(`That does not look like an email address: ${n.join(`, `)}`);return}u(``),c(t.map(e=>e.trim().toLowerCase())),o(Fu(t))};return(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl p-5 mb-2 flex flex-col gap-4`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3.5 min-w-0`,children:[(0,i.jsx)(`div`,{className:`w-10 h-10 rounded-2xl flex items-center justify-center shrink-0 border border-[var(--panel-border)]/50 bg-accent/10 text-accent`,children:(0,i.jsx)(t.Fr,{className:`w-5 h-5`})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0`,children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-bold text-foreground tracking-tight leading-tight truncate`,children:`Who runs this app?`}),(0,i.jsx)(`p`,{className:`text-[12px] text-foreground/50 font-normal leading-snug truncate`,children:`The email you sign in with becomes the owner — separate several with commas.`})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`text`,value:e,"aria-label":`The email address you will sign in with`,placeholder:`you@yourcompany.com`,onChange:e=>d(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),f())},className:`w-full h-10 px-3.5 rounded-[var(--input-radius,0.75rem)] border border-[var(--panel-border)] bg-[var(--panel-bg)] text-[13.5px] text-foreground outline-none transition-all duration-300 placeholder:text-foreground/35 hover:border-accent/40 focus:border-accent console-field ${l?`is-invalid border-red-500/60`:``}`}),(0,i.jsx)(`button`,{type:`button`,onClick:f,className:`btn-primary inline-flex items-center justify-center h-10 px-4 rounded-[var(--btn-radius,0.75rem)] text-[12.5px] font-bold text-white shrink-0 cursor-pointer active:scale-[0.98] transition-transform whitespace-nowrap`,children:`Generate the rules`})]}),l&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 leading-snug px-1`,children:l}),a&&(0,i.jsxs)(`div`,{className:`rounded-2xl border border-emerald-500/20 bg-emerald-500/[0.05] px-3.5 py-3 flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-3`,children:[(0,i.jsx)(`span`,{className:`w-7 h-7 rounded-full bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.zi,{className:`w-3.5 h-3.5 text-emerald-500`})}),(0,i.jsxs)(`div`,{className:`min-w-0 flex-1 flex flex-col gap-0.5`,children:[(0,i.jsxs)(`p`,{"data-admin-emails":!0,className:`text-[13px] font-bold text-foreground leading-snug break-all`,children:[`Ready — they make `,s.join(`, `),` the owner.`]}),(0,i.jsx)(`p`,{className:`text-[12px] font-medium text-foreground/50 leading-snug`,children:`Paste them into Firebase, then sign in with that address — or reload, if you already are.`})]}),(0,i.jsx)(Ru,{compact:!0,code:a,label:`Copy the rules`})]})]})}var Ku=`text-accent underline underline-offset-2 font-semibold hover:text-accent-deep transition-colors`;function qu({text:e,label:t}){return(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl bg-background overflow-hidden`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-4 py-3 border-b border-[var(--panel-border)]/40`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-extrabold tracking-tight text-gradient truncate max-sm:hidden`,children:`Paste this into your assistant`}),(0,i.jsx)(Ru,{compact:!0,code:e,label:t})]}),(0,i.jsx)(`pre`,{className:`px-4 py-3 max-h-64 overflow-auto text-[11.5px] leading-relaxed font-mono text-foreground/70 whitespace-pre-wrap [overflow-wrap:anywhere]`,children:e})]})}function Ju({number:e,title:t,aside:n,children:r}){return(0,i.jsxs)(`div`,{className:`flex flex-col relative pb-10 mb-10 border-b border-[var(--panel-border)]/50 last:border-0 last:pb-0 last:mb-0`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3 mb-4`,children:[(0,i.jsx)(`span`,{className:`w-8 h-8 shrink-0 rounded-full bg-accent/10 border border-accent/20 text-accent flex items-center justify-center text-[14px] font-extrabold`,children:e}),(0,i.jsx)(`h3`,{className:`text-[17px] md:text-[19px] font-extrabold text-foreground tracking-tight flex-1 min-w-0`,children:t}),n]}),(0,i.jsx)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/70 leading-relaxed space-y-4`,children:r})]})}function Yu({basename:e}){return(0,i.jsxs)(`div`,{className:`mt-6 sm:mt-8 relative z-10 flex flex-col sm:flex-row sm:items-center gap-4 sm:gap-6 p-5 sm:p-6 rounded-3xl border border-accent/20 bg-accent/[0.06]`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,i.jsx)(`h3`,{className:`text-[16px] sm:text-[17px] font-extrabold text-foreground tracking-tight`,children:`Worked through every step?`}),(0,i.jsx)(`p`,{className:`text-[13px] sm:text-[13.5px] text-foreground/60 font-medium leading-relaxed mt-1`,children:`Your app will start again and take you to sign in. Use the email address you typed into the rules — that is the one this app knows as its owner.`})]}),(0,i.jsxs)(t.fr.button,{type:`button`,whileHover:{scale:1.02},whileTap:{scale:.98},onClick:()=>{Eu();let t=String(e||``).replace(/\/+$/,``);window.location.assign(`${t}/login`)},className:`btn-primary inline-flex items-center justify-center gap-2 h-12 px-6 rounded-[var(--btn-radius,0.75rem)] text-[13.5px] font-bold text-white shrink-0 cursor-pointer whitespace-nowrap shadow-lg`,children:[`I've completed all the steps`,(0,i.jsx)(t.Xi,{className:`w-4 h-4`})]})]})}function Xu({standalone:e}){let n=t.Na(),[a,o]=Cu(),s=a===`local`,c={project:s?2:1,webApp:s?3:2,keys:s?4:3,signIn:s?5:4,database:s?6:5,storage:s?7:6},l=zu(typeof window>`u`?``:window.location.href).local,[u]=(0,r.useState)(()=>{let e=localStorage.getItem(`theme-mode`);return e===`light`?!1:e===`dark`?!0:window.matchMedia(`(prefers-color-scheme: dark)`).matches});return(0,r.useEffect)(()=>{e&&document.documentElement.setAttribute(`data-theme`,u?`dark`:`light`)},[u,e]),(0,r.useEffect)(()=>{if(e&&t.Pa.faviconUrl){let e=document.querySelector(`link[rel*='icon']`);e||(e=document.createElement(`link`),e.rel=`icon`,document.head.appendChild(e)),e.href=t.Pa.faviconUrl}},[e]),(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(Ce,{children:`Setup`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/setup`]})]})}),(0,i.jsx)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-6 md:p-10 shadow-2xl relative overflow-hidden bg-background flex flex-col`,children:[(0,i.jsx)(`div`,{className:`mb-6 pb-4 sm:mb-8 sm:pb-6 border-b border-[var(--panel-border)]/50 relative z-10`,children:(0,i.jsxs)(`div`,{className:`flex max-sm:flex-col max-sm:items-stretch items-center justify-between gap-3 sm:gap-4`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,i.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-extrabold text-foreground tracking-tight truncate`,children:`Connect your app to Firebase`}),(0,i.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1 sm:mt-1.5 leading-snug truncate`,children:[(0,i.jsx)(`span`,{className:`sm:hidden`,children:`Google's free data and sign-in service.`}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:`Firebase is Google's free service that stores your data and signs people in — about ten minutes, once.`})]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(t.fr.a,{whileHover:{scale:1.05},whileTap:{scale:.95},href:`mailto:antonina@youraiworkflow.co`,title:`Email Support`,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer btn-secondary`,children:(0,i.jsx)(t.Zr,{className:`w-4 h-4`})}),(0,i.jsx)(t.fr.a,{whileHover:{scale:1.05},whileTap:{scale:.95},href:`https://wa.me/34632407883`,target:`_blank`,rel:`noopener noreferrer`,title:`WhatsApp Support`,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer btn-secondary`,children:(0,i.jsx)(bu,{className:`w-4 h-4 text-foreground/80`})})]})]})}),!1,(0,i.jsxs)(`div`,{className:`flex flex-col relative z-10 p-4 sm:p-6 md:p-8 bg-foreground/[0.015] rounded-3xl border border-[var(--panel-border)]/50`,children:[s&&(0,i.jsxs)(Ju,{number:1,title:`Set your project up`,children:[(0,i.jsx)(`p`,{className:`text-foreground/80`,children:`Your assistant does this part — none of it is yours to type. Copy the block below into Claude Code, Codex or Antigravity and let it finish before you carry on. If you are already looking at this page on your own machine, paste it anyway: it only fills in what is missing and changes nothing that is already right.`}),(0,i.jsx)(qu,{text:wu,label:`Copy the setup prompt`}),(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`One of the lines it writes is `,(0,i.jsx)(`strong`,{children:`GEMINI_API_KEY`}),`, and it stays empty unless you later ask for something that uses AI — a chatbot, a writing helper. A free key comes from`,` `,(0,i.jsx)(`a`,{href:`https://aistudio.google.com/apikey`,target:`_blank`,rel:`noopener noreferrer`,className:Ku,children:`aistudio.google.com/apikey`}),` `,`when that day comes.`]})]}),(0,i.jsx)(Ju,{number:c.project,title:`Create a Firebase project`,children:(0,i.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-foreground/80`,children:[(0,i.jsxs)(`li`,{children:[`Open`,` `,(0,i.jsx)(`a`,{href:`https://console.firebase.google.com`,target:`_blank`,rel:`noopener noreferrer`,className:`text-accent underline underline-offset-2 font-semibold hover:text-accent-deep transition-colors`,children:`console.firebase.google.com`}),` `,`and click `,(0,i.jsx)(`strong`,{children:`Add project`}),`. Sign in with your Google account if it asks.`]}),(0,i.jsxs)(`li`,{children:[`Type any name you like and click `,(0,i.jsx)(`strong`,{children:`Continue`}),`.`]}),(0,i.jsxs)(`li`,{children:[`If it offers `,(0,i.jsx)(`strong`,{children:`Enable Gemini in Firebase`}),`, switch it off.`]}),(0,i.jsxs)(`li`,{children:[`Switch off `,(0,i.jsx)(`strong`,{children:`Enable Google Analytics for this project`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Create project`}),`, wait, then click `,(0,i.jsx)(`strong`,{children:`Continue`}),`.`]})]})}),(0,i.jsx)(Ju,{number:c.webApp,title:`Add a web app and copy the six values`,children:(0,i.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-foreground/80`,children:[(0,i.jsxs)(`li`,{children:[`On that page click `,(0,i.jsx)(`strong`,{children:`+ Add app`}),` under your project's name, then pick the `,(0,i.jsx)(`strong`,{children:`</> Web`}),` icon.`]}),(0,i.jsxs)(`li`,{children:[`Give it any nickname (`,(0,i.jsx)(`span`,{className:`text-accent`,children:`MyApp`}),` is fine). Leave `,(0,i.jsx)(`strong`,{children:`Firebase Hosting`}),` unticked.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Register app`}),`.`]}),(0,i.jsx)(`li`,{children:`Firebase now shows six values on screen, each with a label beside it — apiKey, authDomain, projectId, storageBucket, messagingSenderId and appId. You will copy them one at a time in the next step, so keep this tab open.`})]})}),(0,i.jsx)(Ju,{number:c.keys,title:s?`Put the six values in your .env`:`Paste the values into the Gemini prompt`,children:s?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`Step 1 made a `,(0,i.jsx)(`strong`,{children:`.env`}),` file, and every name below is already a line in it. Open it — or ask your assistant to open it for you — and put each value from your Firebase tab between that line's quotes. The names have to match letter for letter, so find them with the Copy name button rather than retyping.`]}),(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`Six lines, and that is all of them. Fill five of them now and leave`,` `,(0,i.jsx)(`strong`,{children:`VITE_FIREBASE_STORAGE_BUCKET`}),` empty — step `,c.storage,` gives you its real value.`]}),(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[(0,i.jsx)(`strong`,{children:`Leave the app as it is for now.`}),` One value is still missing, and starting it again is the last thing you do on this whole page.`]}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl overflow-hidden bg-background`,children:ku.map(({key:e,shownAs:t})=>(0,i.jsx)(Vu,{name:e,shownAs:t,hint:e===`VITE_FIREBASE_STORAGE_BUCKET`?`leave this one empty — step ${c.storage} gives you the real address`:void 0},e))})]}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`In the Gemini chat to the left, you will see a prompt to`,` `,(0,i.jsx)(`strong`,{children:`Enter your environment variables to continue`}),`, with a form like the one below. Paste each value from your Firebase tab into its row, then click `,(0,i.jsx)(`strong`,{children:`Apply`}),`.`]}),(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`Leave `,(0,i.jsx)(`strong`,{children:`VITE_FIREBASE_STORAGE_BUCKET`}),` empty — step `,c.storage,` gives you its real value.`]}),(0,i.jsx)(Wu,{})]})}),(0,i.jsxs)(Ju,{number:c.signIn,title:`Turn on sign-in`,children:[(0,i.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-foreground/80`,children:[(0,i.jsxs)(`li`,{children:[`In the Firebase menu on the left, open `,(0,i.jsx)(`strong`,{children:`Authentication`}),` and click `,(0,i.jsx)(`strong`,{children:`Get started`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Open the `,(0,i.jsx)(`strong`,{children:`Sign-in method`}),` tab.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Email/Password`}),`, switch on the first toggle and `,(0,i.jsx)(`strong`,{children:`Save`}),`. (Leave email link off.)`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Add provider`}),`, choose `,(0,i.jsx)(`strong`,{children:`Google`}),`, switch it on, pick your own address as the support email, and `,(0,i.jsx)(`strong`,{children:`Save`}),`. The app needs this for the `,(0,i.jsx)(`strong`,{children:`Sign in with Google`}),` button to work.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Add provider`}),`, choose `,(0,i.jsx)(`strong`,{children:`Anonymous`}),`, switch it on, and `,(0,i.jsx)(`strong`,{children:`Save`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Open the `,(0,i.jsx)(`strong`,{children:`Settings`}),` tab, then `,(0,i.jsx)(`strong`,{children:`Authorized domains`}),`. Your app has to be listed here or nobody can sign in.`]}),l?(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Nothing to add here yet.`}),` This app is being served from your own machine, and Firebase trusts that address from the start. Come back and add the real one the day you put your app on the internet.`]}):(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Your app's address is right here`}),` — copy it below, then in Firebase click `,(0,i.jsx)(`strong`,{children:`Add domain`}),`, paste it, and save. Nothing to hunt for: it is the address this very page is being served from.`]})]}),(0,i.jsx)(Bu,{})]}),(0,i.jsxs)(Ju,{number:c.database,title:`Create the database and publish its rules`,children:[(0,i.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-foreground/80 mb-4`,children:[(0,i.jsxs)(`li`,{children:[`In the Firebase menu, open `,(0,i.jsx)(`strong`,{children:`Firestore Database`}),` and click `,(0,i.jsx)(`strong`,{children:`Create database`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Pick `,(0,i.jsx)(`strong`,{children:`Standard edition`}),` if asked, choose the location closest to your people, start in `,(0,i.jsx)(`strong`,{children:`Production mode`}),`, and click Continue.`]}),(0,i.jsxs)(`li`,{children:[`In the box below, type the email address you will sign in with and click `,(0,i.jsx)(`strong`,{children:`Generate the rules`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Copy the rules`}),`, then in Firebase open the `,(0,i.jsx)(`strong`,{children:`Rules`}),` tab, select everything that is there, paste over it, and click `,(0,i.jsx)(`strong`,{children:`Publish`}),`.`]})]}),(0,i.jsx)(Gu,{})]}),(0,i.jsxs)(Ju,{number:c.storage,title:s?`Create storage, publish its rules, and start it again`:`Create storage, publish its rules, and press Apply`,children:[(0,i.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-foreground/80 mb-4`,children:[(0,i.jsxs)(`li`,{children:[`In the Firebase menu, open `,(0,i.jsx)(`strong`,{children:`Storage`}),`. Google asks you to upgrade the project first: click `,(0,i.jsx)(`strong`,{children:`Upgrade project`}),` and pick the pay-as-you-go`,` `,(0,i.jsx)(`strong`,{children:`Blaze plan`}),`. Profile photos and attachments cost about $0.03 per gigabyte a month, so this is cents. Set a budget you are comfortable with (say $20), link a billing account, and continue.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Get started`}),`, choose a no-cost location, start in `,(0,i.jsx)(`strong`,{children:`Production mode`}),`, and click `,(0,i.jsx)(`strong`,{children:`Create`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Open the `,(0,i.jsx)(`strong`,{children:`Rules`}),` tab, select everything that is there, paste these over it, and click `,(0,i.jsx)(`strong`,{children:`Publish`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Now Firebase shows the storage address at the top of the page — something like`,` `,`your-project.firebasestorage.app. `,(0,i.jsx)(`strong`,{children:`Copy that`}),`. This is the real one; the one Firebase showed you back in step `,c.webApp,` was a guess made before storage existed.`]}),s?(0,i.jsxs)(`li`,{children:[`Back in your `,(0,i.jsx)(`strong`,{children:`.env`}),` file, paste it into`,` `,(0,i.jsx)(`strong`,{children:`VITE_FIREBASE_STORAGE_BUCKET`}),` — the line you left empty.`]}):(0,i.jsxs)(`li`,{children:[`In Google AI Studio, click the `,(0,i.jsx)(`strong`,{children:`cog`}),` icon in the top right corner and scroll the menu along the top to `,(0,i.jsx)(`strong`,{children:`Secrets`}),`. Paste it as the value of `,(0,i.jsx)(`strong`,{children:`VITE_FIREBASE_STORAGE_BUCKET`}),` — the one you left empty. If it is not listed, click `,(0,i.jsx)(`strong`,{children:`+ Add secret`}),` and use that name.`]}),s?(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Start the app again.`}),` Stop it and start it once more — or just ask your assistant to restart it. A value added while it is running is not read until then. That is the last thing to do: then reload this page and your app is connected.`]}):(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Press Apply, then reload this page.`}),` Your app is connected.`]})]}),(0,i.jsx)(Ru,{code:Pu,label:`Copy the storage rules`})]})]}),(0,i.jsx)(Yu,{basename:n.basename})]})})]})}var Zu={email:{collection:`sys_configs`,doc:`email`},payments:{collection:`sys_payments`,doc:`_settings`}},Qu=e=>e?.enabled!==!1;function $u(e){let{collection:n,doc:i}=Zu[e],[a,s]=(0,r.useState)({loading:!0,on:!0});return(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(t.Da,n,i),e=>s({loading:!1,on:Qu(e.exists()?e.data():null)}),()=>s({loading:!1,on:!0})),[n,i]),{loading:a.loading,on:a.on,set:async r=>{let c=a.on;s({loading:!1,on:r});try{return await(0,o.setDoc)((0,o.doc)(t.Da,n,i),{enabled:r},{merge:!0}),e===`payments`&&J(),null}catch{return s({loading:!1,on:c}),`The switch could not be saved. Check that you are signed in as an admin.`}}}}var ed=`The server could not be reached.`;function td(e,t,n=0){let[i,a]=(0,r.useState)(null),[o,s]=(0,r.useState)(``),c=(0,r.useRef)(!0);(0,r.useEffect)(()=>(c.current=!0,()=>{c.current=!1}),[]);let l=(0,r.useRef)(t);(0,r.useEffect)(()=>{l.current=t},[t]);let u=(0,r.useCallback)(async()=>{try{let t=await(await fetch(e)).json();if(!c.current)return;a(l.current(t)),s(``)}catch{c.current&&s(ed)}},[e]);return(0,r.useEffect)(()=>{if(u(),!n)return;let e=setInterval(u,n);return()=>clearInterval(e)},[u,n]),{status:i,error:o,reread:u}}var nd=e=>({configured:!!e?.configured,mode:e?.mode===`live`||e?.mode===`test`?e.mode:null,webhookConfigured:!!e?.webhookConfigured}),rd=e=>({configured:!!e?.configured,from:e?.from??null,adminCount:Number(e?.adminCount)||0}),id={email:`/api/email/status`,payments:`/api/payments/status`},ad=(e=0)=>td(id.payments,nd,e),od=(e=0)=>td(id.email,rd,e),sd=e=>!!e?.configured;function cd(e){let t=td(id[e],sd),n=$u(e);return{loading:t.status===null&&!t.error||n.loading,configured:t.status===!0,on:n.on}}var ld={collection:`sys_configs`,doc:`publish`},ud=[`published`,`connected`,`authorised`],dd={appName:``,domain:``,done:[]};function fd(e){let t=Array.isArray(e?.done)?e.done:[];return{appName:typeof e?.appName==`string`?e.appName:``,domain:typeof e?.domain==`string`?e.domain:``,done:ud.filter(e=>t.includes(e))}}function pd(e){let t=String(e??``).trim().toLowerCase();return t=t.replace(/^[a-z][a-z0-9+.-]*:\/\//,``),t=t.split(/[/?#]/)[0],t=t.replace(/\.ai\.studio$/,``),t.replace(/[\s_]+/g,`-`).replace(/[^a-z0-9-]/g,``).replace(/-{2,}/g,`-`).replace(/^-+|-+$/g,``)}var md=e=>{let t=pd(e);return t?`https://${t}.ai.studio/`:``};function hd(e){let t=String(e??``).trim().toLowerCase();return t=t.replace(/^[a-z][a-z0-9+.-]*:\/\//,``),t=t.replace(/^[^/@]*@/,``),t=t.split(/[/?#]/)[0],t=t.split(`:`)[0],t=t.replace(/^www\./,``),t=t.replace(/^\.+|\.+$/g,``),/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*\.[a-z]{2,}$/.test(t)?t:``}var gd=e=>{let t=hd(e);return t?`https://${t}/`:``},_d=e=>gd(e?.domain)||md(e?.appName);function vd(e,t=null){let n=t=>e.includes(t),r=ud.find(e=>!n(e))??null,i=r?ud.indexOf(r):ud.length-1;return ud.map((e,a)=>{let o=a<=i,s=t!==null&&t===e&&o;return{id:e,visible:o,done:n(e),open:s||t===null&&e===r}})}var yd=(e,t)=>ud.filter(n=>n===t||e.includes(n));function bd(e){return!e||!e.configured?!1:e.mode===`live`?!e.webhookConfigured:!0}function xd(){let[e,n]=(0,r.useState)({loading:!0,record:dd});return(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(t.Da,ld.collection,ld.doc),e=>n({loading:!1,record:fd(e.exists()?e.data():null)}),()=>n({loading:!1,record:dd})),[]),{loading:e.loading,record:e.record,save:async e=>{n(t=>({loading:!1,record:{...t.record,...e}}));try{return await(0,o.setDoc)((0,o.doc)(t.Da,ld.collection,ld.doc),e,{merge:!0}),null}catch(e){return console.error(`Could not save where you got to`,e),`That could not be saved. Only an admin can, and only while you are signed in.`}}}}function Sd(e,t){return!e&&t!==`live`?{state:`off`,label:`In test mode`}:t===`live`?{state:`saved`,label:`Live`}:{state:`saving`,label:`Waiting for the live key`}}var Cd=[`checkout.session.completed`,`checkout.session.async_payment_succeeded`],wd=`text-[12.5px] font-medium text-foreground/70 leading-relaxed`,Td=`mt-1.5 space-y-1 list-disc list-inside marker:text-foreground/30`,Ed=`my-2 glass-panel border border-[var(--panel-border)] rounded-2xl overflow-hidden bg-background`;function Dd(){let[e,n]=(0,r.useState)(null),[a,s]=(0,r.useState)([]),{status:l}=ad(5e3),u=l?.mode??null,d=l?.webhookConfigured??!1,[f]=Cu(),p=f===`local`,{record:m}=xd(),h=z(_d(m)),g=m.done.includes(`authorised`)&&!!h;(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.collection)(t.Da,ji),e=>{n(!!e.docs.find(e=>e.id===Mi)?.data()?.liveMode);let t=[];e.forEach(e=>{e.id!==`_settings`&&t.push(Ui(e.id,e.data()))}),t.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)),s(t)},()=>n(!1)),[]);let _=async e=>{n(e);try{await(0,o.setDoc)((0,o.doc)(t.Da,ji,Mi),{liveMode:e},{merge:!0})}catch(e){console.error(`Could not save the go-live switch`,e)}},v=!!e,y=Sd(v,u),b=a.filter(e=>qi(e,!1)),x=b.filter(e=>!qi(e,!0)),S=b.length>0&&x.length===0,C=b.some(e=>e.kind===`subscription`);return(0,i.jsx)(t.ut,{icon:t.zr,title:`Go live`,description:v?`Real cards, real money — the steps below finish the switch.`:`Practice is free — flip this only when a test payment has gone all the way through.`,chip:y,enabled:e===null?null:v,onChange:_,children:v&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`ol`,{className:`space-y-3.5 list-decimal list-inside ${wd}`,children:[(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Your live secret key.`}),` In Stripe, click your account name in the top left corner and choose your `,(0,i.jsx)(`strong`,{children:`live`}),` account — not the sandbox.`,(0,i.jsxs)(`ul`,{className:Td,children:[(0,i.jsxs)(`li`,{children:[`Open the dark strip along the bottom that says `,(0,i.jsx)(`strong`,{children:`Developers`}),`, and scroll down to the `,(0,i.jsx)(`strong`,{children:`API keys`}),` section.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Manage API keys`}),`. Under `,(0,i.jsx)(`strong`,{children:`Standard keys`}),`, click `,(0,i.jsx)(`strong`,{children:`+ Create secret key`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Where it asks `,(0,i.jsx)(`em`,{children:`How will you be using this key?`}),`, choose`,` `,(0,i.jsx)(`strong`,{children:`Powering an integration you built`}),`, then`,` `,(0,i.jsx)(`strong`,{children:`Create secret key`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Stripe asks you to confirm it is you: click `,(0,i.jsx)(`strong`,{children:`Send verification`}),` `,`and verify the request with the code it sends.`]}),(0,i.jsxs)(`li`,{children:[`Give the key a name — `,(0,i.jsx)(`span`,{className:`text-accent`,children:`my ai project app key`}),` `,`— and copy it. `,(0,i.jsx)(`strong`,{children:`Stripe will not show it to you again.`})]}),p?(0,i.jsxs)(`li`,{children:[`Open your `,(0,i.jsx)(`strong`,{children:`.env`}),` file and paste it over the sk_test_… value of `,(0,i.jsx)(`strong`,{children:`STRIPE_SECRET_KEY`}),` — replace it, do not add a second line. Start the app again, and the chip at the top of this card turns to `,(0,i.jsx)(`strong`,{children:`Live`}),` on its own.`]}):(0,i.jsxs)(`li`,{children:[`Click the `,(0,i.jsx)(`strong`,{children:`cog icon`}),` in the top right corner of your app in Google AI Studio and find the `,(0,i.jsx)(`strong`,{children:`Secrets`}),` tab. Paste the new key over the value of `,(0,i.jsx)(`strong`,{children:`STRIPE_SECRET_KEY`}),` — replace the sk_test_… one, do not add a second. Click `,(0,i.jsx)(`strong`,{children:`Apply`}),` and refresh this page: the chip at the top of this card turns to `,(0,i.jsx)(`strong`,{children:`Live`}),` on its own.`]})]})]}),C&&(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Your live price ids.`}),` A subscription's prices are made fresh in live mode, so the ids under `,(0,i.jsx)(`strong`,{children:`What you sell`}),` change. Create each plan's price in your live Stripe account and paste its id there. Your test ids are kept and come straight back if you switch off again.`]}),(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`The webhook.`}),` `,g?`What keeps receipts and your sale alerts sending when a buyer pays and never comes back to your app.`:`Stripe has to be able to reach your app from the outside, so this one waits until your app is published.`,` `,(0,i.jsx)(`span`,{className:`inline-block align-middle ml-0.5`,children:(0,i.jsx)(t.lt,{state:d?`saved`:`off`,label:d?`Connected`:`Not yet`})}),g?(0,i.jsxs)(`ul`,{className:Td,children:[(0,i.jsxs)(`li`,{children:[`Still in your `,(0,i.jsx)(`strong`,{children:`live`}),` Stripe account, open the`,` `,(0,i.jsx)(`strong`,{children:`Developers`}),` strip at the bottom again and, in its top menu, click `,(0,i.jsx)(`strong`,{children:`Webhooks`}),`. Click `,(0,i.jsx)(`strong`,{children:`Add destination`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Leave every setting as it is. Under `,(0,i.jsx)(`strong`,{children:`Events`}),`, use the`,` `,(0,i.jsx)(`em`,{children:`Find event by name or description…`}),` search bar to find these two, and click the checkmark on each:`,(0,i.jsx)(`div`,{className:`mt-1.5 flex flex-col gap-1`,children:Cd.map(e=>(0,i.jsx)(Ru,{code:e,label:e,compact:!0},e))}),`The first is an ordinary card payment. The second is a bank transfer landing hours later, when nobody is watching — without it those sales send no email at all.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Continue`}),` and keep it as a`,` `,(0,i.jsx)(`strong`,{children:`Webhook endpoint`}),`. Give the destination a name —`,` `,(0,i.jsx)(`span`,{className:`text-accent`,children:`my ai project receipts`}),`.`]}),(0,i.jsxs)(`li`,{children:[`As the `,(0,i.jsx)(`strong`,{children:`Endpoint URL`}),`, paste exactly this — your published address with the webhook route on the end:`,(0,i.jsx)(`div`,{className:`my-2`,children:(0,i.jsx)(Ru,{code:h,label:`Copy your webhook address`,compact:!0})})]}),(0,i.jsxs)(`li`,{children:[`Create the destination. On the right, under Webhooks, you will find its`,` `,(0,i.jsx)(`strong`,{children:`signing secret`}),` — it starts with `,(0,i.jsx)(`strong`,{children:`whsec_`}),`. Copy it.`]}),(0,i.jsxs)(`li`,{children:[p?(0,i.jsxs)(i.Fragment,{children:[`Add the line below to your `,(0,i.jsx)(`strong`,{children:`.env`}),` file with the whsec_… secret as its value, and start the app again. You are all set — the chip beside this step turns green.`]}):(0,i.jsxs)(i.Fragment,{children:[`Click the `,(0,i.jsx)(`strong`,{children:`cog icon`}),` in the top right corner of your app in Google AI Studio, scroll the menu along the top to `,(0,i.jsx)(`strong`,{children:`Secrets`}),` `,`and click `,(0,i.jsx)(`strong`,{children:`+ Add secret`}),`. Copy the name below into`,` `,(0,i.jsx)(`strong`,{children:`Secret name`}),` and paste the whsec_… secret as its value. Click `,(0,i.jsx)(`strong`,{children:`Apply`}),` and refresh this page. You are all set — the chip beside this step turns green.`]}),(0,i.jsx)(`div`,{className:Ed,children:(0,i.jsx)(Vu,{name:`STRIPE_WEBHOOK_SECRET`,hint:`the whsec_… signing secret from the destination you just made`})})]})]}):(0,i.jsxs)(`div`,{className:`mt-2 flex flex-col gap-2.5`,children:[(0,i.jsxs)(t.st,{children:[`Your app has no public address yet, and the preview address in this browser is not one Stripe can reach — it changes every session.`,` `,m.done.length===0?`Publish your app first`:`Finish publishing your app first`,`: this step opens on its own once step 3 of Publish App,`,` `,(0,i.jsx)(`strong`,{children:`Add your domains and email sender`}),`, is ticked. Everything above works in the meantime.`]}),(0,i.jsxs)(c.Link,{to:`/publish`,className:`inline-flex items-center gap-1.5 w-fit h-9 px-4 rounded-[var(--btn-radius,0.75rem)] text-[12.5px] font-bold border border-accent/40 bg-accent/10 text-accent hover:bg-accent/15 transition-all active:scale-[0.98] cursor-pointer`,children:[`Take me to Publish App`,(0,i.jsx)(t.Xi,{className:`w-3.5 h-3.5`})]})]})]})]}),(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`One more switch lives in Stripe, not here: switching plans (monthly ↔ yearly, Basic ↔ Pro) appears in Stripe’s customer portal — where your buyers manage their own subscriptions — only if you allow it:`,` `,(0,i.jsx)(`a`,{href:`https://dashboard.stripe.com/settings/billing/portal`,target:`_blank`,rel:`noopener noreferrer`,className:`text-accent font-bold hover:underline`,children:`Stripe Settings → Billing → Customer portal`}),` `,`→ let customers switch plans.`]}),b.length>0&&!S&&(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Your subscriptions under What you sell now ask for `,(0,i.jsx)(`strong`,{children:`live`}),` price ids — `,x.length===b.length?`each one`:`${x.length} of ${b.length}`,` is still waiting. Your test ids are kept and come back if you switch back. Once the live ids are in, the message for your assistant appears right here.`]}),S&&(0,i.jsx)(it,{title:`Tell your assistant about the switch`,prompt:ja(b)})]})})}var Od={configured:!1,mode:null,webhookConfigured:!1};function kd(e=5e3){let{status:t,error:n}=ad(e);return{...t??Od,checked:t!==null||!!n}}function Ad(e,t){if(!t.checked)return{state:`saving`,label:`Checking`};switch(e){case 1:case 2:return t.configured?{state:`saved`,label:`Done`}:{state:`off`,label:`Not yet`};case 3:return t.configured?{state:`saved`,label:t.mode===`live`?`Key found — live`:`Key found — test mode`}:{state:`off`,label:`No key yet`}}}var jd={configured:!1,from:null,adminCount:0};function Md(e=5e3){let{status:t,error:n}=od(e);return{...t??jd,checked:t!==null||!!n}}function Nd(e){return e.checked?e.configured?{state:`saved`,label:`Connected`}:{state:`off`,label:`Not yet`}:{state:`saving`,label:`Checking`}}function Pd(e){return e.checked?e.from&&!String(e.from).toLowerCase().endsWith(`@resend.dev`)?{state:`saved`,label:`Your own address`}:{state:`off`,label:`Practice address`}:{state:`saving`,label:`Checking`}}var Fd=`text-accent underline underline-offset-2 font-semibold hover:text-accent-deep transition-colors`;function Id({href:e,children:t}){return(0,i.jsx)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,className:Fd,children:t})}function Ld({number:e,title:t,aside:n,children:r}){return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 pb-5 mb-5 border-b border-[var(--panel-border)]/50 last:border-0 last:pb-0 last:mb-0`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5`,children:[(0,i.jsx)(`span`,{className:`w-7 h-7 shrink-0 rounded-full bg-accent/10 border border-accent/20 text-accent flex items-center justify-center text-[12.5px] font-extrabold`,children:e}),(0,i.jsx)(`h4`,{className:`text-[14px] font-bold text-foreground tracking-tight flex-1 min-w-0`,children:t}),n]}),(0,i.jsx)(`div`,{className:`text-[13px] text-foreground/70 leading-relaxed space-y-3 sm:pl-[2.375rem]`,children:r})]})}var Rd=`space-y-1.5 list-decimal list-inside text-foreground/75`,zd=`glass-panel border border-[var(--panel-border)] rounded-2xl overflow-hidden bg-background`;function Bd({onConfirm:e,hint:n}){let[r]=Cu();return(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 pt-1`,children:[(0,i.jsx)(t.Q,{icon:t.zi,onClick:e,className:`self-start`,children:`I have added the variables`}),(0,i.jsx)(`p`,{className:t.$,children:n||(r===`local`?`Start the app again first — a value added to .env while it is running is not read until then. If the chips have not turned green a minute later, reload this page.`:`Press Apply in AI Studio’s Secrets tab first — the app can only read a secret once it has been applied. If the chips have not turned green a minute later, reload this page.`)})]})}function Vd({icon:e,title:n,description:r,stepsDescription:a,button:o,secret:s,open:c,onOpen:l,confirmed:u,steps:d,children:f}){let[p]=Cu();return(0,i.jsx)(t.at,{icon:e,title:n,description:c?a:r,collapsible:!1,children:c?d:(0,i.jsxs)(i.Fragment,{children:[f,u&&(0,i.jsxs)(t.st,{tone:`error`,children:[`The app cannot see the key yet.`,` `,p===`local`?(0,i.jsxs)(i.Fragment,{children:[`Make sure `,s,` has a value in your .env file, start the app again, then reload this page`]}):(0,i.jsxs)(i.Fragment,{children:[`In AI Studio’s Secrets tab make sure `,s,` is there and press Apply, then reload this page`]}),` `,`— or open the steps again to check them.`]}),(0,i.jsxs)(`button`,{type:`button`,onClick:l,className:`inline-flex items-center gap-1.5 w-fit h-9 px-4 rounded-[var(--btn-radius,0.75rem)] text-[12.5px] font-bold border border-accent/40 bg-accent/10 text-accent hover:bg-accent/15 transition-all active:scale-[0.98] cursor-pointer`,children:[o,(0,i.jsx)(t.Xi,{className:`w-3.5 h-3.5`})]})]})})}function Hd({onConfirm:e}){let n=kd(),[r]=Cu(),a=r===`local`;return(0,i.jsxs)(`div`,{className:`flex flex-col`,children:[(0,i.jsx)(Ld,{number:1,title:`Make a Stripe account`,aside:(0,i.jsx)(t.lt,{...Ad(1,n)}),children:(0,i.jsxs)(`ol`,{className:Rd,children:[(0,i.jsxs)(`li`,{children:[`Open `,(0,i.jsx)(Id,{href:`https://dashboard.stripe.com`,children:`dashboard.stripe.com`}),` and create an account. It asks about your business — answer what you can and skip what you can't; none of it blocks the next steps.`]}),(0,i.jsxs)(`li`,{children:[`Click your account name in the `,(0,i.jsx)(`strong`,{children:`top left`}),` corner, choose`,` `,(0,i.jsx)(`strong`,{children:`Switch to sandbox`}),`, and make a sandbox for testing. A sandbox is a practice copy of Stripe: every card in it is pretend and every payment is practice, so nothing you do here can cost anyone real money.`]})]})}),(0,i.jsx)(Ld,{number:2,title:`Copy the test secret key`,aside:(0,i.jsx)(t.lt,{...Ad(2,n)}),children:(0,i.jsxs)(`ol`,{className:Rd,children:[(0,i.jsxs)(`li`,{children:[`Along the very bottom of the Stripe page is a dark bar that says `,(0,i.jsx)(`strong`,{children:`Developers`}),`. Click the arrow on it to unfold the panel.`]}),(0,i.jsxs)(`li`,{children:[`On the right of that panel, under `,(0,i.jsx)(`strong`,{children:`Testing tools`}),`, is your`,` `,(0,i.jsx)(`strong`,{children:`secret key`}),` — it starts with `,(0,i.jsx)(`strong`,{children:`sk_test_`}),`. Copy it.`]})]})}),(0,i.jsxs)(Ld,{number:3,title:a?`Put it in your .env and start the app again`:`Paste it into Secrets and press Apply`,aside:(0,i.jsx)(t.lt,{...Ad(3,n)}),children:[a?(0,i.jsxs)(`p`,{children:[`Open your `,(0,i.jsx)(`strong`,{children:`.env`}),` file — or ask your assistant to. The line below is already in it: paste the sk_test_… key between its quotes. One line, and that is the whole step — then `,(0,i.jsx)(`strong`,{children:`start the app again`}),` so it is read.`]}):(0,i.jsxs)(`ol`,{className:Rd,children:[(0,i.jsxs)(`li`,{children:[`Click the `,(0,i.jsx)(`strong`,{children:`cog`}),` icon in the top right corner of your app in Google AI Studio.`]}),(0,i.jsxs)(`li`,{children:[`In the menu along the top, scroll across to `,(0,i.jsx)(`strong`,{children:`Secrets`}),`, then click`,` `,(0,i.jsx)(`strong`,{children:`+ Add secret`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Copy the name below into `,(0,i.jsx)(`strong`,{children:`Secret name`}),`, and paste the sk_test_… key you just copied as the value.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Apply`}),`, then refresh the page. You are all set.`]})]}),(0,i.jsx)(`div`,{className:zd,children:(0,i.jsx)(Vu,{name:`STRIPE_SECRET_KEY`,hint:`the sk_test_… key you copied in step 2`})}),(0,i.jsxs)(`p`,{children:[`Now you can test a payment with the pretend card `,(0,i.jsx)(`strong`,{children:`4242 4242 4242 4242`}),` and any other details you like, or by paying with Google Pay or Apple Pay. Nothing is ever charged — a sandbox is all practice.`]})]}),(0,i.jsx)(Bd,{onConfirm:e})]})}function Ud({onConfirm:e}){let n=Md(),[r]=Cu(),a=r===`local`;return(0,i.jsxs)(`div`,{className:`flex flex-col`,children:[(0,i.jsx)(Ld,{number:1,title:`Make a Resend account and a key`,aside:(0,i.jsx)(t.lt,{...Nd(n)}),children:(0,i.jsxs)(`ol`,{className:Rd,children:[(0,i.jsxs)(`li`,{children:[`Open `,(0,i.jsx)(Id,{href:`https://resend.com`,children:`resend.com`}),` and create a free account — it is the service that delivers email for you. Sign up with the address you want your app's mail to reach you at.`]}),(0,i.jsxs)(`li`,{children:[`In Resend, open `,(0,i.jsx)(`strong`,{children:`API Keys`}),` and click `,(0,i.jsx)(`strong`,{children:`Create API key`}),`. Copy the key it shows — it starts with `,(0,i.jsx)(`strong`,{children:`re_`}),` — and keep the tab open.`]})]})}),(0,i.jsxs)(Ld,{number:2,title:a?`Put two values in your .env and start the app again`:`Paste two secrets and press Apply`,aside:(0,i.jsx)(t.lt,{...Nd(n)}),children:[a?(0,i.jsxs)(`p`,{children:[`Open your `,(0,i.jsx)(`strong`,{children:`.env`}),` file. Both lines below are already in it — paste each value between its quotes, then `,(0,i.jsx)(`strong`,{children:`start the app again`}),` so they are read.`]}):(0,i.jsxs)(`ol`,{className:Rd,children:[(0,i.jsxs)(`li`,{children:[`Click the `,(0,i.jsx)(`strong`,{children:`cog`}),` icon in the top right corner of your app in Google AI Studio.`]}),(0,i.jsxs)(`li`,{children:[`In the menu along the top, scroll across to `,(0,i.jsx)(`strong`,{children:`Secrets`}),`.`]}),(0,i.jsxs)(`li`,{children:[`For each row below, click `,(0,i.jsx)(`strong`,{children:`+ Add secret`}),`, copy the name here into`,` `,(0,i.jsx)(`strong`,{children:`Secret name`}),`, and paste the value.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Apply`}),`, then refresh the page.`]})]}),(0,i.jsxs)(`div`,{className:zd,children:[(0,i.jsx)(Vu,{name:`RESEND_API_KEY`,hint:`the re_… key you just made in Resend`}),(0,i.jsx)(Vu,{name:`ADMIN_EMAILS`,hint:`your own email address — where sale, booking and form alerts are sent`})]})]}),(0,i.jsxs)(Ld,{number:3,title:`Verify your domain, or mail only reaches you`,aside:(0,i.jsx)(t.lt,{...Pd(n)}),children:[(0,i.jsxs)(`p`,{children:[(0,i.jsx)(`strong`,{children:`Until you verify a domain of your own, Resend delivers only to the email address you made your Resend account with.`}),` A test email to yourself works; a customer's confirmation, a buyer's receipt, a booking note to someone else does not arrive at all. Do this before anyone but you should get an email.`]}),(0,i.jsxs)(`ol`,{className:Rd,children:[(0,i.jsxs)(`li`,{children:[`In Resend open `,(0,i.jsx)(Id,{href:`https://resend.com/domains`,children:`Domains`}),`, click `,(0,i.jsx)(`strong`,{children:`Add domain`}),` `,`and type the domain you own — `,(0,i.jsx)(`strong`,{children:`yourbusiness.com`}),`, without www.`]}),(0,i.jsx)(`li`,{children:`Resend shows a few DNS records. Add each one where your domain is managed — the company you bought it from, or wherever its website is hosted — copying name and value exactly.`}),(0,i.jsxs)(`li`,{children:[`Back in Resend, click `,(0,i.jsx)(`strong`,{children:`Verify`}),`. It can take a few minutes to turn green; if it does not, one record was copied wrong.`]}),a?(0,i.jsxs)(`li`,{children:[`Fill in one more line in your `,(0,i.jsx)(`strong`,{children:`.env`}),` — an address at that domain, which is what your mail goes out as — and `,(0,i.jsx)(`strong`,{children:`start the app again`}),`.`]}):(0,i.jsxs)(`li`,{children:[`Add one more secret in AI Studio — an address at that domain, which is what your mail goes out as — and press `,(0,i.jsx)(`strong`,{children:`Apply`}),` again.`]})]}),(0,i.jsx)(`div`,{className:zd,children:(0,i.jsx)(Vu,{name:`EMAIL_FROM`,hint:`an address at your verified domain, like hello@yourbusiness.com`})})]}),(0,i.jsx)(Bd,{onConfirm:e})]})}function Wd(){return(0,i.jsx)(c.Navigate,{to:`/setup`,replace:!0})}function Gd(e){return e.kind===`subscription`?e.active?{label:`Subscription active`,tone:`good`}:{label:`Cancelled`,tone:`quiet`}:e.fullyRefunded?{label:`Refunded`,tone:`bad`}:(e.amountRefunded||0)>0?{label:`Partially refunded`,tone:`bad`}:e.paid?{label:`Paid`,tone:`good`}:{label:`Not paid`,tone:`quiet`}}function Kd(e,t){if(e==null)return`—`;try{return new Intl.NumberFormat(void 0,{style:`currency`,currency:(t||`usd`).toUpperCase()}).format(e)}catch{return`${e} ${(t||``).toUpperCase()}`.trim()}}var qd=e=>e?{description:`Every Pay button on your pages works. Switch it off to pause all of it at once.`,chip:{state:`saved`,label:`On`}}:{description:`No Pay button shows and nothing can be bought. Your pages keep their settings.`,chip:{state:`off`,label:`Off`}},Jd=e=>e?new Date(e*1e3).toLocaleDateString(void 0,{day:`numeric`,month:`short`,year:`numeric`}):``;function Yd({label:e,tone:t}){return(0,i.jsx)(`span`,{className:`inline-flex items-center h-6 px-2.5 rounded-full border text-[11px] font-bold whitespace-nowrap shrink-0 ${t===`good`?`text-emerald-500 bg-emerald-500/10 border-emerald-500/20`:t===`bad`?`text-red-500 bg-red-500/10 border-red-500/20`:`text-foreground/50 bg-foreground/[0.04] border-[var(--panel-border)]`}`,children:e})}function Xd(){let{user:e}=t.na(),{status:n,error:a,reread:o}=ad(),[s,c]=(0,r.useState)(!1),[l,u]=(0,r.useState)(!1),[d,f]=(0,r.useState)(null),[p,m]=(0,r.useState)(``),[h,g]=(0,r.useState)([]),[_,v]=(0,r.useState)([]),[y,b]=(0,r.useState)(!1),[x,S]=(0,r.useState)(``),[C,w]=(0,r.useState)(!1),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(``),k=$u(`payments`),[A,j]=(0,r.useState)(``),M=qd(k.on),N=(0,r.useCallback)(async t=>{let n=e?await e.getIdToken():``,r=await fetch(t,{headers:n?{Authorization:`Bearer ${n}`}:void 0}),i=await r.json().catch(()=>({}));if(!r.ok||i?.success===!1)throw Error(i?.error||`The server could not answer.`);return i},[e]),P=()=>{c(!1),o().then(()=>u(!0))},F=(0,r.useCallback)((e,t)=>{let n=e.charges||[],r=e.subscriptions||[];g(e=>t?[...e,...n]:n),v(e=>t?[...e,...r]:r),w(!!(e.chargesHasMore||e.subscriptionsHasMore))},[]);(0,r.useEffect)(()=>{if(!n?.configured||!e)return;let t=!1;return N(`/api/payments/products`).then(e=>{t||f(e.products||[])}).catch(e=>{t||m(e.message)}),N(`/api/payments/orders`).then(e=>{t||(F(e,!1),b(!0))}).catch(e=>{t||(S(e.message),b(!0))}),()=>{t=!0}},[n?.configured,e,N,F]);let I=async()=>{E(!0);try{let e=new URLSearchParams,t=h[h.length-1],n=_[_.length-1];t&&e.set(`starting_after`,t.id),n&&e.set(`subscriptions_after`,n.id),F(await N(`/api/payments/orders?${e}`),!0)}catch(e){S(e.message)}E(!1)},L=e=>{navigator.clipboard?.writeText(e),O(e),setTimeout(()=>O(``),2e3)},R=[...h,..._].sort((e,t)=>(t.created||0)-(e.created||0)),z=(d||[]).flatMap(e=>e.prices),B=n?.mode===`live`?`https://dashboard.stripe.com/products`:`https://dashboard.stripe.com/test/products`,V=!!(n&&!n.configured);return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(Ce,{children:`Payments`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/payments`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col min-h-[600px]`,children:!n&&!a?(0,i.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,i.jsx)(t.ti,{className:`w-6 h-6 animate-spin text-accent`})}):V?(0,i.jsx)(Vd,{icon:t.wi,title:`Connect Stripe`,description:`This app is not taking payments yet.`,stepsDescription:`Three steps — about five minutes, with pretend money until you say otherwise.`,button:`Set up payments`,secret:`STRIPE_SECRET_KEY`,open:s,onOpen:()=>c(!0),confirmed:l,steps:(0,i.jsx)(Hd,{onConfirm:P}),children:(0,i.jsx)(t.st,{children:`Payments run through Stripe, and connecting it is one pasted key — no code, no terminal. Once it is in, this screen fills itself: what you sell, and every payment as it happens.`})}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[n?.mode===`live`&&(0,i.jsxs)(`div`,{className:`flex items-center gap-3 rounded-2xl border border-red-500/25 bg-red-500/[0.06] px-4 py-3`,children:[(0,i.jsx)(t.Er,{className:`w-4 h-4 text-red-500 shrink-0`}),(0,i.jsx)(`p`,{className:`text-[12.5px] font-semibold text-red-500 leading-snug`,children:`Live mode — real cards are being charged. Every payment on this screen is real money.`})]}),(0,i.jsx)(t.ut,{icon:t.Hr,title:`Take payments`,description:M.description,chip:M.chip,enabled:k.loading?null:k.on,onChange:async e=>j(await k.set(e)||``),children:A?(0,i.jsx)(t.st,{tone:`error`,children:A}):null}),(0,i.jsx)(t.at,{icon:t.Wr,title:`Connection`,description:`Which Stripe account this app is running on.`,defaultOpen:!n?.configured,actions:a?(0,i.jsx)(t.lt,{state:`error`,label:`Unreachable`}):(0,i.jsx)(t.lt,{state:`saved`,label:n?.mode===`live`?`Live mode connected`:`Test mode connected`}),children:a?(0,i.jsx)(t.st,{tone:`error`,children:a}):(0,i.jsx)(t.st,{children:n?.mode===`live`?`Connected with a live key. Payments made anywhere on your site are real money.`:`Test mode connected. Your Pay buttons work end to end, but only test cards are accepted and no real money moves. When you are ready for real payments, use Go live below.`})}),(0,i.jsx)(Dd,{}),(0,i.jsx)(fu,{}),(0,i.jsx)(t.at,{icon:t.Ar,title:`In your Stripe account`,description:`The products and prices Stripe has right now — where price ids come from.`,defaultOpen:!1,children:p?(0,i.jsx)(t.st,{tone:`error`,children:p}):d===null?(0,i.jsx)(`div`,{className:`flex items-center justify-center py-6 text-foreground/40`,children:(0,i.jsx)(t.ti,{className:`w-5 h-5 animate-spin text-accent`})}):z.length===0?(0,i.jsxs)(t.st,{children:[`Nothing needs to exist here for one-off payments — a Pay button can name its own amount. Only a subscription needs a price made in Stripe first:`,` `,(0,i.jsx)(`a`,{href:B,target:`_blank`,rel:`noreferrer`,className:`text-accent font-bold hover:underline`,children:`create one in your Stripe dashboard`}),` `,`and it appears here with its id ready to copy.`]}):(0,i.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:z.map(e=>(0,i.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${t.X}`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate min-w-0 flex-1`,children:e.productName||`Unnamed product`}),(0,i.jsxs)(`span`,{className:`text-[12.5px] font-semibold text-foreground/60 whitespace-nowrap shrink-0`,children:[Kd(e.amount,e.currency),e.interval?` / ${e.interval}`:``]}),(0,i.jsx)(t.Q,{compact:!0,icon:D===e.id?t.zi:t.Ti,title:`Copy the price id for ${e.productName||`this price`}`,onClick:()=>L(e.id),children:D===e.id?`Copied`:`Copy price id`})]},e.id))})}),(0,i.jsx)(t.at,{icon:t.Vr,title:`Payments received`,description:`Every charge and subscription, straight from Stripe.`,defaultOpen:!1,children:x?(0,i.jsx)(t.st,{tone:`error`,children:x}):y?R.length===0?(0,i.jsx)(t.st,{children:`Nothing yet. When someone pays, it lands here on its own — and refunds you make in Stripe show up here too, with nothing to sync.`}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[R.map(e=>{let n=Gd(e);return(0,i.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${t.X}`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.name||e.email||`Someone`}),(0,i.jsxs)(`span`,{className:`text-[11px] text-foreground/45 font-medium truncate`,children:[e.productName||e.description||(e.kind===`subscription`?`Subscription`:`One-off payment`),e.page?` — sold on ${e.page}`:``]})]}),(0,i.jsx)(`span`,{className:`max-sm:hidden text-[11.5px] font-medium text-foreground/45 whitespace-nowrap shrink-0`,children:Jd(e.created)}),(0,i.jsxs)(`span`,{className:`text-[12.5px] font-semibold text-foreground/70 whitespace-nowrap shrink-0`,children:[Kd(e.amount,e.currency),e.kind===`subscription`&&e.interval?` / ${e.interval}`:``]}),(0,i.jsx)(Yd,{label:n.label,tone:n.tone})]},e.id)}),C&&(0,i.jsx)(t.Q,{busy:T,onClick:I,className:`self-center mt-1`,children:`Show older payments`})]}):(0,i.jsx)(`div`,{className:`flex items-center justify-center py-6 text-foreground/40`,children:(0,i.jsx)(t.ti,{className:`w-5 h-5 animate-spin text-accent`})})})]})})]})]})}var Zd=`w-[6.5rem] shrink-0`,Qd=`w-9 h-9 rounded-[var(--btn-radius,0.75rem)] border border-[var(--panel-border)] flex items-center justify-center shrink-0 text-foreground/45 hover:text-red-500 hover:border-red-500/40 hover:bg-red-500/[0.06] active:scale-[0.98] transition-all cursor-pointer`,$d=`date-field h-9 w-[10.5rem] shrink-0 px-3 text-[13px] font-semibold bg-transparent border border-[var(--panel-border)] text-foreground focus:outline-none focus:border-accent transition-colors`,ef={from:`09:00`,to:`13:00`};function tf(e,t){return{upcoming:e.filter(e=>e.date>=t),past:e.filter(e=>e.date<t)}}function nf({row:e,onChange:n,onRemove:r}){let a=e.windows.length===0,o=(t,r)=>n({...e,windows:e.windows.map((e,n)=>n===t?{...e,...r}:e)});return(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 py-2.5`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,i.jsx)(`input`,{type:`date`,value:e.date,"aria-label":`The date`,onChange:t=>n({...e,date:t.target.value}),className:$d,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`div`,{className:`w-[11rem] shrink-0`,children:(0,i.jsx)(t.sr,{ariaLabel:`${e.date} — how much of it`,value:a?`all`:`some`,options:[{value:`all`,label:`All day`},{value:`some`,label:`Only some hours`}],onChange:t=>n({...e,windows:t===`all`?[]:[ef]}),className:`console-select`,compact:!0,dense:!0,portal:!0,direction:`auto`})}),(0,i.jsx)(`button`,{type:`button`,title:`Remove ${e.date||`this date`}`,"aria-label":`Remove ${e.date||`this date`}`,onClick:r,className:`${Qd} ml-auto`,children:(0,i.jsx)(t._r,{className:`w-3.5 h-3.5`})})]}),!a&&(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 sm:pl-[0.125rem]`,children:[e.windows.map((r,a)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`div`,{className:Zd,children:(0,i.jsx)(t.sr,{ariaLabel:`${e.date} from${a?` (${a+1})`:``}`,value:r.from,options:t.Ot,onChange:e=>o(a,{from:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),(0,i.jsx)(`span`,{className:`w-3 text-center text-foreground/40 text-[13px] shrink-0 select-none`,children:`–`}),(0,i.jsx)(`div`,{className:Zd,children:(0,i.jsx)(t.sr,{ariaLabel:`${e.date} to${a?` (${a+1})`:``}`,value:r.to,options:t.Tt,onChange:e=>o(a,{to:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),e.windows.length>1&&(0,i.jsx)(`button`,{type:`button`,title:`Remove these hours on ${e.date}`,"aria-label":`Remove ${e.date} hours ${a+1}`,onClick:()=>n({...e,windows:e.windows.filter((e,t)=>t!==a)}),className:Qd,children:(0,i.jsx)(t._r,{className:`w-3.5 h-3.5`})})]},a)),e.windows.length<2&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>n({...e,windows:[...e.windows,{from:`14:00`,to:`18:00`}]}),className:`self-start h-6 px-1 text-[11.5px] font-semibold text-foreground/45 hover:text-accent transition-colors cursor-pointer`,children:`+ Add a second stretch`})]})]})}function rf({blocked:e,onChange:n,now:a}){let o=t.qn(a?a():new Date),[s,c]=(0,r.useState)(!1),{upcoming:l,past:u}=tf(e,o),d=s?[...u,...l]:l,f=(t,r)=>n(e.map(e=>e===t?r:e));return(0,i.jsx)(t.Z,{label:`Days away`,hint:`Dates this week's hours do not apply to — a holiday, a flight, an afternoon out. Nobody can book them, on any link on these hours.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-1`,children:[d.length===0?(0,i.jsx)(`p`,{className:`${t.$} py-3`,children:`No days blocked out. Add one for a holiday or a day off.`}):d.map((t,r)=>(0,i.jsx)(nf,{row:t,onChange:e=>f(t,e),onRemove:()=>n(e.filter(e=>e!==t))},`${t.date}-${r}`)),(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 py-2.5`,children:[(0,i.jsx)(t.Q,{icon:t.Ur,compact:!0,title:`Add a day away`,onClick:()=>n([...e,{date:o,windows:[]}]),children:`Add a date`}),u.length>0&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>c(e=>!e),className:`h-6 px-1 text-[11.5px] font-semibold text-foreground/45 hover:text-accent transition-colors cursor-pointer`,children:s?`Hide past dates`:`Show ${u.length} past date${u.length===1?``:`s`}`})]})]})})}var af=e=>t.xt.find(t=>t.value===e)?.label||`Short text`;function of({options:e,onChange:n}){return(0,i.jsx)(t.Z,{label:`Choices`,hint:`What people pick from.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.length===0&&(0,i.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug px-1`,children:`No choices yet — add the first one.`}),e.map((r,a)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`text`,value:r,"aria-label":`Choice ${a+1}`,placeholder:`e.g. At my place`,onChange:t=>n(e.map((e,n)=>n===a?t.target.value:e)),className:t.et}),(0,i.jsx)(t.Q,{icon:t._r,tone:`danger`,compact:!0,title:`Remove choice ${a+1}`,onClick:()=>n(e.filter((e,t)=>t!==a)),children:`Remove`})]},a)),(0,i.jsx)(`div`,{children:(0,i.jsx)(t.Q,{icon:t.Ur,onClick:()=>n([...e,``]),children:`Add choice`})})]})})}function sf({question:e,index:n,count:a,siblings:o,fixed:s,onChange:c,onMove:l,onRemove:u}){let[d,f]=(0,r.useState)(!e.label.trim()),p=e.label.trim()||`A new question`;return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 sm:gap-2.5 pr-2.5 sm:pr-3.5`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:()=>f(e=>!e),"aria-expanded":d,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3.5 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:p}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(`span`,{className:`${t.$} max-sm:hidden`,children:s?`Always asked`:`${af(e.type)}${e.required?` · must be answered`:``}`}),(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${d?`rotate-180`:``}`})]})]}),!s&&(0,i.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-1.5 shrink-0`,children:[(0,i.jsx)(t.Q,{icon:t.Ji,compact:!0,disabled:n===0,title:`Move ${p} up`,onClick:()=>l(-1),children:`Up`}),(0,i.jsx)(t.Q,{icon:t.Qi,compact:!0,disabled:n===a-1,title:`Move ${p} down`,onClick:()=>l(1),children:`Down`}),(0,i.jsx)(`span`,{className:`max-sm:hidden w-px h-5 bg-[var(--panel-border)] mx-0.5`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${p}`,onClick:u,children:`Remove`})]})]}),d&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.ft,{label:`What are you asking?`,hint:s?`The words above the box. Every booking asks this one — you can only change how it is put.`:`The words above the box, as the person booking reads them.`,value:e.label,placeholder:s?`e.g. Who is coming?`:`e.g. What is your phone number?`,onChange:n=>c({...e,label:n,name:s?e.name:t.tn(e,n,o)})}),!s&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.ct,{label:`Kind of answer`,hint:`Sets the box they type into. The example below follows what you pick.`,value:e.type,options:t.xt,allowEmpty:!1,onChange:n=>c({...e,type:n,options:n===`select`?e.options:[],placeholder:t.$t(e,n)})}),(0,i.jsx)(t.mt,{label:`Must be answered`,hint:`On means they cannot book until it is filled in.`,hintWideOnly:!0,enabled:e.required,onChange:t=>c({...e,required:t})})]}),e.type===`select`&&(0,i.jsx)(of,{options:e.options,onChange:t=>c({...e,options:t})}),t.en(e.type)&&(0,i.jsx)(t.ft,{label:`Example answer`,hint:e.type===`tel`?`Shown under the box — a phone box already starts with a dial code, so the example stands below it.`:`Faint grey words inside the empty box.`,value:e.placeholder,placeholder:t.bt[e.type]||`e.g. +1 555 0123`,onChange:t=>c({...e,placeholder:t})})]})]})}function cf({questions:e,onChange:n}){let r=e.filter(e=>t.vn(e.name)),a=e.filter(e=>!t.vn(e.name)),o=e=>n([...r,...e]);return(0,i.jsx)(t.Z,{label:`What does a booking ask for?`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-3.5`,children:[r.map(t=>(0,i.jsx)(sf,{question:t,index:0,count:1,siblings:e,fixed:!0,onChange:r=>n(e.map(e=>e.name===t.name?r:e)),onMove:()=>{},onRemove:()=>{}},t.name)),a.map((t,n)=>(0,i.jsx)(sf,{question:t,index:n,count:a.length,siblings:e,onChange:e=>o(a.map((t,r)=>r===n?e:t)),onMove:e=>{let t=n+e;if(t<0||t>=a.length)return;let r=[...a];[r[n],r[t]]=[r[t],r[n]],o(r)},onRemove:()=>o(a.filter((e,t)=>t!==n))},n)),(0,i.jsxs)(`div`,{className:`flex flex-col items-start sm:flex-row sm:items-center gap-3 rounded-2xl border border-dashed border-[var(--panel-border)] px-4 py-3.5`,children:[(0,i.jsx)(t.Q,{icon:t.Ur,title:`Add a question`,onClick:()=>o([...a,t.Vt()]),children:`Add a question`}),a.length===0&&(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:`Nothing else is asked — just a name and an email.`})]})]})})}var lf=(e,t,n=72)=>e>=n&&e<=Math.max(n,t*.45);function uf(e,t=340){if(!e)return null;let n=()=>{let t=e.getBoundingClientRect?.(),n=typeof window<`u`&&window.innerHeight||0;t&&n&&lf(t.top,n)||e.scrollIntoView?.({behavior:`smooth`,block:`start`})};return typeof setTimeout==`function`?setTimeout(n,t):(n(),null)}var df=`__new_payment__`;function ff(){let[e,n]=(0,r.useState)([]);return(0,r.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(t.Da,ji),e=>{let t=[];e.forEach(e=>{e.id!==`_settings`&&t.push(Ui(e.id,e.data()))}),n(t.filter(e=>e.kind===`once`).sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)))},()=>n([]));return()=>e()},[]),e}function pf({service:e,what:n,path:r,screen:a,children:o}){return e.loading?null:e.configured?e.on?(0,i.jsx)(i.Fragment,{children:o}):null:(0,i.jsxs)(`div`,{className:`rounded-2xl border border-accent/25 bg-accent/[0.05] px-4 py-3.5 flex flex-wrap items-center justify-between gap-x-4 gap-y-2`,children:[(0,i.jsxs)(`span`,{className:`text-[13px] font-medium text-foreground/70`,children:[`You do not have `,n,` set up yet.`]}),(0,i.jsxs)(c.Link,{to:r,className:`inline-flex items-center gap-1 text-[12px] font-bold text-accent hover:underline whitespace-nowrap`,children:[`Set it up on the `,a,` screen`,(0,i.jsx)(t.Xi,{className:`w-3 h-3`})]})]})}function mf({value:e,products:n,meetingName:a,canCreate:o,onChange:s,onCreate:c}){let[l,u]=(0,r.useState)(!1),[d,f]=(0,r.useState)(``),[p,m]=(0,r.useState)(``),[h,g]=(0,r.useState)(!1),_=[...n.map(e=>({value:e.id,label:`${Yi(e)} — ${Li(e).map(e=>e.amount).filter(Boolean).join(` + `)||`no price yet`}`})),...o?[{value:df,label:`+ A new one-time payment`}]:[]],v=n.find(t=>t.id===e),y=d.trim()&&Ri(d)===null?`Just a number, like 25.`:void 0;return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(t.ct,{label:`Payment for this meeting`,hint:v?`Taken on the booking page before the time is confirmed. Its price and its link are on the Payments screen.`:o?`Optional. A one-time payment taken on the booking page before the time is confirmed.`:n.length?`Optional. One of the payments your admin set up, taken on the booking page before the time is confirmed.`:`Your admin has not set up a payment to charge for a meeting yet.`,value:l?df:e,placeholder:`No payment`,options:_,onChange:e=>{if(e===`__new_payment__`){u(!0);return}u(!1),s(e)}}),l&&(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-3`,children:[(0,i.jsx)(t.ft,{label:`The price`,hint:`Just the number — 25 charges 25 in your Stripe account's currency. The payment is called ${a} and appears on the Payments screen too.`,value:d,onChange:e=>{f(e),p&&m(``)},placeholder:`25`,error:p||y}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(t.Q,{icon:t.Ur,busy:h,onClick:async()=>{if(Ri(d)===null){m(`Just a number for the price, like 25.`);return}m(``),g(!0);let e=await c(a,d.trim());if(g(!1),e){m(e);return}u(!1),f(``)},children:`Create it`}),(0,i.jsx)(t.Q,{onClick:()=>{u(!1),m(``),f(``)},children:`Never mind`})]})]})]})}function hf({link:e,onChange:n}){return(0,i.jsx)(t.Z,{label:`Emails about bookings`,hint:`Sent the moment a time is taken. Every booking is in your Inbox and on the calendar regardless.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5`,children:[(0,i.jsx)(t.mt,{label:`Email me when someone books`,hint:`A note at your address — the sale alert, when they paid.`,hintWideOnly:!0,enabled:e.notifyOwner,onChange:e=>n({notifyOwner:e})}),(0,i.jsx)(t.mt,{label:`Email them a confirmation`,hint:`Their receipt when they pay. For a free booking, a note that the time is theirs — to people who book signed in.`,hintWideOnly:!0,enabled:e.confirmBooker,onChange:e=>n({confirmBooker:e})})]})})}var gf=e=>{let n={...t.A(t.I(),e),createdAt:Date.now()};return{...n,name:t.Rt(n),description:t.Lt(n)}};function _f({link:e,schedules:n,products:r,services:a,isAdmin:o=!0,onChange:s,onCreatePayment:c}){let l=n.find(t=>t.id===e.scheduleId),u=t=>s({...e,...t}),d=t.N(e,l),f=l?t.j(e,l):null,p=n=>{let r={...e,...n};return{...n,...e.name.trim()===t.Rt(e)?{name:t.Rt(r)}:{},...e.description.trim()===t.Lt(e)?{description:t.Lt(r)}:{}}};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.ct,{label:`Which hours is it booked in?`,hint:`Change the hours and every meeting booked in them changes with it — one holiday, entered once, closes them all.`,value:e.scheduleId,options:n.map(e=>({value:e.id,label:t.pn(e)})),allowEmpty:!1,onChange:t=>{let r=n.find(e=>e.id===t);if(!r)return;let i=!l||e.memberName.trim()===l.memberName.trim();u(p({scheduleId:r.id,memberId:r.memberId,...i?{memberName:r.memberName}:{}}))}}),(0,i.jsx)(t.ft,{label:`What is it called?`,hint:`Visitors read this on the booking page. It starts named after its length — call it whatever you like. Left blank it goes back to ${t.Rt(e)}.`,value:e.name,onChange:e=>u({name:e}),placeholder:t.Rt(e)}),(0,i.jsx)(t.dt,{label:`A line or two about it`,hint:`Visitors read it under the name — what it is for, what to bring, what happens after. Emptied, the booking page simply shows none.`,value:e.description,onChange:e=>u({description:e}),placeholder:`A first conversation about what you need and how I can help.`}),(0,i.jsx)(t.ft,{label:`The name visitors see`,value:e.memberName,onChange:e=>u(p({memberName:e})),placeholder:`Anna`}),(0,i.jsx)(t.ct,{label:`How long is one booking?`,value:String(e.slotMinutes),options:t.Mt,allowEmpty:!1,onChange:e=>u(p({slotMinutes:Number(e)}))}),(0,i.jsx)(t.ct,{label:`How far ahead can people book?`,value:String(e.horizonDays),options:t.kt,allowEmpty:!1,onChange:e=>u({horizonDays:Number(e)})}),(0,i.jsx)(t.ct,{label:`How much notice do you need?`,value:String(e.noticeHours),options:t.At,allowEmpty:!1,onChange:e=>u({noticeHours:Number(e)})}),(0,i.jsx)(cf,{questions:e.questions,onChange:e=>u({questions:e})}),(0,i.jsx)(pf,{service:a.payments,what:`Stripe`,path:`/payments`,screen:`Payments`,children:(0,i.jsx)(mf,{value:e.paymentId,products:r,meetingName:t.F(e),canCreate:o,onChange:e=>u({paymentId:e}),onCreate:async(e,t)=>{let n=await c(e,t);return n&&n.startsWith(`p_`)?(u({paymentId:n}),null):n||`The payment could not be made — make sure you are signed in as an admin and try again.`}})}),(0,i.jsx)(pf,{service:a.email,what:`emails`,path:`/email`,screen:`Email`,children:(0,i.jsx)(hf,{link:e,onChange:u})}),(0,i.jsx)(t.Z,{label:`Booking link`,hint:f&&!d&&e.enabled?`Send it to anyone. They see the free times in their own time zone, pick one and book — and pay first, when a payment is attached.`:`The link opens once the meeting is complete and turned on.`,children:(0,i.jsx)(eu,{title:t.F(e),path:t.Qt(e.id)})}),(0,i.jsx)(`div`,{className:`pt-1`,children:d?e.enabled?(0,i.jsxs)(`span`,{className:`text-[11.5px] font-semibold text-amber-500`,children:[`Turned on, but not bookable yet — `,d]}):(0,i.jsx)(`span`,{className:t.$,children:d}):e.enabled?(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Bookable — send the link, pick it on a page under Booking on this page, or add a Pick-a-time question to a form.`}):(0,i.jsx)(`span`,{className:t.$,children:`Complete — flip the switch at the top of the row to offer it.`})})]})}function vf({link:e,schedules:n,products:a,services:o,isAdmin:s=!0,open:c,fresh:l,error:u,onToggle:d,onChange:f,onRemove:p,onCreatePayment:m}){let h=n.find(t=>t.id===e.scheduleId),g=t.M(e,h),[_,v]=(0,r.useState)(!1),y=t.F(e),b=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!l)return;let e=uf(b.current);return()=>{e&&clearTimeout(e)}},[l]),(0,i.jsxs)(`div`,{ref:b,className:`scroll-mt-4 rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 sm:gap-2.5 pr-3`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:d,"aria-expanded":c,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:t.P(e,h)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:(0,i.jsx)(t.lt,{state:g.state,label:g.label})}),(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${c?`rotate-180`:``}`})]})]}),(0,i.jsx)(t.pt,{enabled:e.enabled,onChange:t=>f({...e,enabled:t}),label:`${y} — can be booked`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${y}`,onClick:()=>v(!0),children:`Remove`})]}),(0,i.jsx)(Ve,{isOpen:_,title:`Remove ${y}?`,message:`Its booking link stops working and it leaves every page and form it was picked on. The hours it was booked in stay, and so do the bookings already taken.`,confirmText:`Yes, remove`,cancelText:`Keep it`,onCancel:()=>v(!1),onConfirm:()=>{v(!1),p()}}),c&&(0,i.jsx)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:(0,i.jsx)(_f,{link:e,schedules:n,products:a,services:o,isAdmin:s,onChange:f,onCreatePayment:m})}),u&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-4 pb-3`,children:u})]})}function yf({isAdmin:e=!0}={}){let{user:n}=t.na(),{loading:a,docs:s}=t.b(),c=ff(),l={payments:cd(`payments`),email:cd(`email`)},[u,d]=(0,r.useState)({}),[f,p]=(0,r.useState)([]),[m,h]=(0,r.useState)(null),[g,_]=(0,r.useState)(null),[v,y]=(0,r.useState)({}),b=(0,r.useRef)(new Map),x=n?.uid||``,S=(0,r.useMemo)(()=>[...e?s.schedules:s.schedules.filter(e=>e.memberId===x)].sort((e,t)=>Number(t.memberId===x)-Number(e.memberId===x)),[s.schedules,e,x]),C=(0,r.useMemo)(()=>{let t=new Map(s.links.map(e=>[e.id,e]));for(let e of Object.values(u))t.set(e.id,e);for(let e of f)t.delete(e);return[...t.values()].filter(t=>e||t.memberId===x).sort((e,t)=>Number(t.memberId===x)-Number(e.memberId===x)||(e.createdAt||0)-(t.createdAt||0)||e.id.localeCompare(t.id))},[s.links,u,f,e,x]),w=e=>{let n=b.current.get(e.id);n&&clearTimeout(n),b.current.set(e.id,setTimeout(async()=>{b.current.delete(e.id);let n=await t.d(e);y(t=>{let r={...t};return n?r[e.id]=n:delete r[e.id],r})},600))},T=e=>{d(t=>({...t,[e.id]:e})),w(e)},E=()=>{let e=S.find(e=>e.memberId===x)||S[0];if(!e)return;let t=gf(e);d(e=>({...e,[t.id]:t})),h(t.id),_(t.id),w(t)},D=async e=>{let n=b.current.get(e);n&&(clearTimeout(n),b.current.delete(e)),d(t=>{let n={...t};return delete n[e],n}),p(t=>[...t,e]),m===e&&h(null);let r=await t.l(e);r&&(p(t=>t.filter(t=>t!==e)),y(t=>({...t,[e]:r})))},O=async(e,n)=>{let r={...Ii(`p_${Date.now().toString(36)}`),kind:`once`,items:[{name:e,amount:n}]};try{let{id:e,...n}=r;return await(0,o.setDoc)((0,o.doc)(t.Da,ji,e),n),e}catch(e){return console.error(`Could not make the payment`,e),null}};return(0,i.jsx)(t.at,{icon:t.ii,title:`Booking links`,description:`One per kind of meeting — pick the hours it is booked in, say how long it lasts and what it asks, and send the link.`,actions:!a&&S.length>0?({open:e})=>(0,i.jsx)(t.Q,{icon:t.Ur,compact:!0,title:`Add a booking link`,onClick:()=>{e(),E()},children:`Add a booking link`}):void 0,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:a?(0,i.jsx)(`p`,{className:t.$,children:`Loading your booking links…`}):S.length===0?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Add a schedule above first — a booking link is a meeting booked in somebody's hours, so there have to be hours to put it on.`}):C.length===0?(0,i.jsxs)(`p`,{className:`${t.$} px-1`,children:[`No booking link yet — press Add a booking link. It is what turns `,t.mn(S[0]),` into something people can book.`]}):C.map(t=>(0,i.jsx)(vf,{link:t,schedules:S,products:c,services:l,isAdmin:e,open:m===t.id,fresh:g===t.id,error:v[t.id],onToggle:()=>h(m===t.id?null:t.id),onChange:T,onRemove:()=>D(t.id),onCreatePayment:O},t.id))})})}var bf=(e,n=`host`)=>e.heldOnly?`Held time`:n===`booker`?e.scheduleName.trim()||`A meeting`:t.cn(e),xf=(e,t=`host`)=>e.heldOnly?`Held with no booking behind it`:e.own?`Your own event`:t===`booker`?e.memberName.trim()?`With ${e.memberName.trim()}`:`Booked`:e.scheduleName||e.email||`Booked`,Sf=(e,n=`host`)=>n===`booker`&&!e.heldOnly?t.Yt(e):bf(e,n),Cf=e=>!e.pending||e.cancelled||e.own||e.heldOnly?``:e.partySize>1?`${e.partyAccepted} of ${e.partySize}`:`Pending`;function wf({value:e,onChange:n}){return(0,i.jsx)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:t.Et.map(r=>{let a=r.value===e;return(0,i.jsx)(`button`,{type:`button`,title:r.label,"aria-label":r.label,"aria-pressed":a,onClick:()=>n(r.value),className:`w-8 h-8 rounded-full transition-all cursor-pointer active:scale-95 flex items-center justify-center ${r.value?`border-2`:`border-2 border-dashed`} ${a?`scale-105`:`hover:scale-105`}`,style:{background:t.ln(r.value,a?55:30),borderColor:a?t.sn(r.value):t.ln(r.value,40)},children:a&&(0,i.jsx)(`span`,{className:`w-2 h-2 rounded-full`,style:{background:t.sn(r.value)}})},r.value||`theme`)})})}function Tf({className:e=``}){return(0,i.jsx)(`span`,{className:`inline-flex items-center h-[18px] px-1.5 rounded-md shrink-0 border border-red-500/25 bg-red-500/10 text-[10px] font-bold uppercase tracking-[0.08em] text-red-500/90 ${e}`,children:`Cancelled`})}function Ef({label:e=`Pending`,className:t=``}){return(0,i.jsx)(`span`,{title:`Waiting to be accepted`,className:`inline-flex items-center h-[18px] px-1.5 rounded-md shrink-0 border border-amber-500/25 bg-amber-500/10 text-[10px] font-bold uppercase tracking-[0.08em] text-amber-600 dark:text-amber-400 ${t}`,children:e})}function Df({className:e=``}){return(0,i.jsx)(`span`,{title:`Held with nothing booked`,className:`inline-flex items-center h-[18px] px-1.5 rounded-md shrink-0 border border-[var(--panel-border)] bg-foreground/[0.04] text-[10px] font-bold uppercase tracking-[0.08em] text-foreground/45 ${e}`,children:`Held`})}function Of({booking:e,zone:n,chip:r,withMember:a=!1,side:o=`host`,onOpen:s,now:c}){let l=e.end<(c?c():new Date).toISOString(),u=e.cancelled,d=Cf(e),f=e.color;return(0,i.jsxs)(`button`,{type:`button`,onClick:s,"aria-label":`${t.dn(new Date(e.start),n)} — ${bf(e,o)}${u?` (cancelled)`:``}`,className:`group relative w-full text-left rounded-2xl border overflow-hidden flex items-stretch gap-2.5 p-2.5 transition-all cursor-pointer active:scale-[0.99] ${l&&!u?`opacity-60`:``} ${u||e.heldOnly?`border-dashed border-[var(--panel-border)]/60 bg-foreground/[0.02]`:``}`,style:u||e.heldOnly?void 0:{background:t.ln(f,7),borderColor:t.ln(f,26)},children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-1 rounded-full shrink-0 ${u||e.heldOnly?`bg-foreground/15`:``}`,style:u||e.heldOnly?void 0:{background:t.ln(f,85)}}),(0,i.jsx)(`span`,{"aria-hidden":!0,className:`absolute inset-0 bg-foreground/0 group-hover:bg-foreground/[0.04] transition-colors`}),(0,i.jsxs)(`span`,{className:`relative flex-1 min-w-0 flex flex-col gap-0.5 py-0.5`,children:[(0,i.jsxs)(`span`,{className:`flex items-baseline gap-2 min-w-0`,children:[(0,i.jsx)(`span`,{className:`text-[12.5px] font-bold tabular-nums shrink-0 ${u?`text-foreground/45 line-through`:`text-foreground`}`,children:t.dn(new Date(e.start),n)}),(0,i.jsx)(`span`,{className:`text-[12.5px] font-semibold truncate ${u?`text-foreground/45 line-through`:`text-foreground/80`}`,children:bf(e,o)})]}),(0,i.jsxs)(`span`,{className:`flex items-center justify-between gap-2 min-w-0`,children:[(0,i.jsx)(`span`,{className:`text-[11.5px] font-medium text-foreground/45 truncate`,children:a&&e.memberName?`${e.memberName} · ${xf(e,o)}`:xf(e,o)}),u?(0,i.jsx)(Tf,{}):e.heldOnly?(0,i.jsx)(Df,{}):d?(0,i.jsx)(Ef,{label:d}):r&&(0,i.jsx)(t.lt,{state:r.state,label:r.label})]})]})]})}var kf=e=>{let t=e.replace(/_/g,` `).trim();return t.charAt(0).toUpperCase()+t.slice(1)};function Af(e,t){let n=e.memberName.trim();if(e.partySize>1){let n=`${e.partyAccepted} of ${e.partySize} have accepted.`;return t?`${n} Yours is still to come.`:n}return t?`This is waiting for you to accept.`:n?`Waiting for ${n} to accept.`:`Waiting to be accepted.`}function jf(e){let t=e.memberName.trim();return e.partySize>1?e.partyAccepted>0?`${e.partyAccepted} of ${e.partySize} have confirmed so far. You will hear once they all have.`:`Waiting to be confirmed. You will hear as soon as it is.`:t?`Waiting for ${t} to confirm. You will hear as soon as they do.`:`Waiting to be confirmed. You will hear as soon as it is.`}function Mf({open:e,onClose:n,children:a}){return(0,r.useEffect)(()=>{if(!e)return;let t=e=>{e.key===`Escape`&&n()};return window.addEventListener(`keydown`,t),()=>window.removeEventListener(`keydown`,t)},[e,n]),(0,i.jsx)(t.pr,{children:e&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:n,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/80 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(t.fr.div,{role:`dialog`,"aria-modal":`true`,initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`w-full max-w-[420px] max-h-[85vh] overflow-y-auto styled-scrollbars-mini p-5 sm:p-6 rounded-3xl glass-popover border border-[var(--panel-border)] shadow-2xl relative z-10 text-left`,children:a})]})})}function Nf({color:e,title:n,line:r,cancelled:a,onClose:o}){return(0,i.jsxs)(`div`,{className:`flex items-start gap-3 mb-4`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-1 self-stretch rounded-full shrink-0 ${a?`bg-foreground/15`:``}`,style:a?void 0:{background:t.ln(e,85)}}),(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,i.jsx)(`h3`,{className:`text-[17px] font-extrabold tracking-tight leading-tight break-words ${a?`text-foreground/50 line-through`:`text-foreground`}`,children:n}),a&&(0,i.jsx)(Tf,{})]}),(0,i.jsx)(`p`,{className:`text-[12.5px] font-medium text-foreground/50 leading-snug mt-0.5`,children:r})]}),(0,i.jsx)(`button`,{type:`button`,onClick:o,"aria-label":`Close`,className:t.R,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]})}function Pf({label:e,children:t}){return(0,i.jsxs)(`div`,{className:`flex items-start justify-between gap-3 px-3.5 py-2.5`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 shrink-0`,children:e}),(0,i.jsx)(`span`,{className:`text-[12.5px] font-semibold text-foreground/80 text-right break-words min-w-0`,children:t})]})}function Ff({booking:e,zone:n,chip:a,me:o=``,side:s=`host`,onClose:c,onColor:l,onAccept:u,onCancel:d,onDelete:f,onRelease:p}){let[m,h]=(0,r.useState)(!1),[g,_]=(0,r.useState)(!1),[v,y]=(0,r.useState)(``),[b,x]=(0,r.useState)(!1),[S,C]=(0,r.useState)(``),w=t.Hn(e,n),T=e.end<new Date().toISOString(),E=!e.own&&e.timeZone&&e.timeZone!==n?e.timeZone:``,D=Object.entries(e.answers).filter(([,e])=>e),O=s===`booker`,k=!e.heldOnly&&(D.length>0||!!E||!!a||!O&&!e.own&&(!!e.scheduleName||!!e.email||e.createdAt>0)),A=e.heldOnly,j=!A&&(e.own||e.cancelled||T),M=!O&&!!o&&e.memberId===o,N=Cf(e),P=!!N&&M&&!!u,F=A?`Free this held time`:e.own?`Delete this event`:e.cancelled?`Remove this cancelled booking`:T?`Remove this booking`:N&&M?`Decline this booking`:`Cancel this booking`,I=A?!!p:j&&!!f,L=!j&&!A,R=!!N&&M&&!j;return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(Mf,{open:!0,onClose:c,children:[(0,i.jsx)(Nf,{color:e.color,title:Sf(e,s),line:`${w.day} · ${w.time}`,cancelled:e.cancelled,onClose:c}),e.cancelled&&(0,i.jsxs)(`div`,{className:`mb-4 px-3.5 py-2.5 rounded-2xl border border-[var(--panel-border)] bg-foreground/[0.03] flex flex-col gap-1.5`,children:[(0,i.jsxs)(`p`,{className:`text-[12.5px] font-medium text-foreground/70 leading-snug`,children:[If(e),` The time is free again — it stays here so you have the record.`]}),!!e.cancelReason&&(0,i.jsxs)(`p`,{className:`text-[12.5px] font-semibold text-foreground/80 leading-snug border-l-2 border-[var(--panel-border)] pl-2.5`,children:[`“`,e.cancelReason,`”`]})]}),!!N&&(0,i.jsxs)(`div`,{className:`mb-4 px-3.5 py-3 rounded-2xl border border-amber-500/25 bg-amber-500/[0.07] flex flex-col gap-2.5`,children:[(0,i.jsxs)(`div`,{className:`flex items-start gap-2.5`,children:[(0,i.jsx)(t.ki,{className:`w-4 h-4 shrink-0 mt-[1px] text-amber-600 dark:text-amber-400`,"aria-hidden":!0}),(0,i.jsx)(`p`,{className:`text-[12.5px] font-semibold text-foreground/75 leading-snug flex-1 min-w-0`,children:O?jf(e):Af(e,M)}),e.partySize>1&&(0,i.jsx)(Ef,{label:N})]}),P&&!g&&(0,i.jsxs)(t.cr,{onClick:async()=>{x(!0),C(``);let e=await u();x(!1),e&&C(e)},isLoading:b,className:`py-2 px-4 text-[13px] font-bold rounded-xl self-start`,children:[(0,i.jsx)(t.zi,{className:`w-3.5 h-3.5 shrink-0`,"aria-hidden":!0}),`Accept`]})]}),A&&(0,i.jsx)(`p`,{className:`mb-4 px-3.5 py-2.5 rounded-2xl border border-[var(--panel-border)] bg-foreground/[0.03] text-[12.5px] font-medium text-foreground/70 leading-snug`,children:`This hour is held with no booking behind it — a booking that was started and never finished. Nobody can take the time until it is freed, and there is nothing here to cancel.`}),k&&(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 bg-foreground/[0.015] divide-y divide-[var(--panel-border)]/40`,children:[!O&&!e.own&&e.scheduleName&&(0,i.jsx)(Pf,{label:`Meeting`,children:e.scheduleName}),!O&&e.email&&(0,i.jsx)(Pf,{label:`Email`,children:(0,i.jsx)(`a`,{href:`mailto:${e.email}`,className:`text-accent hover:underline break-all`,children:e.email})}),D.map(([e,n])=>(0,i.jsx)(Pf,{label:e===`note`?`Note`:kf(e),children:t.rr(n)?(0,i.jsx)(`span`,{className:`flex flex-col items-end gap-1 min-w-0`,children:t.nr(n).map(e=>(0,i.jsxs)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,title:t.tr(e),className:`inline-flex items-center gap-1.5 max-w-full min-w-0 text-accent hover:underline`,children:[(0,i.jsx)(t.qr,{className:`w-3.5 h-3.5 shrink-0`}),(0,i.jsx)(`span`,{className:`truncate min-w-0`,children:t.tr(e)})]},e))}):n},e)),E&&(0,i.jsxs)(Pf,{label:O?`The time you booked in`:`Their time`,children:[t.dn(new Date(e.start),E),` — `,t.Kn(E)]}),a&&(0,i.jsx)(Pf,{label:`Payment`,children:(0,i.jsx)(t.lt,{state:a.state,label:a.label})}),!O&&!e.own&&e.createdAt>0&&(0,i.jsx)(Pf,{label:`Booked`,children:new Intl.DateTimeFormat(void 0,{dateStyle:`medium`}).format(new Date(e.createdAt))})]}),!e.cancelled&&!A&&!!l&&(0,i.jsxs)(`div`,{className:`mt-4 flex flex-col gap-2`,children:[(0,i.jsx)(`span`,{className:`text-[12.5px] sm:text-[13px] font-medium text-foreground/50 select-none ml-1`,children:`Colour`}),(0,i.jsx)(wf,{value:e.color,onChange:async e=>{C(``);let t=await l(e);t&&C(t)}}),(0,i.jsx)(`p`,{className:`text-[11px] font-medium text-foreground/40 leading-snug ml-1 mt-0.5`,children:`Shown on the calendar and in the day beside it.`})]}),g&&(0,i.jsxs)(`div`,{className:`mt-4 flex flex-col gap-3 p-3.5 rounded-2xl border border-[var(--panel-border)] bg-foreground/[0.02]`,children:[(0,i.jsx)(t.dt,{label:R?`Why are you turning it down?`:O?`Why can you not make it?`:`Why are you cancelling?`,value:v,onChange:y,placeholder:O?`Something has come up — I would like to book another time.`:`Something has come up and I cannot make this time — do book another.`,hint:O?`${e.memberName.trim()||`Whoever you booked with`} will see this.`:`${e.name.trim()||`Whoever booked`} will see this on the meeting.`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,i.jsx)(t.cr,{variant:`secondary`,onClick:()=>{_(!1),C(``)},disabled:b,className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl`,children:`Keep it`}),(0,i.jsx)(t.cr,{onClick:async()=>{x(!0),C(``);let e=await d(v.trim());if(x(!1),e){C(e);return}_(!1),c()},isLoading:b,disabled:!v.trim(),className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl bg-red-500 hover:bg-red-600 border-none text-white shadow-lg hover:shadow-red-500/20 disabled:opacity-40 disabled:hover:bg-red-500 disabled:hover:shadow-none`,children:R?`Decline it`:`Cancel it`})]})]}),!g&&!L&&!I&&!O&&!A&&(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug mt-4 ml-1`,children:`Nothing left to do here — only an admin can take a booking off the calendar for good.`}),!!S&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 mt-3 ml-1`,children:S}),!g&&(0,i.jsxs)(`div`,{className:`mt-5 flex items-center gap-3 ${I||L?`justify-between`:`justify-end`}`,children:[(I||L)&&(0,i.jsx)(t.Q,{icon:I?t.Or:t.Hi,tone:`danger`,title:F,onClick:()=>I?h(!0):_(!0),children:A?`Free the time`:e.own?`Delete`:I?`Remove`:R?`Decline`:`Cancel booking`}),(0,i.jsx)(t.cr,{variant:`secondary`,onClick:c,className:`py-2 px-4 text-[13px] font-bold rounded-xl`,children:`Close`})]})]}),(0,i.jsx)(Ve,{isOpen:m,title:`${F}?`,message:A?`The hour goes back on offer. There is no booking behind it, so nothing else is lost.`:e.own?`It leaves your calendar and the time can be booked again.`:`It goes from the calendar for good, with everything it holds — in every diary it was booked into. This cannot be undone.`,confirmText:A?`Yes, free it`:e.own?`Yes, delete`:`Yes, remove`,cancelText:`Keep it`,isProcessing:b,onCancel:()=>h(!1),onConfirm:async()=>{x(!0);let e=await(A?p?.()??null:f?.()??null);x(!1),h(!1),e?C(e):c()}})]})}function If(e){let t=e.cancelledAt>0?` on ${new Intl.DateTimeFormat(void 0,{dateStyle:`medium`}).format(new Date(e.cancelledAt))}`:``,n=e.cancelledBy.trim();return e.cancelledSide===`booker`?`${n||`The person who booked`} cancelled this${t}.`:e.cancelledSide===`host`?`${n||`Your team`} cancelled this${t}.`:`This booking was cancelled${t}.`}var Lf=(e,n,r,i)=>({title:``,time:e===i?t.Tn(r,n):`09:00`,minutes:`60`,color:``,note:``});function Rf({dateKey:e,dayLabel:n,zone:a,today:o,now:s,onClose:c,onAdd:l}){let[u,d]=(0,r.useState)(()=>Lf(e,a,s?s():new Date,o)),[f,p]=(0,r.useState)(!1),[m,h]=(0,r.useState)(``),g=e=>d(t=>({...t,...e}));return(0,i.jsxs)(Mf,{open:!0,onClose:c,children:[(0,i.jsx)(Nf,{color:u.color,title:u.title.trim()||`Add an event`,line:`${n} · your time, ${t.Kn(a)}`,onClose:c}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3.5`,children:[(0,i.jsx)(t.ft,{label:`What is it?`,value:u.title,onChange:e=>g({title:e}),placeholder:`Lunch with Sam`,hint:`Leave it empty and the time simply shows as busy.`}),(0,i.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,i.jsx)(t.ct,{label:`Starts at`,value:u.time,onChange:e=>g({time:e}),options:t.jt,allowEmpty:!1}),(0,i.jsx)(t.ct,{label:`Lasts`,value:u.minutes,onChange:e=>g({minutes:e}),options:t.Dt,allowEmpty:!1})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsx)(`span`,{className:`${t.nt} ml-1`,children:`Colour`}),(0,i.jsx)(wf,{value:u.color,onChange:e=>g({color:e})})]}),(0,i.jsx)(t.dt,{label:`Note`,value:u.note,onChange:e=>g({note:e}),placeholder:`Anything to remember`})]}),(0,i.jsx)(`p`,{className:`text-[11.5px] font-medium text-foreground/40 leading-snug mt-3 ml-1`,children:`Nobody can book this time once it is here.`}),!!m&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 mt-3 ml-1`,children:m}),(0,i.jsxs)(`div`,{className:`mt-5 flex items-center gap-3`,children:[(0,i.jsx)(t.cr,{variant:`secondary`,onClick:c,disabled:f,className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl`,children:`Cancel`}),(0,i.jsx)(t.cr,{onClick:async()=>{p(!0),h(``);let n=t.Qn(e,u.time,a),r=new Date(n.getTime()+Number(u.minutes)*6e4),i=await l({title:u.title.trim(),start:n.toISOString(),end:r.toISOString(),color:u.color,note:u.note.trim()});p(!1),i?h(i):c()},isLoading:f,className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl`,children:`Add it`})]})]})}var zf=(e,t)=>new Intl.DateTimeFormat(t,{timeZone:`UTC`,weekday:`short`,day:`numeric`,month:`long`}).format(new Date(`${e}T00:00:00Z`)),Bf=[`M`,`T`,`W`,`T`,`F`,`S`,`S`],Vf=e=>e.slice(0,7),Hf=(e,n,r)=>t.dn(e,n,r).replace(/[\s\u00a0\u202f]+/g,``).toLowerCase();function Uf(e,t=3){return e.length<=t?{shown:e,extra:0}:{shown:e.slice(0,t-1),extra:e.length-(t-1)}}var Wf=(e,t,n=`host`)=>n===`booker`?Sf(e,n):t&&e.memberName?`${bf(e)} · ${e.memberName}`:bf(e);function Gf(e,n){let r=new Map;for(let i of e){let e=t.Zn(new Date(i.start),n).dateKey,a=r.get(e)||[];a.push(i),r.set(e,a)}for(let e of r.values())e.sort((e,t)=>e.start.localeCompare(t.start));return r}function Kf(e,t,n=!0){return!n||!e.paymentId&&!e.paymentSession?null:e.paymentSession?t===void 0?{state:`saving`,label:`Checking payment`}:t?{state:`saved`,label:`Paid`}:{state:`off`,label:`Awaiting payment`}:{state:`off`,label:`Not paid`}}var qf=`h-8 px-3 rounded-xl border border-[var(--panel-border)]/60 inline-flex items-center gap-1.5 text-[12.5px] font-semibold text-foreground/60 hover:text-foreground hover:border-accent/40 hover:bg-foreground/5 active:scale-[0.98] transition-all cursor-pointer`;function Jf({bookings:e,zone:n,paid:a,openBookingId:o,onOpened:s,withMember:c=!1,me:l=``,side:u=`host`,onAccept:d,onCancel:f,onDelete:p,canDelete:m,onColor:h,onRelease:g,onAdd:_,now:v}){let y=t.Zn(v?v():new Date,n).dateKey,b=(0,r.useMemo)(()=>Gf(e,n),[e,n]),[x,S]=(0,r.useState)(Vf(y)),[C,w]=(0,r.useState)(y),[T,E]=(0,r.useState)(null),[D,O]=(0,r.useState)(!1),k=(0,r.useRef)(``);(0,r.useEffect)(()=>{if(!o){k.current=``;return}if(k.current===o)return;let r=e.find(e=>e.id===o);if(!r)return;k.current=o;let i=t.Zn(new Date(r.start),n).dateKey;S(Vf(i)),w(i),E(r.id),s?.()},[o,e,n,s]);let A=t.U(x),j=b.get(C)||[],M=(v?v():new Date).toISOString(),N=zf(C),P=T?e.find(e=>e.id===T):void 0,{ref:F,moreBelow:I}=t.W(j.length,C);return(0,i.jsxs)(`div`,{className:`flex flex-col md:flex-row gap-3 md:gap-4 w-full md:items-stretch`,children:[(0,i.jsxs)(`div`,{className:`${t.B} w-full md:flex-1 min-w-0`,children:[(0,i.jsxs)(`div`,{className:t.V,children:[(0,i.jsx)(`h4`,{className:`text-[14px] font-bold text-foreground tracking-tight truncate`,children:t.wn(x)}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 shrink-0`,children:[(0,i.jsx)(`button`,{type:`button`,onClick:()=>{S(Vf(y)),w(y)},className:qf,children:`Today`}),(0,i.jsx)(`button`,{type:`button`,"aria-label":`Previous month`,onClick:()=>S(e=>t.Rn(e,-1)),className:t.R,children:(0,i.jsx)(t.Li,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{type:`button`,"aria-label":`Next month`,onClick:()=>S(e=>t.Rn(e,1)),className:t.R,children:(0,i.jsx)(t.Ii,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`p-2 sm:p-3`,children:(0,i.jsxs)(`div`,{className:`grid grid-cols-7 gap-1`,role:`grid`,"aria-label":t.wn(x),children:[Bf.map((e,t)=>(0,i.jsx)(`div`,{className:`text-center text-[10.5px] font-bold uppercase tracking-wider text-foreground/35 pb-1`,children:e},t)),A.map((e,r)=>{if(!e)return(0,i.jsx)(`div`,{"aria-hidden":!0},`blank-${r}`);let a=b.get(e)||[],{shown:o,extra:s}=Uf(a),l=e===C,d=e===y;return(0,i.jsxs)(`button`,{type:`button`,role:`gridcell`,"aria-label":`${e}${a.length?`, ${a.length} booked`:``}`,"aria-selected":l,onClick:()=>w(e),className:`relative flex flex-col items-center sm:items-stretch justify-center sm:justify-start h-10 sm:h-[86px] rounded-xl sm:p-1 text-left transition-all cursor-pointer border ${l?`border-accent/70 bg-accent/[0.08] shadow-sm shadow-accent/10`:a.length?`border-transparent hover:bg-foreground/[0.05] hover:border-[var(--panel-border)]/60`:`border-transparent hover:bg-foreground/[0.03]`} ${d&&!l?`ring-1 ring-inset ring-accent/45`:``}`,children:[(0,i.jsx)(`span`,{className:`text-[13px] tabular-nums leading-none sm:px-1 sm:pt-0.5 sm:pb-1 ${l||d?`font-bold text-accent`:a.length?`font-bold text-foreground`:`font-semibold text-foreground/35`}`,children:Number(e.slice(8,10))}),(0,i.jsxs)(`span`,{"aria-hidden":!0,className:`max-sm:hidden sm:flex flex-col gap-[2px] w-full min-w-0`,children:[o.map(e=>(0,i.jsxs)(`span`,{className:`flex items-center gap-1 min-w-0 rounded-md pr-1 py-[2px] leading-[1.2] overflow-hidden ${e.end<M&&!e.cancelled?`opacity-50`:``} ${e.cancelled?`bg-foreground/[0.04] line-through`:``}`,style:e.cancelled?void 0:{background:t.ln(e.color,12)},children:[(0,i.jsx)(`span`,{className:`w-[3px] self-stretch rounded-full shrink-0 ${e.cancelled?`bg-foreground/15`:``}`,style:e.cancelled?void 0:{background:t.ln(e.color,85)}}),(0,i.jsx)(`span`,{className:`text-[9.5px] font-bold tabular-nums shrink-0 ${e.cancelled?`text-foreground/40`:`text-foreground/85`}`,children:Hf(new Date(e.start),n)}),(0,i.jsx)(`span`,{className:`text-[9.5px] font-medium truncate ${e.cancelled?`text-foreground/40`:`text-foreground/60`}`,children:Wf(e,c,u)})]},e.id)),s>0&&(0,i.jsxs)(`span`,{className:`px-1 text-[9.5px] font-bold text-foreground/45 leading-[1.2]`,children:[`+`,s,` more`]})]})]},e)})]})})]}),(0,i.jsx)(`div`,{className:`w-full md:w-[320px] shrink-0 md:relative md:min-h-[360px]`,children:(0,i.jsxs)(`div`,{className:`${t.B} flex flex-col md:absolute md:inset-0`,children:[(0,i.jsxs)(`div`,{className:t.V,children:[(0,i.jsx)(`p`,{className:`text-[13px] font-bold text-foreground tracking-tight truncate`,children:N}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[j.length>0&&(0,i.jsxs)(`span`,{className:`text-[11.5px] font-semibold text-foreground/40 tabular-nums max-sm:hidden`,children:[j.length,` `,j.length===1?`event`:`events`]}),_&&(0,i.jsxs)(`button`,{type:`button`,onClick:()=>O(!0),title:`Add an event on ${N}`,className:qf,children:[(0,i.jsx)(t.Ur,{className:`w-3.5 h-3.5 shrink-0`}),`Add`]})]})]}),(0,i.jsxs)(`div`,{className:`relative flex-1 min-h-0`,children:[(0,i.jsx)(`div`,{ref:F,className:`p-3 h-full overflow-y-auto styled-scrollbars-mini flex flex-col gap-2`,children:j.length===0?(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center text-center gap-2 py-8 px-2`,children:[(0,i.jsx)(t.Ui,{className:`w-5 h-5 text-foreground/25`,"aria-hidden":!0}),(0,i.jsx)(`p`,{className:`text-[12.5px] font-medium text-foreground/45 leading-relaxed`,children:`Nothing on this day yet.`})]}):j.map(e=>(0,i.jsx)(Of,{booking:e,zone:n,now:v,chip:Kf(e,a?.[e.paymentSession],!!a),withMember:c,side:u,onOpen:()=>E(e.id)},e.id))}),I&&(0,i.jsx)(t.H,{})]})]})}),P&&(0,i.jsx)(Ff,{booking:P,zone:n,chip:Kf(P,a?.[P.paymentSession],!!a),onClose:()=>E(null),me:l,side:u,onColor:h?e=>h(P.id,e):void 0,onAccept:d?()=>d(P):void 0,onCancel:e=>f(P,e),onDelete:p&&(!m||m(P))?()=>p(P):void 0,onRelease:g?()=>g(P):void 0}),D&&_&&(0,i.jsx)(Rf,{dateKey:C,dayLabel:N,zone:n,today:y,now:v,onClose:()=>O(!1),onAdd:_})]})}var Yf=`team`,Xf=e=>`m:${e}`,Zf=`__nobody__`;function Qf(e,n,r){return[{value:`me`,label:`My calendar`},{value:Yf,label:`My team's calendar`},...e.filter(e=>e.id!==r).map(e=>({value:Xf(e.id),label:t.h(e)||e.email,disabled:!n.has(e.id)}))]}var $f=e=>e.startsWith(`m:`)?e.slice(2):``;function ep(e){let[t,n]=(0,r.useState)({});return(0,r.useEffect)(()=>{let r=e.filter(e=>e.paymentSession&&t[e.paymentSession]===void 0);if(!r.length)return;let i=!1;return Promise.all(r.map(async e=>[e.paymentSession,(await ee(e.paymentSession)).paid])).then(e=>{i||n(t=>({...t,...Object.fromEntries(e)}))}),()=>{i=!0}},[e,t]),t}function tp(e,n,r,i=``){if(!e.email)return Promise.resolve();let a=t.Hn(e,e.timeZone||r);return Xa(n,t.ht,e.id,{when:`${a.day}, ${a.time}`,memberName:e.memberName,scheduleName:e.scheduleName,reason:i.trim()}).then(()=>{}).catch(()=>{})}function np(e,t,n){let r=e=>[...new Set(e.map(e=>String(e||``).trim()))].filter(e=>e&&e!==n),i=r([e.memberId,...t.map(e=>e.memberId),...e.copyIds.map(e=>e.split(`__`)[0])]);return{members:i,bookers:r([e.uid,...t.map(e=>e.uid)]).filter(e=>e!==`guest`).filter(e=>!i.includes(e))}}async function rp(e,n,r,i){if(e.own||e.heldOnly)return;let a={title:`Meeting removed`,body:`${t.Yt(e)} · ${t.un(new Date(e.start),i)}`};await tp(e,`booking_cancelled`,i,`The meeting was removed from the calendar.`);let{members:o,bookers:s}=np(e,n,r);await T(o,{...a,link:`/schedule`}),await T(s,{...a,link:`/my-bookings`})}function ip({isAdmin:e}){let{user:n}=t.na(),a=n?.uid||``,o=t.an(),[s,l]=(0,c.useSearchParams)(),u=s.get(`open`)||s.get(`booking`)||``,{schedules:d}=t.S(),{members:f}=t.C(),p=(0,r.useMemo)(()=>new Set(d.map(e=>e.memberId)),[d]),m=(0,r.useMemo)(()=>Qf(f,p,a),[f,p,a]),[h,g]=(0,r.useState)(null);(0,r.useEffect)(()=>{u&&e&&g(e=>e??`team`)},[u,e]);let _=h??`me`,v=new Set(m.filter(e=>!e.disabled).map(e=>e.value)).has(_)?_:`me`,y=$f(v),{loading:b,bookings:x,error:S}=t.g({members:v===`team`?void 0:[y||a||Zf],includePast:!0}),C=ep(x),w=t.x((0,r.useMemo)(()=>(v===`team`?f.map(e=>e.id):[y||a]).filter(Boolean),[v,f,y,a]),(0,r.useMemo)(()=>{let e=new Date;return new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth()-1,1))},[])),[T,E]=(0,r.useState)(()=>Date.now());(0,r.useEffect)(()=>{let e=setInterval(()=>E(Date.now()),6e4);return()=>clearInterval(e)},[]);let D=(0,r.useMemo)(()=>t.O(x),[x]),O=(0,r.useMemo)(()=>{let e=x.map(e=>{let t=D.get(e.id);return t?{...e,...t}:e}),n=e=>{let n=f.find(t=>t.id===e);return d.find(t=>t.memberId===e)?.memberName||(n?t.h(n):``)},r=t.k(w,x,T).map(e=>t.D(e,n(e.memberId)));return r.length?[...e,...r]:e},[x,D,w,T,f,d]),k=y||a,A=f.find(e=>e.id===k),j=d.find(e=>e.memberId===k)?.memberName||(A?t.h(A):``)||(k===a?String(n?.displayName||``):``);return O.length===0?null:(0,i.jsx)(t.at,{icon:t.Ui,title:`Calendar`,description:v===`team`?`Every booking made with your team, and the events they put on their own days — in your time, ${t.Kn(o)}.`:y?`${j||`Their`} calendar, read as they read it — in your time, ${t.Kn(o)}.`:`Every booking made with you, under every schedule of yours — in your time, ${t.Kn(o)}.`,actions:e&&m.length>2?(0,i.jsx)(t.sr,{ariaLabel:`Whose calendar`,value:v,options:m,onChange:g,className:`console-select`,compact:!0,dense:!0,portal:!0,direction:`auto`}):void 0,children:b?(0,i.jsx)(`p`,{className:t.$,children:`Loading the calendar…`}):S?(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:S}):(0,i.jsx)(Jf,{bookings:O,zone:o,paid:C,openBookingId:u||void 0,onOpened:u?()=>l(e=>(e.delete(`open`),e.delete(`booking`),e),{replace:!0}):void 0,withMember:v===Yf,me:a,onAccept:async e=>{let n=await t.n(e.id);return n||tp(e,`booking_confirmed`,o),n},onCancel:async(e,r)=>{let i=await t.i(e.id,{ids:e.copyIds,reason:r,side:`host`,by:e.memberId===a?j||String(n?.displayName||``):e.memberName,byUid:a});return i||tp(e,`booking_cancelled`,o,r),i},onDelete:async e=>(await rp(e,x,a,o),t.o(e.id,e.copyIds)),canDelete:t=>e||t.own&&t.memberId===a,onRelease:e=>t.s(e.memberId,e.start),onColor:t.p,onAdd:v===`team`?void 0:e=>t.r({...e,memberId:k,memberName:j,timeZone:o})})})}function ap(e,t){if(!e.enabled)return{state:`off`,label:`Off`};if(lo(e,t))return{state:`error`,label:`Unfinished`};let n=e.schedules.length;return{state:`saved`,label:n===1?`1 meeting`:`${n} meetings`}}var op=e=>{let t=e.schedules.length;return`${uo(e)} — ${t===0?`nothing on it yet`:t===1?`1 meeting`:`${t} meetings`}`};function sp({page:e,schedules:n,onChange:r}){return n.length?(0,i.jsx)(t.Z,{label:`Meetings on this page`,hint:`They appear in the order you tick them. A meeting switched off above is kept off the page too.`,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-1.5`,children:n.map(n=>{let a=e.schedules.includes(n.id);return(0,i.jsxs)(`button`,{type:`button`,role:`checkbox`,"aria-checked":a,onClick:()=>r(co(e,n.id)),className:`flex items-center gap-3 px-3 py-2.5 rounded-xl border text-left transition-all cursor-pointer active:scale-[0.995] ${a?`border-accent/45 bg-accent/[0.07]`:`border-[var(--panel-border)]/70 hover:border-accent/30 hover:bg-foreground/[0.03]`}`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-[5px] border flex items-center justify-center shrink-0 transition-all ${a?`border-accent bg-accent`:`border-foreground/25`}`,children:a&&(0,i.jsx)(`span`,{className:`w-[7px] h-[7px] rounded-[2px] bg-[var(--button-fg,#fff)]`})}),(0,i.jsx)(`span`,{className:`flex-1 min-w-0 text-[13px] font-semibold text-foreground/80 truncate`,children:t.Fn(n)})]},n.id)})})}):(0,i.jsx)(t.Z,{label:`Meetings on this page`,children:(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Make a schedule above first — a page offers the meetings you have set up.`})})}function cp({page:e,taken:n,onRename:a}){let[o,s]=(0,r.useState)(e.id),c=to(o),l=!!c&&c!==e.id&&n.includes(c);return(0,i.jsx)(t.ft,{label:`Its address`,prefix:`/meet/`,value:o,onChange:s,onBlur:()=>{if(!c||l||c===e.id){s(e.id);return}a(c)},placeholder:`anna-bell`,error:l?`Another page already has that address.`:void 0,hint:`Change it and the old link stops working, so change it before you send it out.`})}function lp({page:e,schedules:n,taken:a,open:o,fresh:s,error:c,onToggle:l,onChange:u,onRename:d,onRemove:f}){let[p,m]=(0,r.useState)(!1),h=ap(e,n),g=uo(e),_=lo(e,n),v=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!s)return;let e=uf(v.current);return()=>{e&&clearTimeout(e)}},[s]),(0,i.jsxs)(`div`,{ref:v,className:`scroll-mt-4 rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 sm:gap-2.5 pr-3`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:l,"aria-expanded":o,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:op(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:(0,i.jsx)(t.lt,{state:h.state,label:h.label})}),(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${o?`rotate-180`:``}`})]})]}),(0,i.jsx)(t.pt,{enabled:e.enabled,onChange:t=>u({...e,enabled:t}),label:`${g} — page is live`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${g}`,onClick:()=>m(!0),children:`Remove`})]}),(0,i.jsx)(Ve,{isOpen:p,title:`Remove ${g}?`,message:`Its link stops working. The meetings on it are untouched and keep their own links, and bookings already taken are kept.`,confirmText:`Yes, remove`,cancelText:`Keep it`,onCancel:()=>m(!1),onConfirm:()=>{m(!1),f()}}),o&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.ft,{label:`Name on the page`,value:e.title,onChange:t=>u({...e,title:t}),placeholder:`Anna Bell`,hint:`Usually the name of whoever the page is for.`}),(0,i.jsx)(st,{label:`Photo`,hint:`Shown at the top of the page. A square picture of the person works best.`,value:e.photo,onChange:t=>u({...e,photo:t})}),(0,i.jsx)(t.dt,{label:`About this page`,value:e.intro,onChange:t=>u({...e,intro:t}),rows:3,placeholder:`I help small studios get their bookkeeping straight. Pick a time below and tell me what you need.`}),(0,i.jsx)(sp,{page:e,schedules:n,onChange:u}),(0,i.jsx)(cp,{page:e,taken:a,onRename:d}),_?(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-amber-500 px-1`,children:_}):(0,i.jsx)(eu,{title:g,path:ro(e.id)})]}),c&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-4 pb-3`,children:c})]})}function up({schedules:e,myName:n,isAdmin:a=!0,meId:o=``}){let{loading:s,pages:c}=fo(),[l,u]=(0,r.useState)({}),[d,f]=(0,r.useState)([]),[p,m]=(0,r.useState)(null),[h,g]=(0,r.useState)(null),[_,v]=(0,r.useState)({}),y=(0,r.useRef)(new Map),b=new Map(c.map(e=>[e.id,e]));for(let e of Object.values(l))b.set(e.id,e);for(let e of d)b.delete(e);let x=[...b.values()].sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)||e.id.localeCompare(t.id)),S=x.map(e=>e.id),C=ao(x,o,a),w=a?e:e.filter(e=>e.memberId===o),T=e=>{let t=y.current.get(e.id);t&&clearTimeout(t),y.current.set(e.id,setTimeout(async()=>{y.current.delete(e.id);let t=await po(e);v(n=>{let r={...n};return t?r[e.id]=t:delete r[e.id],r})},600))},E=e=>{u(t=>({...t,[e.id]:e})),T(e)},D=()=>{let e=eo(no(n||`my page`,S),n,o);u(t=>({...t,[e.id]:e})),f(t=>t.filter(t=>t!==e.id)),m(e.id),g(e.id),T(e)},O=async(e,t)=>{let n=y.current.get(e.id);n&&(clearTimeout(n),y.current.delete(e.id));let r={...e,id:t};u(n=>{let i={...n};return delete i[e.id],i[t]=r,i}),f(n=>[...n.filter(e=>e!==t),e.id]),p===e.id&&m(t);let i=await ho(e.id,r);i&&v(e=>({...e,[t]:i}))},k=async e=>{let t=y.current.get(e);t&&(clearTimeout(t),y.current.delete(e)),u(t=>{let n={...t};return delete n[e],n}),f(t=>[...t,e]),p===e&&m(null);let n=await mo(e);n&&(f(t=>t.filter(t=>t!==e)),v(t=>({...t,[e]:n})))};return(0,i.jsx)(t.at,{icon:t.ii,title:`Your booking pages`,description:`One link with a photo, a line about you and every meeting you offer.`,actions:({open:e})=>(0,i.jsx)(t.Q,{icon:t.Ur,compact:!0,title:`Create a page`,onClick:()=>{e(),D()},children:`Create a page`}),children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:s?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Loading pages…`}):C.length===0?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`No pages yet. Create one to hand out a single link — a visitor sees your photo, what you do and every meeting you offer, and picks the one they want.`}):C.map(e=>(0,i.jsx)(lp,{page:e,schedules:w,taken:S,open:p===e.id,fresh:h===e.id,error:_[e.id],onToggle:()=>m(t=>t===e.id?null:e.id),onChange:E,onRename:t=>O(e,t),onRemove:()=>k(e.id)},e.id))})})}var dp={from:`09:00`,to:`17:00`},fp=e=>t.gn(e)?{state:`saved`,label:`Ready`}:{state:`off`,label:`In progress`},pp=e=>({...t.Ht(t.L(),e.id,t.h(e),t.an()),name:`Working hours`,enabled:!0,createdAt:Date.now()}),mp=`w-[6.5rem] shrink-0`,hp=`w-9 h-9 rounded-[var(--btn-radius,0.75rem)] border border-[var(--panel-border)] flex items-center justify-center shrink-0 text-foreground/45 hover:text-red-500 hover:border-red-500/40 hover:bg-red-500/[0.06] active:scale-[0.98] transition-all cursor-pointer`;function gp({day:e,windows:n,onChange:r}){let a=n.length>0,o=(e,t)=>r(n.map((n,r)=>r===e?{...n,...t}:n));return(0,i.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-[8.5rem_minmax(0,1fr)] items-start gap-x-4 gap-y-2 py-2.5`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 h-9`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-medium ${a?`text-foreground/80`:`text-foreground/40`}`,children:t.wt[e]}),(0,i.jsx)(t.pt,{enabled:a,onChange:e=>r(e?[dp]:[]),label:`${t.wt[e]} — bookable`})]}),a&&(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 min-w-0`,children:[n.map((a,s)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`div`,{className:mp,children:(0,i.jsx)(t.sr,{ariaLabel:`${t.wt[e]} from${s?` (${s+1})`:``}`,value:a.from,options:t.Ot,onChange:e=>o(s,{from:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),(0,i.jsx)(`span`,{className:`w-3 text-center text-foreground/40 text-[13px] shrink-0 select-none`,children:`–`}),(0,i.jsx)(`div`,{className:mp,children:(0,i.jsx)(t.sr,{ariaLabel:`${t.wt[e]} to${s?` (${s+1})`:``}`,value:a.to,options:t.Tt,onChange:e=>o(s,{to:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),n.length>1&&(0,i.jsx)(`button`,{type:`button`,title:`Remove these hours on ${t.wt[e]}`,"aria-label":`Remove ${t.wt[e]} hours ${s+1}`,onClick:()=>r(n.filter((e,t)=>t!==s)),className:hp,children:(0,i.jsx)(t._r,{className:`w-3.5 h-3.5`})})]},s)),n.length<2&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>r([...n,{from:`18:00`,to:`20:00`}]),className:`self-start h-6 px-1 text-[11.5px] font-semibold text-foreground/45 hover:text-accent transition-colors cursor-pointer`,children:`+ Add a second stretch`})]})]})}function _p({schedule:e,onChange:n}){let r=t=>n({...e,...t}),a=t.hn(e);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.ft,{label:`What are these hours called?`,hint:`Only you and your team read this — it is how a booking link names the hours it is booked in. Working hours, Evenings, Studio days.`,value:e.name,onChange:e=>r({name:e}),placeholder:`Working hours`}),(0,i.jsx)(t.Y,{value:e.timeZone,onChange:e=>r({timeZone:e})}),(0,i.jsx)(t.Z,{label:`When`,hint:`The hours on each day, in this person's own time zone. Add a second stretch for a break in the middle. A time booked in any of their hours is taken here too.`,children:(0,i.jsx)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-1`,children:t.Ct.map(t=>(0,i.jsx)(gp,{day:t,windows:e.days[t]||[],onChange:n=>r({days:{...e.days,[t]:n}})},t))})}),(0,i.jsx)(rf,{blocked:e.blocked,onChange:e=>r({blocked:e})}),(0,i.jsx)(`div`,{className:`pt-1`,children:a?(0,i.jsxs)(`span`,{className:`text-[11.5px] font-semibold text-amber-500`,children:[`Not usable yet — `,a]}):(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Ready — add a booking link below to let people book these hours, or ask for a page built on them.`})})]})}function vp({schedule:e,open:n,stale:a,fresh:o,error:s,onToggle:c,onChange:l,onRemove:u}){let d=fp(e),[f,p]=(0,r.useState)(!1),m=t.mn(e),h=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!o)return;let e=uf(h.current);return()=>{e&&clearTimeout(e)}},[o]),(0,i.jsxs)(`div`,{ref:h,className:`scroll-mt-4 rounded-2xl border border-[var(--panel-border)] ${a?`opacity-60`:``}`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 sm:gap-2.5 pr-3`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:c,"aria-expanded":n,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:t._n(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[a?(0,i.jsx)(`span`,{className:`${t.$} max-sm:hidden`,children:`No longer on the team`}):(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:(0,i.jsx)(t.lt,{state:d.state,label:d.label})}),(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${n?`rotate-180`:``}`})]})]}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${m}`,onClick:()=>p(!0),children:`Remove`})]}),(0,i.jsx)(Ve,{isOpen:f,title:`Remove ${m}?`,message:a?`They are no longer on the team, so nobody can book them. Bookings already taken are kept.`:`Every booking link booked in these hours stops working, and they leave every page and form they were picked on. Bookings already taken are kept.`,confirmText:`Yes, remove`,cancelText:`Keep it`,onCancel:()=>p(!1),onConfirm:()=>{p(!1),u()}}),n&&(0,i.jsx)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:(0,i.jsx)(_p,{schedule:e,onChange:l})}),s&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-4 pb-3`,children:s})]})}function yp({name:e,schedules:n,stale:a,open:o,onToggle:s,onAdd:c,openScheduleId:l,freshId:u,errors:d,onToggleSchedule:f,onChange:p,onRemove:m}){let h=a?`No longer on the team`:n.length===0?`No schedules yet`:`${n.length} schedule${n.length===1?``:`s`}`,g=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!o)return;let e=uf(g.current);return()=>{e&&clearTimeout(e)}},[o]),(0,i.jsxs)(`div`,{ref:g,className:`scroll-mt-4 rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:s,"aria-expanded":o,className:`w-full flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:e}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(`span`,{className:`${t.$} max-sm:hidden`,children:h}),(0,i.jsx)(t.Ri,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${o?`rotate-180`:``}`})]})]}),o&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-3`,children:[n.map(e=>(0,i.jsx)(vp,{schedule:e,stale:a,fresh:u===e.id,open:l===e.id,error:d[e.id],onToggle:()=>f(e.id),onChange:p,onRemove:()=>m(e.id)},e.id)),a?n.length===0&&(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`No schedule yet for `,e,`.`]}):(0,i.jsxs)(`div`,{className:`flex flex-col items-start sm:flex-row sm:items-center gap-3 rounded-2xl border border-dashed border-[var(--panel-border)] px-4 py-3`,children:[(0,i.jsx)(t.Q,{icon:t.Ur,title:`Add a schedule for ${e}`,onClick:c,children:`Add a schedule`}),n.length===0&&(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`No schedule yet for `,e,`.`]})]})]})]})}var bp=e=>({id:e.uid,name:String(e.displayName||``),email:String(e.email||``),role:`admin`});function xp({isAdmin:e=!0}={}){let{user:n}=t.na(),{loading:a,members:o}=t.C(),{loading:s,docs:l}=t.b(),u=l.schedules,[d,f]=(0,r.useState)({}),[p,m]=(0,r.useState)([]),[h,g]=(0,r.useState)(null),[_,v]=(0,r.useState)(null),[y,b]=(0,r.useState)(null),[x,S]=(0,r.useState)({}),C=(0,r.useRef)(new Map),w=(0,r.useMemo)(()=>{let e=new Map(u.map(e=>[e.id,e]));for(let t of Object.values(d))e.set(t.id,t);for(let t of p)e.delete(t);return[...e.values()].sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)||e.id.localeCompare(t.id))},[u,d,p]),T=e=>{let n=C.current.get(e.id);n&&clearTimeout(n),C.current.set(e.id,setTimeout(async()=>{C.current.delete(e.id);let n=await t.f(e);S(t=>{let r={...t};return n?r[e.id]=n:delete r[e.id],r})},600))},E=e=>{f(t=>({...t,[e.id]:e})),T(e)},D=(0,r.useMemo)(()=>n?o.find(e=>e.id===n.uid)||bp(n):null,[n,o]),O=(0,r.useMemo)(()=>D&&!o.some(e=>e.id===D.id)?[D,...o]:o,[D,o]),k=(0,r.useRef)(!1),[A,j]=(0,r.useState)(``),M=(0,r.useMemo)(()=>l.schedules.filter(t=>l.legacyIds.includes(t.id)&&(e||t.memberId===D?.id)),[l.schedules,l.legacyIds,e,D]);(0,r.useEffect)(()=>{k.current||M.length===0||(k.current=!0,t.m(M).then(e=>{e&&j(e)}))},[M]);let N=e=>{let t=pp(e);f(e=>({...e,[t.id]:t})),g(t.id),v(t.id),D&&e.id!==D.id&&b(e.id),T(t)},P=()=>{D&&N(D)},F=async e=>{let n=C.current.get(e);n&&(clearTimeout(n),C.current.delete(e)),f(t=>{let n={...t};return delete n[e],n}),m(t=>[...t,e]),h===e&&g(null);let r=await t.u(e);r&&(m(t=>t.filter(t=>t!==e)),S(t=>({...t,[e]:r})))},I=a||s,L=new Set(O.map(e=>e.id)),R=D?w.filter(e=>e.memberId===D.id):[],z=(0,r.useMemo)(()=>{if(!D)return[];let e=new Map;for(let t of w){if(t.memberId===D.id)continue;let n=e.get(t.memberId);n?n.push(t):e.set(t.memberId,[t])}let n=[];for(let r of O)r.id!==D.id&&(n.push({id:r.id,name:t.h(r)||r.email,stale:!1,schedules:e.get(r.id)||[]}),e.delete(r.id));for(let[t,r]of e)n.push({id:t,name:r[0].memberName.trim()||`Someone no longer on the team`,stale:!0,schedules:r});return n},[w,O,D]);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.at,{icon:t.Wi,title:`Your schedules`,description:`When you are free — a name, a time zone, the week's hours and the days you are away. The base for anything booked on them.`,actions:I?void 0:({open:e})=>(0,i.jsx)(t.Q,{icon:t.Ur,compact:!0,title:`Add a schedule`,onClick:()=>{e(),P()},children:`Add a schedule`}),children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[I?(0,i.jsx)(`p`,{className:t.$,children:`Loading your schedules…`}):R.length===0?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`No hours of your own yet — press Add a schedule. Everything booked in them shares one availability, so a time taken once is gone from all of it.`}):R.map(e=>(0,i.jsx)(vp,{schedule:e,stale:!L.has(e.memberId),fresh:_===e.id,open:h===e.id,error:x[e.id],onToggle:()=>g(h===e.id?null:e.id),onChange:E,onRemove:()=>F(e.id)},e.id)),!!A&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:A})]})}),e&&(0,i.jsx)(t.at,{icon:t.xr,title:`Your team's schedules`,description:`When everyone else is free — one folded row per person; open a name to add their hours or see what they keep.`,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:I?(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:`Loading your team's schedules…`}):z.length===0?(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug px-1`,children:[`Nobody else is marked Internal or Admin yet. Add them on the`,` `,(0,i.jsx)(c.Link,{to:`/users`,className:`text-accent font-bold hover:underline`,children:`Users screen`}),` and a folded row for them appears here.`]}):z.map(e=>(0,i.jsx)(yp,{name:e.name,schedules:e.schedules,stale:e.stale,open:y===e.id,onToggle:()=>{let t=y!==e.id;b(t?e.id:null),t&&e.schedules.length&&g(e.schedules[0].id)},onAdd:()=>{let t=O.find(t=>t.id===e.id);t&&N(t)},openScheduleId:h,freshId:_,errors:x,onToggleSchedule:e=>g(h===e?null:e),onChange:E,onRemove:F},e.id))})})]})}function Sp(){let{user:e,userRole:n}=t.na(),r=n===`admin`,{schedules:a}=t._(),o=e&&(e.displayName||e.email?.split(`@`)[0])||``;return t.fa(n)?(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(Ce,{children:`Schedule`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/schedule`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col min-h-[600px]`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsx)(`div`,{className:`flex flex-col gap-1.5 px-1`,children:(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/60 leading-relaxed`,children:r?`When you and your team are free, and everything built on it. A schedule is a week of hours in one person’s own time zone; a booking link turns those hours into a meeting people can book, with an address to send. The same hours are what a page you ask for is built on.`:`When you are free, and what people can book in it. Your schedule is your week of hours; a booking link turns it into a meeting, with an address of its own to send — they pick a free time and it lands on your calendar. A booking page gathers your meetings under one address to hand out.`})}),(0,i.jsx)(ip,{isAdmin:r}),(0,i.jsx)(xp,{isAdmin:r}),(0,i.jsx)(yf,{isAdmin:r}),(0,i.jsx)(up,{schedules:a,myName:o,isAdmin:r,meId:e?.uid||``})]})})]})]}):(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:(0,i.jsx)(Ci,{})})}function Cp(){let{user:e}=t.na(),n=t.an(),{loading:a,bookings:o,error:s}=t.v(e?.uid||``,e?.email||``),{docs:c}=t.b(),l=(0,r.useMemo)(()=>t.w(c),[c]),u=(0,r.useMemo)(()=>t.T(o,l),[o,l]);return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(Ce,{children:`My bookings`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/my-bookings`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col min-h-[600px]`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/60 leading-relaxed px-1`,children:[`Every meeting booked with your email address — including any you booked before you had an account. Shown in your time, `,t.Kn(n),`.`]}),a?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Loading your bookings…`}):s?(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:s}):u.length===0?(0,i.jsx)(t.at,{icon:t.Wi,title:`Nothing booked yet`,description:`Meetings you book appear here.`,children:(0,i.jsxs)(`p`,{className:`${t.$} px-1`,children:[`When you book a time through one of `,e?.displayName?`their`:`our`,` booking links, it lands here — and stays here afterwards, so you always have the record.`]})}):(0,i.jsx)(t.at,{icon:t.Wi,title:`Your calendar`,description:`Press a day to see what is on it. Everything you have booked is here, including the meetings that have been and the ones called off.`,children:(0,i.jsx)(Jf,{bookings:u,zone:n,side:`booker`,onCancel:async(r,i)=>{let a=await t.i(r.id,{ids:r.copyIds,reason:i,side:`booker`,by:r.name.trim()||String(e?.displayName||``)});if(!a){let e=t.Hn(r,n);Ya(`heads_up`,{title:`Booking cancelled`,summary:`${r.name.trim()||`Someone`} cancelled ${t.Yt(r)} — ${e.day}, ${e.time}`,details:{Who:r.name.trim(),Email:r.email,When:`${e.day}, ${e.time}`,Reason:i}}).catch(()=>{})}return a}})}),!a&&!s&&u.length>0&&(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug px-1 flex items-start gap-1.5`,children:[(0,i.jsx)(t.Cr,{className:`w-3.5 h-3.5 shrink-0 mt-[1px]`,"aria-hidden":!0}),(0,i.jsx)(`span`,{children:`Cancelling gives the time back straight away. To MOVE a meeting, cancel it and book another — or reply to its confirmation email.`})]})]})})]})]})}var wp=(0,r.lazy)(()=>Promise.resolve().then(()=>require(`./PhoneInputField-CkAv_5Lw.cjs`)).then(e=>e.n)),Tp=`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,Ep=`text-[12px] font-semibold text-red-500 mt-1 ml-1`,Dp=`flex w-full text-[15px] text-foreground px-4 py-3 transition-all duration-300 placeholder:text-foreground/40 focus:outline-none focus:border-accent glow-focus glass-panel resize-none`;function Op({children:e}){return(0,i.jsx)(`div`,{className:`flex flex-col w-full min-w-0`,children:e})}function kp({question:e,value:n,error:a,onChange:o}){let s=e.label.trim(),c=e.required?`${s} *`:s;return e.type===`textarea`?(0,i.jsxs)(Op,{children:[(0,i.jsx)(`label`,{className:Tp,htmlFor:`q_${e.name}`,children:c}),(0,i.jsx)(`textarea`,{id:`q_${e.name}`,rows:3,value:n,placeholder:e.placeholder,onChange:e=>o(e.target.value),className:`${Dp} rounded-xl min-h-[90px]`}),a&&(0,i.jsx)(`p`,{className:Ep,children:a})]}):e.type===`checkbox`?(0,i.jsxs)(Op,{children:[(0,i.jsxs)(`label`,{className:`flex items-center gap-3 w-full cursor-pointer group py-1.5`,children:[(0,i.jsxs)(`span`,{className:`relative flex items-center justify-center w-5 h-5 rounded border border-foreground/20 bg-background/50 group-hover:border-accent transition-colors shrink-0`,children:[(0,i.jsx)(`input`,{type:`checkbox`,checked:n===`Yes`,onChange:e=>o(e.target.checked?`Yes`:``),className:`absolute opacity-0 w-full h-full cursor-pointer`}),n===`Yes`&&(0,i.jsx)(`span`,{className:`w-2.5 h-2.5 bg-accent rounded-sm shrink-0`})]}),(0,i.jsx)(`span`,{className:`text-[14px] font-medium text-foreground/80 leading-snug group-hover:text-foreground transition-colors`,children:c})]}),a&&(0,i.jsx)(`p`,{className:Ep,children:a})]}):e.type===`select`?(0,i.jsxs)(Op,{children:[(0,i.jsx)(t.sr,{label:c,direction:`auto`,value:n,options:[{value:``,label:(0,i.jsx)(`span`,{className:`text-foreground/40`,children:e.placeholder||`Choose one…`})},...e.options.filter(Boolean).map(e=>({value:e,label:e}))],onChange:o}),a&&(0,i.jsx)(`p`,{className:Ep,children:a})]}):e.type===`tel`?(0,i.jsxs)(Op,{children:[(0,i.jsx)(r.Suspense,{fallback:(0,i.jsx)(`div`,{className:`h-12 w-full glass-panel animate-pulse rounded-xl`}),children:(0,i.jsx)(wp,{field:{label:c,required:!1,placeholder:e.placeholder},value:n,onChange:o})}),a&&(0,i.jsx)(`p`,{className:Ep,children:a})]}):e.type===`file`?(0,i.jsx)(Op,{children:(0,i.jsx)(t.$n,{field:{label:c,placeholder:e.placeholder},value:n,error:a,onChange:e=>o(e(n))})}):e.type===`date`?(0,i.jsxs)(Op,{children:[(0,i.jsx)(`label`,{className:Tp,htmlFor:`q_${e.name}`,children:c}),(0,i.jsxs)(`div`,{className:`relative flex items-center lift-focus`,children:[(0,i.jsx)(`input`,{id:`q_${e.name}`,type:`date`,value:n,onChange:e=>o(e.target.value),className:`date-field block h-12 w-full text-[15px] pl-4 pr-11 py-2 transition-all duration-300 focus:outline-none focus:border-accent glow-focus glass-panel ${n?`text-foreground`:`text-foreground/40`}`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(t.Vi,{className:`w-4 h-4 text-foreground/50 absolute right-4 pointer-events-none`,"aria-hidden":!0})]}),a&&(0,i.jsx)(`p`,{className:Ep,children:a})]}):(0,i.jsx)(Op,{children:(0,i.jsx)(t.lr,{label:c,type:e.type,value:n,error:a,placeholder:e.placeholder,onChange:e=>o(e.target.value)})})}function Ap({questions:e,answers:n,errors:r,onChange:a}){return(0,i.jsx)(i.Fragment,{children:t.It(e).map(e=>(0,i.jsx)(kp,{question:e,value:n[e.name]||``,error:r[e.name],onChange:t=>a(e.name,t)},e.name))})}var jp=/^[^\s@,;]+@[^\s@,;.]+(\.[^\s@,;.]+)*\.[a-z]{2,}$/i;function Mp(e){if(!e||e.kind!==`once`)return null;let t=Li(e),n=t.reduce((e,t)=>e+(Ri(t.amount)||0),0),r=e.name.trim()||t.map(e=>e.name.trim()).filter(Boolean).join(` and `)||Yi(e);return n>0?{amount:n,name:r}:null}var Np=(e,t=`usd`)=>{try{return new Intl.NumberFormat(void 0,{style:`currency`,currency:t.toUpperCase()}).format(e)}catch{return`${e} ${t.toUpperCase()}`}};function Pp(e){let[n,i]=(0,r.useState)({id:``,product:null});return(0,r.useEffect)(()=>{if(!e)return;let n=!1;return(0,o.getDoc)((0,o.doc)(t.Da,ji,e)).then(t=>{n||i({id:e,product:t.exists()?Ui(t.id,t.data()):null})}).catch(()=>{n||i({id:e,product:null})}),()=>{n=!0}},[e]),e?n.id===e?{loading:!1,product:n.product}:{loading:!0,product:null}:{loading:!1,product:null}}function Fp({icon:e,accent:t,children:n}){return(0,i.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 h-7 px-3 rounded-full border text-[12.5px] font-semibold whitespace-nowrap ${t?`border-accent/40 bg-accent/10 text-accent`:`border-[var(--panel-border)]/70 text-foreground/65`}`,children:[e&&(0,i.jsx)(e,{className:`w-3.5 h-3.5 text-accent shrink-0`,"aria-hidden":!0}),n]})}function Ip({children:e,wide:n,form:r}){return(0,i.jsx)(`main`,{className:`flex-1 w-full mx-auto px-4 py-8 md:py-12 z-10 flex flex-col justify-center transition-[max-width] duration-500 ease-out ${n?`max-w-4xl`:r?`max-w-2xl`:`max-w-xl`}`,children:(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},transition:{duration:.4},className:`w-full rounded-3xl glass-panel border border-[var(--panel-border)] p-5 sm:p-8 md:p-10 shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:e})})}function Lp({children:e}){return(0,i.jsx)(`h1`,{ref:Se([e]),className:`text-2xl sm:text-3xl font-extrabold tracking-tight text-gradient leading-tight whitespace-nowrap data-[fold]:whitespace-normal data-[fold]:text-balance`,children:e})}function Rp({icon:e,title:n,children:r}){return(0,i.jsxs)(`div`,{className:`flex flex-col items-center text-center py-8 gap-4`,children:[(0,i.jsx)(`div`,{className:`w-14 h-14 ${t.K}`,children:(0,i.jsx)(e,{className:`w-6 h-6`})}),(0,i.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold text-foreground tracking-tight`,children:n}),r&&(0,i.jsx)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed max-w-md`,children:r}),(0,i.jsx)(c.Link,{to:`/`,className:`text-[13px] font-bold text-accent hover:underline mt-2`,children:`Back to the site`})]})}function zp({sessionId:e,schedule:n}){let[a,o]=(0,r.useState)(null);if((0,r.useEffect)(()=>{let t=!1;return ee(e).then(e=>{t||o(e)}),()=>{t=!0}},[e]),!a)return(0,i.jsx)(Rp,{icon:t.ti,title:`Confirming your payment…`,children:`One moment — checking with the payment provider.`});let s=a.metadata?.when||``;return a.paid?(0,i.jsx)(Rp,{icon:t.Gi,title:`Paid — your time is held`,children:(0,i.jsxs)(`p`,{children:[s?`${s} — `:``,t.In(n),`. Held for you while it is confirmed.`,a.customerEmail?` A receipt is on its way to ${a.customerEmail}.`:``]})}):(0,i.jsx)(Rp,{icon:t.Oi,title:`Not confirmed yet`,children:(0,i.jsx)(`p`,{children:a.error||`The payment provider has not confirmed this payment yet. Your time is held; if a receipt arrives by email, the booking is yours.`})})}function Bp(){let{id:e=``}=(0,c.useParams)(),[n]=(0,c.useSearchParams)(),{activeConfig:a}=t.ja(),{loading:o,schedule:s}=t.y(e),{loading:l,product:u}=Pp(s?.paymentId||``),d=Mp(u),f=Y(),[p,m]=(0,r.useState)(()=>t.an()),[h]=(0,r.useState)(()=>new Date),g=t.x(s?[s.memberId]:[],h),_=(0,r.useMemo)(()=>s&&t.Wt(s)?[s]:[],[s]),[v,y]=(0,r.useState)(null),[b,x]=(0,r.useState)(()=>t.Ea.currentUser?.displayName||``),[S,C]=(0,r.useState)(()=>t.Ea.currentUser?.email||``),[w,T]=(0,r.useState)({}),[E,D]=(0,r.useState)({}),[O,k]=(0,r.useState)(!1),[A,j]=(0,r.useState)(``),[M,N]=(0,r.useState)(``),[P,F]=(0,r.useState)(``),I=n.get(`session_id`)||``,R=n.get(`cancelled`)===`1`;if(o)return(0,i.jsx)(Ip,{children:(0,i.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-16 text-foreground/50`,children:[(0,i.jsx)(t.ti,{className:`w-4 h-4 animate-spin text-accent`}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium`,children:`Loading…`})]})});if(!s)return(0,i.jsx)(Ip,{children:(0,i.jsx)(Rp,{icon:t.Hi,title:`This booking link is no longer open`,children:`It may have been taken down. Ask whoever sent it for a new one.`})});if(I)return(0,i.jsx)(Ip,{children:(0,i.jsx)(zp,{sessionId:I,schedule:s})});if(M)return(0,i.jsx)(Ip,{children:(0,i.jsx)(Rp,{icon:t.Oi,title:`Your time is held`,children:(0,i.jsxs)(`p`,{children:[M,` — held for you while `,s.memberName.trim()||`the person you booked with`,` confirms it.`,P?` We have sent the details to ${P}, and will write again the moment it is confirmed.`:``]})})});if(!t.Wt(s))return(0,i.jsx)(Ip,{children:(0,i.jsx)(Rp,{icon:t.Hi,title:t.In(s),children:`This is not taking bookings at the moment.`})});let z=!!s.paymentId&&!l&&(!d||!f.loading&&!f.configured),B=async()=>{if(!v||O)return;let e={...t.qt(s.questions,w)};if(b.trim()||(e._name=`Your name, please.`),jp.test(S.trim())||(e._email=`That does not look like an email address — check for a typo, e.g. jane@example.com`),D(e),Object.keys(e).length)return;k(!0),j(``);let n=t.nn(v,s.memberName,p),r=await t.a(v);if(r){j(r),y(null),k(!1);return}let i=null;if(d){let e=await W({amount:d.amount,productName:`${t.In(s)} — ${n}`,metadata:{bookingId:t.zn(v.memberId,v.start),scheduleId:s.id,page:t.Qt(s.id),when:n,emailReceipt:s.confirmBooker?`yes`:`no`,notifyOwner:s.notifyOwner?`yes`:`no`},successPath:t.Qt(s.id),cancelPath:`${t.Qt(s.id)}?cancelled=1`});if(typeof e==`string`){await t.c(v),j(e),k(!1);return}i=e}let a=t.zn(v.memberId,v.start),o=await t.E(v,{memberName:s.memberName,scheduleId:s.id,scheduleName:t.Mn(s),paymentId:s.paymentId,paymentSession:i?.sessionId||``,timeZone:p,name:b.trim(),email:S.trim(),answers:t.Gt(s.questions,w),formId:t.gt,entryId:``});if(o){await t.c(v),j(o),k(!1);return}if(i){L.goTo(i.url);return}if(s.notifyOwner&&Ya(`heads_up`,{title:`New booking`,summary:`${b.trim()} booked ${t.In(s)} — ${n}`,details:{Name:b.trim(),Email:S.trim(),When:n,...t.Kt(s.questions,w)}}).catch(()=>{}),s.confirmBooker&&t.Ea.currentUser){let e=S.trim();Xa(`booking_requested`,`mem_bookings`,a,{when:n,memberName:s.memberName,scheduleName:t.In(s),details:{When:n,With:s.memberName,What:t.In(s)}}).then(t=>{t||F(e)}).catch(()=>{})}N(n),k(!1)},V=!z&&!v,H=!z&&!!v,U=t.Ft(s.questions,`name`),G=t.Ft(s.questions,`email`);return(0,i.jsxs)(Ip,{wide:V,form:H,children:[R&&(0,i.jsx)(`p`,{className:`mb-5 px-4 py-3 rounded-xl bg-amber-500/10 border border-amber-500/20 text-[13px] font-medium text-foreground/80`,children:`Nothing was charged. Pick a time again to book.`}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 mb-5 sm:mb-6`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3.5 min-w-0`,children:[(0,i.jsx)(`div`,{className:`w-11 h-11 ${t.K}`,children:(0,i.jsx)(t.Wi,{className:`w-5 h-5`})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[a?.appName&&(0,i.jsx)(`span`,{className:`text-[10.5px] font-bold uppercase tracking-[0.18em] text-foreground/40 truncate`,children:a.appName}),(0,i.jsx)(Lp,{children:t.In(s)})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[!s.memberName.trim()&&(0,i.jsx)(Fp,{icon:t.Cr,children:`with your host`}),(0,i.jsx)(Fp,{icon:t.Oi,children:t.Bn(s.slotMinutes)}),d&&(0,i.jsx)(Fp,{accent:!0,children:Np(d.amount)})]}),t.jn(s)&&(0,i.jsx)(`p`,{className:`text-[13.5px] sm:text-[14px] text-foreground/60 font-medium leading-relaxed max-w-2xl whitespace-pre-line`,children:t.jn(s)})]}),(0,i.jsx)(`div`,{className:`h-px bg-[var(--panel-border)]/60 mb-5 sm:mb-6`}),z?(0,i.jsx)(`p`,{className:`text-[14px] font-medium text-foreground/60`,children:`This booking cannot be paid for right now — please try again later.`}):v?(0,i.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,i.jsx)(t.G,{slot:v,timeZone:p,onChange:()=>y(null)}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsx)(t.lr,{label:U.label,value:b,onChange:e=>x(e.target.value),error:E._name,placeholder:U.placeholder}),(0,i.jsx)(t.lr,{label:G.label,type:`email`,value:S,onChange:e=>C(e.target.value),error:E._email,placeholder:G.placeholder}),(0,i.jsx)(Ap,{questions:s.questions,answers:w,errors:E,onChange:(e,t)=>{T(n=>({...n,[e]:t})),D(t=>t[e]?{...t,[e]:``}:t)}})]}),A&&(0,i.jsx)(`p`,{role:`alert`,className:`text-[13px] font-semibold text-red-500`,children:A}),(0,i.jsx)(`div`,{className:`h-px bg-[var(--panel-border)]/60`}),(0,i.jsx)(t.J,{timeZone:p,onTimeZone:m,action:(0,i.jsx)(t.cr,{variant:`primary`,onClick:B,disabled:O||l,className:`max-sm:w-full h-11 px-6 text-[13.5px] font-bold shrink-0`,children:O?d?`Opening checkout…`:`Booking…`:d?`Book and pay ${Np(d.amount)}`:`Confirm booking`})})]}):(0,i.jsxs)(i.Fragment,{children:[A&&(0,i.jsx)(`p`,{role:`alert`,className:`mb-3 text-[13px] font-semibold text-red-500`,children:A}),(0,i.jsx)(t.z,{members:_,value:v,onChange:y,taken:g,timeZone:p,onTimeZone:m})]})]})}var Vp=`rounded-2xl flex items-center justify-center shrink-0 border border-[var(--panel-border)]/50 bg-accent/10 text-accent`,Hp=`rounded-2xl border border-[var(--panel-border)]/60 bg-foreground/[0.015]`;function Up(e){let[n,i]=(0,r.useState)(new Map),a=e.join(`,`);return(0,r.useEffect)(()=>{let e=a?a.split(`,`):[];if(!e.length)return;let n=!1;return Promise.all(e.map(async e=>{try{let n=await(0,o.getDoc)((0,o.doc)(t.Da,ji,e));return n.exists()?Ui(e,n.data()):null}catch{return null}})).then(e=>{if(n)return;let t=new Map;e.forEach(e=>{e&&t.set(e.id,e)}),i(t)}),()=>{n=!0}},[a]),n}function Wp({children:e}){return(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-2xl mx-auto px-4 py-8 md:py-12 z-10 flex flex-col justify-center`,children:(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},transition:{duration:.4},className:`w-full rounded-3xl glass-panel border border-[var(--panel-border)] p-5 sm:p-8 md:p-10 shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:e})})}function Gp({icon:e,title:t,children:n}){return(0,i.jsxs)(`div`,{className:`flex flex-col items-center text-center py-8 gap-4`,children:[(0,i.jsx)(`div`,{className:`w-14 h-14 ${Vp}`,children:(0,i.jsx)(e,{className:`w-6 h-6`})}),(0,i.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold text-foreground tracking-tight`,children:t}),n&&(0,i.jsx)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed max-w-md`,children:n}),(0,i.jsx)(c.Link,{to:`/`,className:`text-[13px] font-bold text-accent hover:underline mt-2`,children:`Back to the site`})]})}function Kp({icon:e,accent:t,children:n}){return(0,i.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 h-6 px-2.5 rounded-full border text-[11.5px] font-semibold whitespace-nowrap ${t?`border-accent/40 bg-accent/10 text-accent`:`border-[var(--panel-border)]/70 text-foreground/60`}`,children:[e&&(0,i.jsx)(e,{className:`w-3 h-3 text-accent shrink-0`,"aria-hidden":!0}),n]})}function qp({schedule:e,price:n}){let r=t.jn(e),a=t.Vn(e.slotMinutes);return(0,i.jsxs)(c.Link,{to:t.Qt(e.id),className:`${Hp} group relative overflow-hidden flex items-center gap-3.5 sm:gap-4 p-3 sm:p-4 transition-all duration-300
|
|
666
|
+
`,jc=[{key:`VITE_FIREBASE_API_KEY`,label:`API Key`,shownAs:`apiKey`},{key:`VITE_FIREBASE_AUTH_DOMAIN`,label:`Auth Domain`,shownAs:`authDomain`},{key:`VITE_FIREBASE_PROJECT_ID`,label:`Project ID`,shownAs:`projectId`},{key:`VITE_FIREBASE_STORAGE_BUCKET`,label:`Storage Bucket`,shownAs:`storageBucket`},{key:`VITE_FIREBASE_MESSAGING_SENDER_ID`,label:`Messaging Sender ID`,shownAs:`messagingSenderId`},{key:`VITE_FIREBASE_APP_ID`,label:`App ID`,shownAs:`appId`}];function Mc(e){let t;try{if(t={BASE_URL:`/`,DEV:!1,MODE:`production`,PROD:!0,SSR:!1,VITE_ADMIN_EMAILS:void 0,VITE_FIREBASE_API_KEY:void 0,VITE_FIREBASE_APP_ID:void 0,VITE_FIREBASE_AUTH_DOMAIN:void 0,VITE_FIREBASE_MESSAGING_SENDER_ID:void 0,VITE_FIREBASE_PROJECT_ID:void 0,VITE_FIREBASE_STORAGE_BUCKET:void 0}?.[e],t&&typeof t==`string`&&t.trim()!==``)return t}catch{}try{if(t=(typeof window<`u`?window:globalThis)?.process?.env?.[e],t&&typeof t==`string`&&t.trim()!==``)return t}catch{}try{switch(e){case`VITE_FIREBASE_API_KEY`:t=void 0;break;case`VITE_FIREBASE_AUTH_DOMAIN`:t=void 0;break;case`VITE_FIREBASE_PROJECT_ID`:t=void 0;break;case`VITE_FIREBASE_STORAGE_BUCKET`:t=void 0;break;case`VITE_FIREBASE_MESSAGING_SENDER_ID`:t=void 0;break;case`VITE_FIREBASE_APP_ID`:t=void 0;break}if(t&&typeof t==`string`&&t.trim()!==``)return t}catch{}return``}function Nc(e,t){let n=Mc(e);if(n)return n;if(t?.firebaseConfig){let n={VITE_FIREBASE_API_KEY:`apiKey`,VITE_FIREBASE_AUTH_DOMAIN:`authDomain`,VITE_FIREBASE_PROJECT_ID:`projectId`,VITE_FIREBASE_STORAGE_BUCKET:`storageBucket`,VITE_FIREBASE_MESSAGING_SENDER_ID:`messagingSenderId`,VITE_FIREBASE_APP_ID:`appId`}[e];if(n&&t.firebaseConfig[n])return t.firebaseConfig[n]}return``}function Pc(e){let t=[],n=[],r=t=>Nc(t,e);for(let{key:e,label:i}of jc){let a=r(e);a?a.trim()===``&&n.push(i):t.push(i)}let i=[...t,...n];return{allSet:i.length===0,missing:i,empty:n}}function Fc(){return Pc().allSet}var Ic=Ac;function Lc(e){let t=e.map(e=>e.trim().toLowerCase()).filter(Boolean).filter((e,t,n)=>n.indexOf(e)===t),n=t.length?t.map(e=>`'${e.replace(/'/g,``)}'`).join(`, `):`'your@email.com'`;return kc.replace(/(function adminEmails\(\) \{\s*return )\[[^\]]*\];/,`$1[${n}];`)}function Rc(e){return e.split(/[,\s]+/).map(e=>e.trim()).filter(Boolean)}var zc=/^[^@\s]+@[^@\s]+\.[^@\s]+$/;function Bc({code:e,label:n,compact:a}){let[o,s]=r.default.useState(!1);return(0,i.jsxs)(t.fr.button,{whileHover:{scale:1.02},whileTap:{scale:.98},onClick:()=>{navigator.clipboard?.writeText(e),s(!0),setTimeout(()=>s(!1),2e3)},className:`inline-flex items-center font-bold transition-all shrink-0 cursor-pointer ${a?`gap-1.5 h-9 px-3 rounded-xl text-[12px] self-start sm:self-auto`:`gap-2 px-4 py-2 mt-2 rounded-xl text-[13px] tracking-wide`} ${o?`bg-emerald-500/10 text-emerald-500 border border-emerald-500/20`:`btn-secondary${a?``:` shadow-sm`}`}`,children:[o?(0,i.jsx)(t.Fi,{className:a?`w-3.5 h-3.5`:`w-4 h-4`}):(0,i.jsx)(t.Si,{className:a?`w-3.5 h-3.5`:`w-4 h-4`}),o?a?`Copied`:`Copied to Clipboard!`:n]})}function Vc(e){let t=``;try{t=new URL(e).hostname}catch{t=``}let n=t===`localhost`||t===`127.0.0.1`||t.endsWith(`.local`);return{host:t,local:n}}function Hc(){let{host:e,local:t}=Vc(typeof window>`u`?``:window.location.href);return e?(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl bg-background flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-3 px-4 py-3 mt-3`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`div`,{className:`text-[13.5px] font-bold text-foreground break-all sm:break-normal sm:truncate`,children:e}),(0,i.jsx)(`div`,{className:`text-[12.5px] text-foreground/50 font-medium`,children:t?`this machine — Firebase trusts it already, nothing to add`:`your app's address, read from this page`})]}),!t&&(0,i.jsx)(Bc,{compact:!0,code:e,label:`Copy the address`})]}):null}function Uc({name:e,shownAs:n,hint:a}){let[o,s]=r.default.useState(!1);return(0,i.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 sm:gap-3 px-4 py-3 border-b border-[var(--panel-border)]/40 last:border-0`,children:[(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(`div`,{className:`text-[13.5px] font-bold text-foreground break-all sm:break-normal sm:truncate`,children:e}),(0,i.jsx)(`div`,{className:`text-[12.5px] text-foreground/50 font-medium`,children:a??(0,i.jsxs)(i.Fragment,{children:[`the value Firebase labels `,n]})})]}),(0,i.jsxs)(`button`,{type:`button`,onClick:()=>{navigator.clipboard?.writeText(e),s(!0),setTimeout(()=>s(!1),2e3)},className:`inline-flex items-center gap-1.5 h-9 px-3 rounded-xl text-[12px] font-bold shrink-0 self-start sm:self-auto transition-all cursor-pointer active:scale-[0.98] ${o?`bg-emerald-500/10 text-emerald-500 border border-emerald-500/20`:`btn-secondary`}`,children:[o?(0,i.jsx)(t.Fi,{className:`w-3.5 h-3.5`}):(0,i.jsx)(t.Si,{className:`w-3.5 h-3.5`}),o?`Copied`:`Copy name`]})]})}var Wc={VITE_FIREBASE_API_KEY:`AIzaSyD3k9xQeL7vR2mN8pT4wY6…`,VITE_FIREBASE_AUTH_DOMAIN:`your-project.firebaseapp.com`,VITE_FIREBASE_PROJECT_ID:`your-project`,VITE_FIREBASE_MESSAGING_SENDER_ID:`482915736204`,VITE_FIREBASE_APP_ID:`1:482915736204:web:9c1e7a4b2d8f6e3a`},Gc=jc.map(({key:e})=>e===`VITE_FIREBASE_STORAGE_BUCKET`?{name:e,value:`leave empty`,empty:!0}:{name:e,value:Wc[e]});function Kc({name:e,value:n,empty:r}){return(0,i.jsxs)(`div`,{className:`px-3 sm:px-4 py-1.5 flex flex-col gap-1 sm:grid sm:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_2.25rem] sm:gap-3 sm:items-center`,children:[(0,i.jsx)(`div`,{title:e,className:`min-w-0 sm:h-9 sm:px-3 flex items-center sm:rounded-xl sm:bg-foreground/[0.05] text-[12.5px] sm:text-[13px] font-semibold text-foreground/80`,children:(0,i.jsx)(`span`,{className:`break-all sm:truncate`,children:e})}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 sm:contents`,children:[(0,i.jsx)(`div`,{className:`flex-1 min-w-0 h-9 px-3 flex items-center rounded-xl border text-[12.5px] sm:text-[13px] font-medium ${r?`border-dashed border-accent/40 text-accent`:`border-[var(--panel-border)]/60 text-foreground/45`}`,children:(0,i.jsx)(`span`,{className:`truncate`,children:n})}),(0,i.jsx)(`span`,{"aria-hidden":`true`,className:`w-9 h-9 shrink-0 rounded-xl flex items-center justify-center bg-foreground/[0.05] text-foreground/35`,children:(0,i.jsx)(t.gi,{className:`w-4 h-4`})})]})]})}function qc(){return(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl overflow-hidden bg-background`,children:[(0,i.jsx)(`div`,{className:`max-sm:hidden sm:grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_2.25rem] gap-3 px-4 pt-3.5 pb-1`,children:[`Name`,`Value`].map(e=>(0,i.jsx)(`span`,{className:`px-3 text-[12.5px] font-semibold text-foreground/45`,children:e},e))}),(0,i.jsx)(`div`,{className:`py-2 sm:py-1.5`,children:Gc.map(e=>(0,i.jsx)(Kc,{...e},e.name))}),(0,i.jsx)(`div`,{className:`flex justify-end px-3 sm:px-4 py-3 border-t border-[var(--panel-border)]/40`,children:(0,i.jsx)(`span`,{"aria-hidden":`true`,className:`btn-secondary inline-flex items-center h-9 px-4 rounded-xl text-[12.5px] font-bold select-none`,children:`Apply`})})]})}function Jc(){let[e,n]=(0,r.useState)(``),[a,o]=(0,r.useState)(``),[s,c]=(0,r.useState)([]),[l,u]=(0,r.useState)(``),d=e=>{n(e),a&&(o(``),c([])),l&&u(``)},f=()=>{let t=Rc(e);if(t.length===0){u(`Type an email address first — it is what the rules will name.`);return}let n=t.filter(e=>!zc.test(e));if(n.length>0){u(`That does not look like an email address: ${n.join(`, `)}`);return}u(``),c(t.map(e=>e.trim().toLowerCase())),o(Lc(t))};return(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl p-5 mb-2 flex flex-col gap-4`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3.5 min-w-0`,children:[(0,i.jsx)(`div`,{className:`w-10 h-10 rounded-2xl flex items-center justify-center shrink-0 border border-[var(--panel-border)]/50 bg-accent/10 text-accent`,children:(0,i.jsx)(t.Pr,{className:`w-5 h-5`})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0`,children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-bold text-foreground tracking-tight leading-tight truncate`,children:`Who runs this app?`}),(0,i.jsx)(`p`,{className:`text-[12px] text-foreground/50 font-normal leading-snug truncate`,children:`The email you sign in with becomes the owner — separate several with commas.`})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`text`,value:e,"aria-label":`The email address you will sign in with`,placeholder:`you@yourcompany.com`,onChange:e=>d(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),f())},className:`w-full h-10 px-3.5 rounded-[var(--input-radius,0.75rem)] border border-[var(--panel-border)] bg-[var(--panel-bg)] text-[13.5px] text-foreground outline-none transition-all duration-300 placeholder:text-foreground/35 hover:border-accent/40 focus:border-accent console-field ${l?`is-invalid border-red-500/60`:``}`}),(0,i.jsx)(`button`,{type:`button`,onClick:f,className:`btn-primary inline-flex items-center justify-center h-10 px-4 rounded-[var(--btn-radius,0.75rem)] text-[12.5px] font-bold text-white shrink-0 cursor-pointer active:scale-[0.98] transition-transform whitespace-nowrap`,children:`Generate the rules`})]}),l&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 leading-snug px-1`,children:l}),a&&(0,i.jsxs)(`div`,{className:`rounded-2xl border border-emerald-500/20 bg-emerald-500/[0.05] px-3.5 py-3 flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-3`,children:[(0,i.jsx)(`span`,{className:`w-7 h-7 rounded-full bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.Fi,{className:`w-3.5 h-3.5 text-emerald-500`})}),(0,i.jsxs)(`div`,{className:`min-w-0 flex-1 flex flex-col gap-0.5`,children:[(0,i.jsxs)(`p`,{"data-admin-emails":!0,className:`text-[13px] font-bold text-foreground leading-snug break-all`,children:[`Ready — they make `,s.join(`, `),` the owner.`]}),(0,i.jsx)(`p`,{className:`text-[12px] font-medium text-foreground/50 leading-snug`,children:`Paste them into Firebase, then sign in with that address — or reload, if you already are.`})]}),(0,i.jsx)(Bc,{compact:!0,code:a,label:`Copy the rules`})]})]})}var Yc=`text-accent underline underline-offset-2 font-semibold hover:text-accent-deep transition-colors`;function Xc({text:e,label:t}){return(0,i.jsxs)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl bg-background overflow-hidden`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-4 py-3 border-b border-[var(--panel-border)]/40`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-extrabold tracking-tight text-gradient truncate max-sm:hidden`,children:`Paste this into your assistant`}),(0,i.jsx)(Bc,{compact:!0,code:e,label:t})]}),(0,i.jsx)(`pre`,{className:`px-4 py-3 max-h-64 overflow-auto text-[11.5px] leading-relaxed font-mono text-foreground/70 whitespace-pre-wrap [overflow-wrap:anywhere]`,children:e})]})}function Zc({number:e,title:t,aside:n,children:r}){return(0,i.jsxs)(`div`,{className:`flex flex-col relative pb-10 mb-10 border-b border-[var(--panel-border)]/50 last:border-0 last:pb-0 last:mb-0`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3 mb-4`,children:[(0,i.jsx)(`span`,{className:`w-8 h-8 shrink-0 rounded-full bg-accent/10 border border-accent/20 text-accent flex items-center justify-center text-[14px] font-extrabold`,children:e}),(0,i.jsx)(`h3`,{className:`text-[17px] md:text-[19px] font-extrabold text-foreground tracking-tight flex-1 min-w-0`,children:t}),n]}),(0,i.jsx)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/70 leading-relaxed space-y-4`,children:r})]})}function Qc({basename:e}){return(0,i.jsxs)(`div`,{className:`mt-6 sm:mt-8 relative z-10 flex flex-col sm:flex-row sm:items-center gap-4 sm:gap-6 p-5 sm:p-6 rounded-3xl border border-accent/20 bg-accent/[0.06]`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,i.jsx)(`h3`,{className:`text-[16px] sm:text-[17px] font-extrabold text-foreground tracking-tight`,children:`Worked through every step?`}),(0,i.jsx)(`p`,{className:`text-[13px] sm:text-[13.5px] text-foreground/60 font-medium leading-relaxed mt-1`,children:`Your app will start again and take you to sign in. Use the email address you typed into the rules — that is the one this app knows as its owner.`})]}),(0,i.jsxs)(t.fr.button,{type:`button`,whileHover:{scale:1.02},whileTap:{scale:.98},onClick:()=>{Oc();let t=String(e||``).replace(/\/+$/,``);window.location.assign(`${t}/login`)},className:`btn-primary inline-flex items-center justify-center gap-2 h-12 px-6 rounded-[var(--btn-radius,0.75rem)] text-[13.5px] font-bold text-white shrink-0 cursor-pointer whitespace-nowrap shadow-lg`,children:[`I've completed all the steps`,(0,i.jsx)(t.Ki,{className:`w-4 h-4`})]})]})}function $c({standalone:e}){let n=t.ka(),[a,o]=Tc(),s=a===`local`,c={project:s?2:1,webApp:s?3:2,keys:s?4:3,signIn:s?5:4,database:s?6:5,storage:s?7:6},l=Vc(typeof window>`u`?``:window.location.href).local,[u]=(0,r.useState)(()=>{let e=localStorage.getItem(`theme-mode`);return e===`light`?!1:e===`dark`?!0:window.matchMedia(`(prefers-color-scheme: dark)`).matches});return(0,r.useEffect)(()=>{e&&document.documentElement.setAttribute(`data-theme`,u?`dark`:`light`)},[u,e]),(0,r.useEffect)(()=>{if(e&&t.Aa.faviconUrl){let e=document.querySelector(`link[rel*='icon']`);e||(e=document.createElement(`link`),e.rel=`icon`,document.head.appendChild(e)),e.href=t.Aa.faviconUrl}},[e]),(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(we,{children:`Setup`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/setup`]})]})}),(0,i.jsx)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-6 md:p-10 shadow-2xl relative overflow-hidden bg-background flex flex-col`,children:[(0,i.jsx)(`div`,{className:`mb-6 pb-4 sm:mb-8 sm:pb-6 border-b border-[var(--panel-border)]/50 relative z-10`,children:(0,i.jsxs)(`div`,{className:`flex max-sm:flex-col max-sm:items-stretch items-center justify-between gap-3 sm:gap-4`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,i.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-extrabold text-foreground tracking-tight truncate`,children:`Connect your app to Firebase`}),(0,i.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1 sm:mt-1.5 leading-snug truncate`,children:[(0,i.jsx)(`span`,{className:`sm:hidden`,children:`Google's free data and sign-in service.`}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:`Firebase is Google's free service that stores your data and signs people in — about ten minutes, once.`})]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(t.fr.a,{whileHover:{scale:1.05},whileTap:{scale:.95},href:`mailto:antonina@youraiworkflow.co`,title:`Email Support`,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer btn-secondary`,children:(0,i.jsx)(t.Xr,{className:`w-4 h-4`})}),(0,i.jsx)(t.fr.a,{whileHover:{scale:1.05},whileTap:{scale:.95},href:`https://wa.me/34632407883`,target:`_blank`,rel:`noopener noreferrer`,title:`WhatsApp Support`,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer btn-secondary`,children:(0,i.jsx)(Sc,{className:`w-4 h-4 text-foreground/80`})})]})]})}),!1,(0,i.jsxs)(`div`,{className:`flex flex-col relative z-10 p-4 sm:p-6 md:p-8 bg-foreground/[0.015] rounded-3xl border border-[var(--panel-border)]/50`,children:[s&&(0,i.jsxs)(Zc,{number:1,title:`Set your project up`,children:[(0,i.jsx)(`p`,{className:`text-foreground/80`,children:`Your assistant does this part — none of it is yours to type. Copy the block below into Claude Code, Codex or Antigravity and let it finish before you carry on. If you are already looking at this page on your own machine, paste it anyway: it only fills in what is missing and changes nothing that is already right.`}),(0,i.jsx)(Xc,{text:Ec,label:`Copy the setup prompt`}),(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`One of the lines it writes is `,(0,i.jsx)(`strong`,{children:`GEMINI_API_KEY`}),`, and it stays empty unless you later ask for something that uses AI — a chatbot, a writing helper. A free key comes from`,` `,(0,i.jsx)(`a`,{href:`https://aistudio.google.com/apikey`,target:`_blank`,rel:`noopener noreferrer`,className:Yc,children:`aistudio.google.com/apikey`}),` `,`when that day comes.`]})]}),(0,i.jsx)(Zc,{number:c.project,title:`Create a Firebase project`,children:(0,i.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-foreground/80`,children:[(0,i.jsxs)(`li`,{children:[`Open`,` `,(0,i.jsx)(`a`,{href:`https://console.firebase.google.com`,target:`_blank`,rel:`noopener noreferrer`,className:`text-accent underline underline-offset-2 font-semibold hover:text-accent-deep transition-colors`,children:`console.firebase.google.com`}),` `,`and click `,(0,i.jsx)(`strong`,{children:`Add project`}),`. Sign in with your Google account if it asks.`]}),(0,i.jsxs)(`li`,{children:[`Type any name you like and click `,(0,i.jsx)(`strong`,{children:`Continue`}),`.`]}),(0,i.jsxs)(`li`,{children:[`If it offers `,(0,i.jsx)(`strong`,{children:`Enable Gemini in Firebase`}),`, switch it off.`]}),(0,i.jsxs)(`li`,{children:[`Switch off `,(0,i.jsx)(`strong`,{children:`Enable Google Analytics for this project`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Create project`}),`, wait, then click `,(0,i.jsx)(`strong`,{children:`Continue`}),`.`]})]})}),(0,i.jsx)(Zc,{number:c.webApp,title:`Add a web app and copy the six values`,children:(0,i.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-foreground/80`,children:[(0,i.jsxs)(`li`,{children:[`On that page click `,(0,i.jsx)(`strong`,{children:`+ Add app`}),` under your project's name, then pick the `,(0,i.jsx)(`strong`,{children:`</> Web`}),` icon.`]}),(0,i.jsxs)(`li`,{children:[`Give it any nickname (`,(0,i.jsx)(`span`,{className:`text-accent`,children:`MyApp`}),` is fine). Leave `,(0,i.jsx)(`strong`,{children:`Firebase Hosting`}),` unticked.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Register app`}),`.`]}),(0,i.jsx)(`li`,{children:`Firebase now shows six values on screen, each with a label beside it — apiKey, authDomain, projectId, storageBucket, messagingSenderId and appId. You will copy them one at a time in the next step, so keep this tab open.`})]})}),(0,i.jsx)(Zc,{number:c.keys,title:s?`Put the six values in your .env`:`Paste the values into the environment variables window`,children:s?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`Step 1 made a `,(0,i.jsx)(`strong`,{children:`.env`}),` file, and every name below is already a line in it. Open it — or ask your assistant to open it for you — and put each value from your Firebase tab between that line's quotes. The names have to match letter for letter, so find them with the Copy name button rather than retyping.`]}),(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`Six lines, and that is all of them. Fill five of them now and leave`,` `,(0,i.jsx)(`strong`,{children:`VITE_FIREBASE_STORAGE_BUCKET`}),` empty — step `,c.storage,` gives you its real value.`]}),(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[(0,i.jsx)(`strong`,{children:`Leave the app as it is for now.`}),` One value is still missing, and starting it again is the last thing you do on this whole page.`]}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-2xl overflow-hidden bg-background`,children:jc.map(({key:e,shownAs:t})=>(0,i.jsx)(Uc,{name:e,shownAs:t,hint:e===`VITE_FIREBASE_STORAGE_BUCKET`?`leave this one empty — step ${c.storage} gives you the real address`:void 0},e))})]}):(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`AI Studio pops up a window that says`,` `,(0,i.jsx)(`strong`,{children:`Enter your environment variables to continue`}),`, with a form like the one below. Paste each value from your Firebase tab into its row — the values below are only examples of what each one looks like.`]}),(0,i.jsxs)(`p`,{className:`text-foreground/80`,children:[`Leave `,(0,i.jsx)(`strong`,{children:`VITE_FIREBASE_STORAGE_BUCKET`}),` empty and keep the window open — don't press `,(0,i.jsx)(`strong`,{children:`Apply`}),` yet. Step `,c.storage,` gives you the last value, and Apply comes after it.`]}),(0,i.jsx)(qc,{})]})}),(0,i.jsxs)(Zc,{number:c.signIn,title:`Turn on sign-in`,children:[(0,i.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-foreground/80`,children:[(0,i.jsxs)(`li`,{children:[`In the Firebase menu on the left, open `,(0,i.jsx)(`strong`,{children:`Authentication`}),` and click `,(0,i.jsx)(`strong`,{children:`Get started`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Open the `,(0,i.jsx)(`strong`,{children:`Sign-in method`}),` tab.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Email/Password`}),`, switch on the first toggle and `,(0,i.jsx)(`strong`,{children:`Save`}),`. (Leave email link off.)`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Add provider`}),`, choose `,(0,i.jsx)(`strong`,{children:`Google`}),`, switch it on, pick your own address as the support email, and `,(0,i.jsx)(`strong`,{children:`Save`}),`. The app needs this for the `,(0,i.jsx)(`strong`,{children:`Sign in with Google`}),` button to work.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Add provider`}),`, choose `,(0,i.jsx)(`strong`,{children:`Anonymous`}),`, switch it on, and `,(0,i.jsx)(`strong`,{children:`Save`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Open the `,(0,i.jsx)(`strong`,{children:`Settings`}),` tab, then `,(0,i.jsx)(`strong`,{children:`Authorized domains`}),`. Your app has to be listed here or nobody can sign in.`]}),l?(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Nothing to add here yet.`}),` This app is being served from your own machine, and Firebase trusts that address from the start. Come back and add the real one the day you put your app on the internet.`]}):(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Your app's address is right here`}),` — copy it below, then in Firebase click `,(0,i.jsx)(`strong`,{children:`Add domain`}),`, paste it, and save.`]})]}),(0,i.jsx)(Hc,{})]}),(0,i.jsxs)(Zc,{number:c.database,title:`Create the database and publish its rules`,children:[(0,i.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-foreground/80 mb-4`,children:[(0,i.jsxs)(`li`,{children:[`In the Firebase menu, open `,(0,i.jsx)(`strong`,{children:`Firestore Database`}),` and click `,(0,i.jsx)(`strong`,{children:`Create database`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Pick `,(0,i.jsx)(`strong`,{children:`Standard edition`}),` if asked, choose the location closest to your people, start in `,(0,i.jsx)(`strong`,{children:`Production mode`}),`, and click Continue.`]}),(0,i.jsxs)(`li`,{children:[`In the box below, type the email address you will sign in with and click `,(0,i.jsx)(`strong`,{children:`Generate the rules`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Copy the rules`}),`, then in Firebase open the `,(0,i.jsx)(`strong`,{children:`Rules`}),` tab, select everything that is there, paste over it, and click `,(0,i.jsx)(`strong`,{children:`Publish`}),`.`]})]}),(0,i.jsx)(Jc,{})]}),(0,i.jsxs)(Zc,{number:c.storage,title:`Create storage and publish its rules`,children:[(0,i.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-foreground/80 mb-4`,children:[(0,i.jsxs)(`li`,{children:[`In the Firebase menu, open `,(0,i.jsx)(`strong`,{children:`Storage`}),`. Google asks you to upgrade the project first: click `,(0,i.jsx)(`strong`,{children:`Upgrade project`}),` and pick the pay-as-you-go`,` `,(0,i.jsx)(`strong`,{children:`Blaze plan`}),`. Profile photos and attachments cost about $0.03 per gigabyte a month, so this is cents. Set a budget you are comfortable with (say $20), link a billing account, and continue.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Get started`}),`, choose a no-cost location, start in `,(0,i.jsx)(`strong`,{children:`Production mode`}),`, and click `,(0,i.jsx)(`strong`,{children:`Create`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Open the `,(0,i.jsx)(`strong`,{children:`Rules`}),` tab, select everything that is there, paste these over it, and click `,(0,i.jsx)(`strong`,{children:`Publish`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Now Firebase shows the storage address at the top of the page — something like`,` `,`your-project.firebasestorage.app. `,(0,i.jsx)(`strong`,{children:`Copy that`}),`. This is the real one; the one Firebase showed you back in step `,c.webApp,` was a guess made before storage existed.`]}),s?(0,i.jsxs)(`li`,{children:[`Back in your `,(0,i.jsx)(`strong`,{children:`.env`}),` file, paste it into`,` `,(0,i.jsx)(`strong`,{children:`VITE_FIREBASE_STORAGE_BUCKET`}),` — the line you left empty.`]}):(0,i.jsxs)(`li`,{children:[`Back in the environment variables window from step `,c.keys,`, paste it into`,` `,(0,i.jsx)(`strong`,{children:`VITE_FIREBASE_STORAGE_BUCKET`}),` — the row you left empty.`]}),s?(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Start the app again.`}),` Stop it and start it once more — or just ask your assistant to restart it. A value added while it is running is not read until then. That is the last thing to do: then reload this page and your app is connected.`]}):(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Press Apply, then reload this page.`}),` Your app is connected.`]})]}),(0,i.jsx)(Bc,{code:Ic,label:`Copy the storage rules`})]})]}),(0,i.jsx)(Qc,{basename:n.basename})]})})]})}var el={email:{collection:`sys_configs`,doc:`email`},payments:{collection:`sys_payments`,doc:`_settings`}},tl=e=>e?.enabled!==!1;function nl(e){let{collection:n,doc:i}=el[e],[a,s]=(0,r.useState)({loading:!0,on:!0});return(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(t.Ca,n,i),e=>s({loading:!1,on:tl(e.exists()?e.data():null)}),()=>s({loading:!1,on:!0})),[n,i]),{loading:a.loading,on:a.on,set:async r=>{let c=a.on;s({loading:!1,on:r});try{return await(0,o.setDoc)((0,o.doc)(t.Ca,n,i),{enabled:r},{merge:!0}),e===`payments`&&Y(),null}catch{return s({loading:!1,on:c}),`The switch could not be saved. Check that you are signed in as an admin.`}}}}var rl=`The server could not be reached.`;function il(e,t,n=0){let[i,a]=(0,r.useState)(null),[o,s]=(0,r.useState)(``),c=(0,r.useRef)(!0);(0,r.useEffect)(()=>(c.current=!0,()=>{c.current=!1}),[]);let l=(0,r.useRef)(t);(0,r.useEffect)(()=>{l.current=t},[t]);let u=(0,r.useCallback)(async()=>{try{let t=await(await fetch(e)).json();if(!c.current)return;a(l.current(t)),s(``)}catch{c.current&&s(rl)}},[e]);return(0,r.useEffect)(()=>{if(u(),!n)return;let e=setInterval(u,n);return()=>clearInterval(e)},[u,n]),{status:i,error:o,reread:u}}var al=e=>({configured:!!e?.configured,mode:e?.mode===`live`||e?.mode===`test`?e.mode:null,webhookConfigured:!!e?.webhookConfigured}),ol=e=>({configured:!!e?.configured,from:e?.from??null,adminCount:Number(e?.adminCount)||0}),sl={email:`/api/email/status`,payments:`/api/payments/status`},cl=(e=0)=>il(sl.payments,al,e),ll=(e=0)=>il(sl.email,ol,e),ul=e=>!!e?.configured;function dl(e){let t=il(sl[e],ul),n=nl(e);return{loading:t.status===null&&!t.error||n.loading,configured:t.status===!0,on:n.on}}var fl={collection:`sys_configs`,doc:`publish`},pl=[`published`,`connected`,`authorised`],ml={appName:``,domain:``,done:[]};function hl(e){let t=Array.isArray(e?.done)?e.done:[];return{appName:typeof e?.appName==`string`?e.appName:``,domain:typeof e?.domain==`string`?e.domain:``,done:pl.filter(e=>t.includes(e))}}function gl(e){let t=String(e??``).trim().toLowerCase();return t=t.replace(/^[a-z][a-z0-9+.-]*:\/\//,``),t=t.split(/[/?#]/)[0],t=t.replace(/\.ai\.studio$/,``),t.replace(/[\s_]+/g,`-`).replace(/[^a-z0-9-]/g,``).replace(/-{2,}/g,`-`).replace(/^-+|-+$/g,``)}var _l=e=>{let t=gl(e);return t?`https://${t}.ai.studio/`:``};function vl(e){let t=String(e??``).trim().toLowerCase();return t=t.replace(/^[a-z][a-z0-9+.-]*:\/\//,``),t=t.replace(/^[^/@]*@/,``),t=t.split(/[/?#]/)[0],t=t.split(`:`)[0],t=t.replace(/^www\./,``),t=t.replace(/^\.+|\.+$/g,``),/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*\.[a-z]{2,}$/.test(t)?t:``}var yl=e=>{let t=vl(e);return t?`https://${t}/`:``},bl=e=>yl(e?.domain)||_l(e?.appName);function xl(e,t=null){let n=t=>e.includes(t),r=pl.find(e=>!n(e))??null,i=r?pl.indexOf(r):pl.length-1;return pl.map((e,a)=>{let o=a<=i,s=t!==null&&t===e&&o;return{id:e,visible:o,done:n(e),open:s||t===null&&e===r}})}var Sl=(e,t)=>pl.filter(n=>n===t||e.includes(n));function Cl(e){return!e||!e.configured?!1:e.mode===`live`?!e.webhookConfigured:!0}function wl(){let[e,n]=(0,r.useState)({loading:!0,record:ml});return(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(t.Ca,fl.collection,fl.doc),e=>n({loading:!1,record:hl(e.exists()?e.data():null)}),()=>n({loading:!1,record:ml})),[]),{loading:e.loading,record:e.record,save:async e=>{n(t=>({loading:!1,record:{...t.record,...e}}));try{return await(0,o.setDoc)((0,o.doc)(t.Ca,fl.collection,fl.doc),e,{merge:!0}),null}catch(e){return console.error(`Could not save where you got to`,e),`That could not be saved. Only an admin can, and only while you are signed in.`}}}}function Tl(e,t){return!e&&t!==`live`?{state:`off`,label:`In test mode`}:t===`live`?{state:`saved`,label:`Live`}:{state:`saving`,label:`Waiting for the live key`}}var El=[`checkout.session.completed`,`checkout.session.async_payment_succeeded`],Dl=`text-[12.5px] font-medium text-foreground/70 leading-relaxed`,Ol=`mt-1.5 space-y-1 list-disc list-inside marker:text-foreground/30`,kl=`my-2 glass-panel border border-[var(--panel-border)] rounded-2xl overflow-hidden bg-background`;function Al(){let[e,n]=(0,r.useState)(null),[a,s]=(0,r.useState)([]),{status:l}=cl(5e3),u=l?.mode??null,d=l?.webhookConfigured??!1,[f]=Tc(),p=f===`local`,{record:m}=wl(),h=B(bl(m)),g=m.done.includes(`authorised`)&&!!h;(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.collection)(t.Ca,Nn),e=>{n(!!e.docs.find(e=>e.id===Pn)?.data()?.liveMode);let t=[];e.forEach(e=>{e.id!==`_settings`&&t.push(Gn(e.id,e.data()))}),t.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)),s(t)},()=>n(!1)),[]);let _=async e=>{n(e);try{await(0,o.setDoc)((0,o.doc)(t.Ca,Nn,Pn),{liveMode:e},{merge:!0})}catch(e){console.error(`Could not save the go-live switch`,e)}},v=!!e,y=Tl(v,u),b=a.filter(e=>Yn(e,!1)),x=b.filter(e=>!Yn(e,!0)),S=b.length>0&&x.length===0,C=b.some(e=>e.kind===`subscription`);return(0,i.jsx)(t.ut,{icon:t.Rr,title:`Go live`,description:v?`Real cards, real money — the steps below finish the switch.`:`Practice is free — flip this only when a test payment has gone all the way through.`,chip:y,enabled:e===null?null:v,onChange:_,children:v&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(`ol`,{className:`space-y-3.5 list-decimal list-inside ${Dl}`,children:[(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Your live secret key.`}),` In Stripe, click your account name in the top left corner and choose your `,(0,i.jsx)(`strong`,{children:`live`}),` account — not the sandbox.`,(0,i.jsxs)(`ul`,{className:Ol,children:[(0,i.jsxs)(`li`,{children:[`Open the dark strip along the bottom that says `,(0,i.jsx)(`strong`,{children:`Developers`}),`, and scroll down to the `,(0,i.jsx)(`strong`,{children:`API keys`}),` section.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Manage API keys`}),`. Under `,(0,i.jsx)(`strong`,{children:`Standard keys`}),`, click `,(0,i.jsx)(`strong`,{children:`+ Create secret key`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Where it asks `,(0,i.jsx)(`em`,{children:`How will you be using this key?`}),`, choose`,` `,(0,i.jsx)(`strong`,{children:`Powering an integration you built`}),`, then`,` `,(0,i.jsx)(`strong`,{children:`Create secret key`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Stripe asks you to confirm it is you: click `,(0,i.jsx)(`strong`,{children:`Send verification`}),` `,`and verify the request with the code it sends.`]}),(0,i.jsxs)(`li`,{children:[`Give the key a name — `,(0,i.jsx)(`span`,{className:`text-accent`,children:`my ai project app key`}),` `,`— and copy it. `,(0,i.jsx)(`strong`,{children:`Stripe will not show it to you again.`})]}),p?(0,i.jsxs)(`li`,{children:[`Open your `,(0,i.jsx)(`strong`,{children:`.env`}),` file and paste it over the sk_test_… value of `,(0,i.jsx)(`strong`,{children:`STRIPE_SECRET_KEY`}),` — replace it, do not add a second line. Start the app again, and the chip at the top of this card turns to `,(0,i.jsx)(`strong`,{children:`Live`}),` on its own.`]}):(0,i.jsxs)(`li`,{children:[`Click the `,(0,i.jsx)(`strong`,{children:`cog icon`}),` in the top right corner of your app in Google AI Studio and find the `,(0,i.jsx)(`strong`,{children:`Secrets`}),` tab. Paste the new key over the value of `,(0,i.jsx)(`strong`,{children:`STRIPE_SECRET_KEY`}),` — replace the sk_test_… one, do not add a second. Click `,(0,i.jsx)(`strong`,{children:`Apply`}),` and refresh this page: the chip at the top of this card turns to `,(0,i.jsx)(`strong`,{children:`Live`}),` on its own.`]})]})]}),C&&(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`Your live price ids.`}),` A subscription's prices are made fresh in live mode, so the ids under `,(0,i.jsx)(`strong`,{children:`What you sell`}),` change. Create each plan's price in your live Stripe account and paste its id there. Your test ids are kept and come straight back if you switch off again.`]}),(0,i.jsxs)(`li`,{children:[(0,i.jsx)(`strong`,{children:`The webhook.`}),` `,g?`What keeps receipts and your sale alerts sending when a buyer pays and never comes back to your app.`:`Stripe has to be able to reach your app from the outside, so this one waits until your app is published.`,` `,(0,i.jsx)(`span`,{className:`inline-block align-middle ml-0.5`,children:(0,i.jsx)(t.lt,{state:d?`saved`:`off`,label:d?`Connected`:`Not yet`})}),g?(0,i.jsxs)(`ul`,{className:Ol,children:[(0,i.jsxs)(`li`,{children:[`Still in your `,(0,i.jsx)(`strong`,{children:`live`}),` Stripe account, open the`,` `,(0,i.jsx)(`strong`,{children:`Developers`}),` strip at the bottom again and, in its top menu, click `,(0,i.jsx)(`strong`,{children:`Webhooks`}),`. Click `,(0,i.jsx)(`strong`,{children:`Add destination`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Leave every setting as it is. Under `,(0,i.jsx)(`strong`,{children:`Events`}),`, use the`,` `,(0,i.jsx)(`em`,{children:`Find event by name or description…`}),` search bar to find these two, and click the checkmark on each:`,(0,i.jsx)(`div`,{className:`mt-1.5 flex flex-col gap-1`,children:El.map(e=>(0,i.jsx)(Bc,{code:e,label:e,compact:!0},e))}),`The first is an ordinary card payment. The second is a bank transfer landing hours later, when nobody is watching — without it those sales send no email at all.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Continue`}),` and keep it as a`,` `,(0,i.jsx)(`strong`,{children:`Webhook endpoint`}),`. Give the destination a name —`,` `,(0,i.jsx)(`span`,{className:`text-accent`,children:`my ai project receipts`}),`.`]}),(0,i.jsxs)(`li`,{children:[`As the `,(0,i.jsx)(`strong`,{children:`Endpoint URL`}),`, paste exactly this — your published address with the webhook route on the end:`,(0,i.jsx)(`div`,{className:`my-2`,children:(0,i.jsx)(Bc,{code:h,label:`Copy your webhook address`,compact:!0})})]}),(0,i.jsxs)(`li`,{children:[`Create the destination. On the right, under Webhooks, you will find its`,` `,(0,i.jsx)(`strong`,{children:`signing secret`}),` — it starts with `,(0,i.jsx)(`strong`,{children:`whsec_`}),`. Copy it.`]}),(0,i.jsxs)(`li`,{children:[p?(0,i.jsxs)(i.Fragment,{children:[`Add the line below to your `,(0,i.jsx)(`strong`,{children:`.env`}),` file with the whsec_… secret as its value, and start the app again. You are all set — the chip beside this step turns green.`]}):(0,i.jsxs)(i.Fragment,{children:[`Click the `,(0,i.jsx)(`strong`,{children:`cog icon`}),` in the top right corner of your app in Google AI Studio, scroll the menu along the top to `,(0,i.jsx)(`strong`,{children:`Secrets`}),` `,`and click `,(0,i.jsx)(`strong`,{children:`+ Add secret`}),`. Copy the name below into`,` `,(0,i.jsx)(`strong`,{children:`Secret name`}),` and paste the whsec_… secret as its value. Click `,(0,i.jsx)(`strong`,{children:`Apply`}),` and refresh this page. You are all set — the chip beside this step turns green.`]}),(0,i.jsx)(`div`,{className:kl,children:(0,i.jsx)(Uc,{name:`STRIPE_WEBHOOK_SECRET`,hint:`the whsec_… signing secret from the destination you just made`})})]})]}):(0,i.jsxs)(`div`,{className:`mt-2 flex flex-col gap-2.5`,children:[(0,i.jsxs)(t.st,{children:[`Your app has no public address yet, and the preview address in this browser is not one Stripe can reach — it changes every session.`,` `,m.done.length===0?`Publish your app first`:`Finish publishing your app first`,`: this step opens on its own once step 3 of Publish App,`,` `,(0,i.jsx)(`strong`,{children:`Add your domains and email sender`}),`, is ticked. Everything above works in the meantime.`]}),(0,i.jsxs)(c.Link,{to:`/publish`,className:`inline-flex items-center gap-1.5 w-fit h-9 px-4 rounded-[var(--btn-radius,0.75rem)] text-[12.5px] font-bold border border-accent/40 bg-accent/10 text-accent hover:bg-accent/15 transition-all active:scale-[0.98] cursor-pointer`,children:[`Take me to Publish App`,(0,i.jsx)(t.Ki,{className:`w-3.5 h-3.5`})]})]})]})]}),(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`One more switch lives in Stripe, not here: switching plans (monthly ↔ yearly, Basic ↔ Pro) appears in Stripe’s customer portal — where your buyers manage their own subscriptions — only if you allow it:`,` `,(0,i.jsx)(`a`,{href:`https://dashboard.stripe.com/settings/billing/portal`,target:`_blank`,rel:`noopener noreferrer`,className:`text-accent font-bold hover:underline`,children:`Stripe Settings → Billing → Customer portal`}),` `,`→ let customers switch plans.`]}),b.length>0&&!S&&(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Your subscriptions under What you sell now ask for `,(0,i.jsx)(`strong`,{children:`live`}),` price ids — `,x.length===b.length?`each one`:`${x.length} of ${b.length}`,` is still waiting. Your test ids are kept and come back if you switch back. Once the live ids are in, the message for your assistant appears right here.`]}),S&&(0,i.jsx)(at,{title:`Tell your assistant about the switch`,prompt:Nr(b)})]})})}var jl={configured:!1,mode:null,webhookConfigured:!1};function Ml(e=5e3){let{status:t,error:n}=cl(e);return{...t??jl,checked:t!==null||!!n}}function Nl(e,t){if(!t.checked)return{state:`saving`,label:`Checking`};switch(e){case 1:case 2:return t.configured?{state:`saved`,label:`Done`}:{state:`off`,label:`Not yet`};case 3:return t.configured?{state:`saved`,label:t.mode===`live`?`Key found — live`:`Key found — test mode`}:{state:`off`,label:`No key yet`}}}var Pl={configured:!1,from:null,adminCount:0};function Fl(e=5e3){let{status:t,error:n}=ll(e);return{...t??Pl,checked:t!==null||!!n}}function Il(e){return e.checked?e.configured?{state:`saved`,label:`Connected`}:{state:`off`,label:`Not yet`}:{state:`saving`,label:`Checking`}}function Ll(e){return e.checked?e.from&&!String(e.from).toLowerCase().endsWith(`@resend.dev`)?{state:`saved`,label:`Your own address`}:{state:`off`,label:`Practice address`}:{state:`saving`,label:`Checking`}}var Rl=`text-accent underline underline-offset-2 font-semibold hover:text-accent-deep transition-colors`;function zl({href:e,children:t}){return(0,i.jsx)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,className:Rl,children:t})}function Bl({number:e,title:t,aside:n,children:r}){return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 pb-5 mb-5 border-b border-[var(--panel-border)]/50 last:border-0 last:pb-0 last:mb-0`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5`,children:[(0,i.jsx)(`span`,{className:`w-7 h-7 shrink-0 rounded-full bg-accent/10 border border-accent/20 text-accent flex items-center justify-center text-[12.5px] font-extrabold`,children:e}),(0,i.jsx)(`h4`,{className:`text-[14px] font-bold text-foreground tracking-tight flex-1 min-w-0`,children:t}),n]}),(0,i.jsx)(`div`,{className:`text-[13px] text-foreground/70 leading-relaxed space-y-3 sm:pl-[2.375rem]`,children:r})]})}var Vl=`space-y-1.5 list-decimal list-inside text-foreground/75`,Hl=`glass-panel border border-[var(--panel-border)] rounded-2xl overflow-hidden bg-background`;function Ul({onConfirm:e,hint:n}){let[r]=Tc();return(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 pt-1`,children:[(0,i.jsx)(t.Q,{icon:t.Fi,onClick:e,className:`self-start`,children:`I have added the variables`}),(0,i.jsx)(`p`,{className:t.$,children:n||(r===`local`?`Start the app again first — a value added to .env while it is running is not read until then. If the chips have not turned green a minute later, reload this page.`:`Press Apply in AI Studio’s Secrets tab first — the app can only read a secret once it has been applied. If the chips have not turned green a minute later, reload this page.`)})]})}function Wl({icon:e,title:n,description:r,stepsDescription:a,button:o,secret:s,open:c,onOpen:l,confirmed:u,steps:d,children:f}){let[p]=Tc();return(0,i.jsx)(t.at,{icon:e,title:n,description:c?a:r,collapsible:!1,children:c?d:(0,i.jsxs)(i.Fragment,{children:[f,u&&(0,i.jsxs)(t.st,{tone:`error`,children:[`The app cannot see the key yet.`,` `,p===`local`?(0,i.jsxs)(i.Fragment,{children:[`Make sure `,s,` has a value in your .env file, start the app again, then reload this page`]}):(0,i.jsxs)(i.Fragment,{children:[`In AI Studio’s Secrets tab make sure `,s,` is there and press Apply, then reload this page`]}),` `,`— or open the steps again to check them.`]}),(0,i.jsxs)(`button`,{type:`button`,onClick:l,className:`inline-flex items-center gap-1.5 w-fit h-9 px-4 rounded-[var(--btn-radius,0.75rem)] text-[12.5px] font-bold border border-accent/40 bg-accent/10 text-accent hover:bg-accent/15 transition-all active:scale-[0.98] cursor-pointer`,children:[o,(0,i.jsx)(t.Ki,{className:`w-3.5 h-3.5`})]})]})})}function Gl({onConfirm:e}){let n=Ml(),[r]=Tc(),a=r===`local`;return(0,i.jsxs)(`div`,{className:`flex flex-col`,children:[(0,i.jsx)(Bl,{number:1,title:`Make a Stripe account`,aside:(0,i.jsx)(t.lt,{...Nl(1,n)}),children:(0,i.jsxs)(`ol`,{className:Vl,children:[(0,i.jsxs)(`li`,{children:[`Open `,(0,i.jsx)(zl,{href:`https://dashboard.stripe.com`,children:`dashboard.stripe.com`}),` and create an account. It asks about your business — answer what you can and skip what you can't; none of it blocks the next steps.`]}),(0,i.jsxs)(`li`,{children:[`Click your account name in the `,(0,i.jsx)(`strong`,{children:`top left`}),` corner, choose`,` `,(0,i.jsx)(`strong`,{children:`Switch to sandbox`}),`, and make a sandbox for testing. A sandbox is a practice copy of Stripe: every card in it is pretend and every payment is practice, so nothing you do here can cost anyone real money.`]})]})}),(0,i.jsx)(Bl,{number:2,title:`Copy the test secret key`,aside:(0,i.jsx)(t.lt,{...Nl(2,n)}),children:(0,i.jsxs)(`ol`,{className:Vl,children:[(0,i.jsxs)(`li`,{children:[`Along the very bottom of the Stripe page is a dark bar that says `,(0,i.jsx)(`strong`,{children:`Developers`}),`. Click the arrow on it to unfold the panel.`]}),(0,i.jsxs)(`li`,{children:[`On the right of that panel, under `,(0,i.jsx)(`strong`,{children:`Testing tools`}),`, is your`,` `,(0,i.jsx)(`strong`,{children:`secret key`}),` — it starts with `,(0,i.jsx)(`strong`,{children:`sk_test_`}),`. Copy it.`]})]})}),(0,i.jsxs)(Bl,{number:3,title:a?`Put it in your .env and start the app again`:`Paste it into Secrets and press Apply`,aside:(0,i.jsx)(t.lt,{...Nl(3,n)}),children:[a?(0,i.jsxs)(`p`,{children:[`Open your `,(0,i.jsx)(`strong`,{children:`.env`}),` file — or ask your assistant to. The line below is already in it: paste the sk_test_… key between its quotes. One line, and that is the whole step — then `,(0,i.jsx)(`strong`,{children:`start the app again`}),` so it is read.`]}):(0,i.jsxs)(`ol`,{className:Vl,children:[(0,i.jsxs)(`li`,{children:[`Click the `,(0,i.jsx)(`strong`,{children:`cog`}),` icon in the top right corner of your app in Google AI Studio.`]}),(0,i.jsxs)(`li`,{children:[`In the menu along the top, scroll across to `,(0,i.jsx)(`strong`,{children:`Secrets`}),`, then click`,` `,(0,i.jsx)(`strong`,{children:`+ Add secret`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Copy the name below into `,(0,i.jsx)(`strong`,{children:`Secret name`}),`, and paste the sk_test_… key you just copied as the value.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Apply`}),`, then refresh the page. You are all set.`]})]}),(0,i.jsx)(`div`,{className:Hl,children:(0,i.jsx)(Uc,{name:`STRIPE_SECRET_KEY`,hint:`the sk_test_… key you copied in step 2`})}),(0,i.jsxs)(`p`,{children:[`Now you can test a payment with the pretend card `,(0,i.jsx)(`strong`,{children:`4242 4242 4242 4242`}),` and any other details you like, or by paying with Google Pay or Apple Pay. Nothing is ever charged — a sandbox is all practice.`]})]}),(0,i.jsx)(Ul,{onConfirm:e})]})}function Kl({onConfirm:e}){let n=Fl(),[r]=Tc(),a=r===`local`;return(0,i.jsxs)(`div`,{className:`flex flex-col`,children:[(0,i.jsx)(Bl,{number:1,title:`Make a Resend account and a key`,aside:(0,i.jsx)(t.lt,{...Il(n)}),children:(0,i.jsxs)(`ol`,{className:Vl,children:[(0,i.jsxs)(`li`,{children:[`Open `,(0,i.jsx)(zl,{href:`https://resend.com`,children:`resend.com`}),` and create a free account — it is the service that delivers email for you. Sign up with the address you want your app's mail to reach you at.`]}),(0,i.jsxs)(`li`,{children:[`In Resend, open `,(0,i.jsx)(`strong`,{children:`API Keys`}),` and click `,(0,i.jsx)(`strong`,{children:`Create API key`}),`. Copy the key it shows — it starts with `,(0,i.jsx)(`strong`,{children:`re_`}),` — and keep the tab open.`]})]})}),(0,i.jsxs)(Bl,{number:2,title:a?`Put two values in your .env and start the app again`:`Paste two secrets and press Apply`,aside:(0,i.jsx)(t.lt,{...Il(n)}),children:[a?(0,i.jsxs)(`p`,{children:[`Open your `,(0,i.jsx)(`strong`,{children:`.env`}),` file. Both lines below are already in it — paste each value between its quotes, then `,(0,i.jsx)(`strong`,{children:`start the app again`}),` so they are read.`]}):(0,i.jsxs)(`ol`,{className:Vl,children:[(0,i.jsxs)(`li`,{children:[`Click the `,(0,i.jsx)(`strong`,{children:`cog`}),` icon in the top right corner of your app in Google AI Studio.`]}),(0,i.jsxs)(`li`,{children:[`In the menu along the top, scroll across to `,(0,i.jsx)(`strong`,{children:`Secrets`}),`.`]}),(0,i.jsxs)(`li`,{children:[`For each row below, click `,(0,i.jsx)(`strong`,{children:`+ Add secret`}),`, copy the name here into`,` `,(0,i.jsx)(`strong`,{children:`Secret name`}),`, and paste the value.`]}),(0,i.jsxs)(`li`,{children:[`Click `,(0,i.jsx)(`strong`,{children:`Apply`}),`, then refresh the page.`]})]}),(0,i.jsxs)(`div`,{className:Hl,children:[(0,i.jsx)(Uc,{name:`RESEND_API_KEY`,hint:`the re_… key you just made in Resend`}),(0,i.jsx)(Uc,{name:`ADMIN_EMAILS`,hint:`your own email address — where sale, booking and form alerts are sent`})]})]}),(0,i.jsxs)(Bl,{number:3,title:`Verify your domain, or mail only reaches you`,aside:(0,i.jsx)(t.lt,{...Ll(n)}),children:[(0,i.jsxs)(`p`,{children:[(0,i.jsx)(`strong`,{children:`Until you verify a domain of your own, Resend delivers only to the email address you made your Resend account with.`}),` A test email to yourself works; a customer's confirmation, a buyer's receipt, a booking note to someone else does not arrive at all. Do this before anyone but you should get an email.`]}),(0,i.jsxs)(`ol`,{className:Vl,children:[(0,i.jsxs)(`li`,{children:[`In Resend open `,(0,i.jsx)(zl,{href:`https://resend.com/domains`,children:`Domains`}),`, click `,(0,i.jsx)(`strong`,{children:`Add domain`}),` `,`and type the domain you own — `,(0,i.jsx)(`strong`,{children:`yourbusiness.com`}),`, without www.`]}),(0,i.jsx)(`li`,{children:`Resend shows a few DNS records. Add each one where your domain is managed — the company you bought it from, or wherever its website is hosted — copying name and value exactly.`}),(0,i.jsxs)(`li`,{children:[`Back in Resend, click `,(0,i.jsx)(`strong`,{children:`Verify`}),`. It can take a few minutes to turn green; if it does not, one record was copied wrong.`]}),a?(0,i.jsxs)(`li`,{children:[`Fill in one more line in your `,(0,i.jsx)(`strong`,{children:`.env`}),` — an address at that domain, which is what your mail goes out as — and `,(0,i.jsx)(`strong`,{children:`start the app again`}),`.`]}):(0,i.jsxs)(`li`,{children:[`Add one more secret in AI Studio — an address at that domain, which is what your mail goes out as — and press `,(0,i.jsx)(`strong`,{children:`Apply`}),` again.`]})]}),(0,i.jsx)(`div`,{className:Hl,children:(0,i.jsx)(Uc,{name:`EMAIL_FROM`,hint:`an address at your verified domain, like hello@yourbusiness.com`})})]}),(0,i.jsx)(Ul,{onConfirm:e})]})}function ql(){return(0,i.jsx)(c.Navigate,{to:`/setup`,replace:!0})}function Jl(e){return e.kind===`subscription`?e.active?{label:`Subscription active`,tone:`good`}:{label:`Cancelled`,tone:`quiet`}:e.fullyRefunded?{label:`Refunded`,tone:`bad`}:(e.amountRefunded||0)>0?{label:`Partially refunded`,tone:`bad`}:e.paid?{label:`Paid`,tone:`good`}:{label:`Not paid`,tone:`quiet`}}function Yl(e,t){if(e==null)return`—`;try{return new Intl.NumberFormat(void 0,{style:`currency`,currency:(t||`usd`).toUpperCase()}).format(e)}catch{return`${e} ${(t||``).toUpperCase()}`.trim()}}var Xl=e=>e?{description:`Every Pay button on your pages works. Switch it off to pause all of it at once.`,chip:{state:`saved`,label:`On`}}:{description:`No Pay button shows and nothing can be bought. Your pages keep their settings.`,chip:{state:`off`,label:`Off`}},Zl=e=>e?new Date(e*1e3).toLocaleDateString(void 0,{day:`numeric`,month:`short`,year:`numeric`}):``;function Ql({label:e,tone:t}){return(0,i.jsx)(`span`,{className:`inline-flex items-center h-6 px-2.5 rounded-full border text-[11px] font-bold whitespace-nowrap shrink-0 ${t===`good`?`text-emerald-500 bg-emerald-500/10 border-emerald-500/20`:t===`bad`?`text-red-500 bg-red-500/10 border-red-500/20`:`text-foreground/50 bg-foreground/[0.04] border-[var(--panel-border)]`}`,children:e})}function $l(){let{user:e}=t.Qi(),{status:n,error:a,reread:o}=cl(),[s,c]=(0,r.useState)(!1),[l,u]=(0,r.useState)(!1),[d,f]=(0,r.useState)(null),[p,m]=(0,r.useState)(``),[h,g]=(0,r.useState)([]),[_,v]=(0,r.useState)([]),[y,b]=(0,r.useState)(!1),[x,S]=(0,r.useState)(``),[C,w]=(0,r.useState)(!1),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(``),k=nl(`payments`),[A,j]=(0,r.useState)(``),M=Xl(k.on),N=(0,r.useCallback)(async t=>{let n=e?await e.getIdToken():``,r=await fetch(t,{headers:n?{Authorization:`Bearer ${n}`}:void 0}),i=await r.json().catch(()=>({}));if(!r.ok||i?.success===!1)throw Error(i?.error||`The server could not answer.`);return i},[e]),P=()=>{c(!1),o().then(()=>u(!0))},F=(0,r.useCallback)((e,t)=>{let n=e.charges||[],r=e.subscriptions||[];g(e=>t?[...e,...n]:n),v(e=>t?[...e,...r]:r),w(!!(e.chargesHasMore||e.subscriptionsHasMore))},[]);(0,r.useEffect)(()=>{if(!n?.configured||!e)return;let t=!1;return N(`/api/payments/products`).then(e=>{t||f(e.products||[])}).catch(e=>{t||m(e.message)}),N(`/api/payments/orders`).then(e=>{t||(F(e,!1),b(!0))}).catch(e=>{t||(S(e.message),b(!0))}),()=>{t=!0}},[n?.configured,e,N,F]);let I=async()=>{E(!0);try{let e=new URLSearchParams,t=h[h.length-1],n=_[_.length-1];t&&e.set(`starting_after`,t.id),n&&e.set(`subscriptions_after`,n.id),F(await N(`/api/payments/orders?${e}`),!0)}catch(e){S(e.message)}E(!1)},L=e=>{navigator.clipboard?.writeText(e),O(e),setTimeout(()=>O(``),2e3)},R=[...h,..._].sort((e,t)=>(t.created||0)-(e.created||0)),z=(d||[]).flatMap(e=>e.prices),B=n?.mode===`live`?`https://dashboard.stripe.com/products`:`https://dashboard.stripe.com/test/products`,V=!!(n&&!n.configured);return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(we,{children:`Payments`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/payments`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col min-h-[600px]`,children:!n&&!a?(0,i.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,i.jsx)(t.ei,{className:`w-6 h-6 animate-spin text-accent`})}):V?(0,i.jsx)(Wl,{icon:t.xi,title:`Connect Stripe`,description:`This app is not taking payments yet.`,stepsDescription:`Three steps — about five minutes, with pretend money until you say otherwise.`,button:`Set up payments`,secret:`STRIPE_SECRET_KEY`,open:s,onOpen:()=>c(!0),confirmed:l,steps:(0,i.jsx)(Gl,{onConfirm:P}),children:(0,i.jsx)(t.st,{children:`Payments run through Stripe, and connecting it is one pasted key — no code, no terminal. Once it is in, this screen fills itself: what you sell, and every payment as it happens.`})}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[n?.mode===`live`&&(0,i.jsxs)(`div`,{className:`flex items-center gap-3 rounded-2xl border border-red-500/25 bg-red-500/[0.06] px-4 py-3`,children:[(0,i.jsx)(t.Er,{className:`w-4 h-4 text-red-500 shrink-0`}),(0,i.jsx)(`p`,{className:`text-[12.5px] font-semibold text-red-500 leading-snug`,children:`Live mode — real cards are being charged. Every payment on this screen is real money.`})]}),(0,i.jsx)(t.ut,{icon:t.Vr,title:`Take payments`,description:M.description,chip:M.chip,enabled:k.loading?null:k.on,onChange:async e=>j(await k.set(e)||``),children:A?(0,i.jsx)(t.st,{tone:`error`,children:A}):null}),(0,i.jsx)(t.at,{icon:t.Ur,title:`Connection`,description:`Which Stripe account this app is running on.`,defaultOpen:!n?.configured,actions:a?(0,i.jsx)(t.lt,{state:`error`,label:`Unreachable`}):(0,i.jsx)(t.lt,{state:`saved`,label:n?.mode===`live`?`Live mode connected`:`Test mode connected`}),children:a?(0,i.jsx)(t.st,{tone:`error`,children:a}):(0,i.jsx)(t.st,{children:n?.mode===`live`?`Connected with a live key. Payments made anywhere on your site are real money.`:`Test mode connected. Your Pay buttons work end to end, but only test cards are accepted and no real money moves. When you are ready for real payments, use Go live below.`})}),(0,i.jsx)(Al,{}),(0,i.jsx)(mc,{}),(0,i.jsx)(t.at,{icon:t.Ar,title:`In your Stripe account`,description:`The products and prices Stripe has right now — where price ids come from.`,defaultOpen:!1,children:p?(0,i.jsx)(t.st,{tone:`error`,children:p}):d===null?(0,i.jsx)(`div`,{className:`flex items-center justify-center py-6 text-foreground/40`,children:(0,i.jsx)(t.ei,{className:`w-5 h-5 animate-spin text-accent`})}):z.length===0?(0,i.jsxs)(t.st,{children:[`Nothing needs to exist here for one-off payments — a Pay button can name its own amount. Only a subscription needs a price made in Stripe first:`,` `,(0,i.jsx)(`a`,{href:B,target:`_blank`,rel:`noreferrer`,className:`text-accent font-bold hover:underline`,children:`create one in your Stripe dashboard`}),` `,`and it appears here with its id ready to copy.`]}):(0,i.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:z.map(e=>(0,i.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${t.X}`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate min-w-0 flex-1`,children:e.productName||`Unnamed product`}),(0,i.jsxs)(`span`,{className:`text-[12.5px] font-semibold text-foreground/60 whitespace-nowrap shrink-0`,children:[Yl(e.amount,e.currency),e.interval?` / ${e.interval}`:``]}),(0,i.jsx)(t.Q,{compact:!0,icon:D===e.id?t.Fi:t.Si,title:`Copy the price id for ${e.productName||`this price`}`,onClick:()=>L(e.id),children:D===e.id?`Copied`:`Copy price id`})]},e.id))})}),(0,i.jsx)(t.at,{icon:t.Br,title:`Payments received`,description:`Every charge and subscription, straight from Stripe.`,defaultOpen:!1,children:x?(0,i.jsx)(t.st,{tone:`error`,children:x}):y?R.length===0?(0,i.jsx)(t.st,{children:`Nothing yet. When someone pays, it lands here on its own — and refunds you make in Stripe show up here too, with nothing to sync.`}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[R.map(e=>{let n=Jl(e);return(0,i.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${t.X}`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.name||e.email||`Someone`}),(0,i.jsxs)(`span`,{className:`text-[11px] text-foreground/45 font-medium truncate`,children:[e.productName||e.description||(e.kind===`subscription`?`Subscription`:`One-off payment`),e.page?` — sold on ${e.page}`:``]})]}),(0,i.jsx)(`span`,{className:`max-sm:hidden text-[11.5px] font-medium text-foreground/45 whitespace-nowrap shrink-0`,children:Zl(e.created)}),(0,i.jsxs)(`span`,{className:`text-[12.5px] font-semibold text-foreground/70 whitespace-nowrap shrink-0`,children:[Yl(e.amount,e.currency),e.kind===`subscription`&&e.interval?` / ${e.interval}`:``]}),(0,i.jsx)(Ql,{label:n.label,tone:n.tone})]},e.id)}),C&&(0,i.jsx)(t.Q,{busy:T,onClick:I,className:`self-center mt-1`,children:`Show older payments`})]}):(0,i.jsx)(`div`,{className:`flex items-center justify-center py-6 text-foreground/40`,children:(0,i.jsx)(t.ei,{className:`w-5 h-5 animate-spin text-accent`})})})]})})]})]})}var eu=`w-[6.5rem] shrink-0`,tu=`w-9 h-9 rounded-[var(--btn-radius,0.75rem)] border border-[var(--panel-border)] flex items-center justify-center shrink-0 text-foreground/45 hover:text-red-500 hover:border-red-500/40 hover:bg-red-500/[0.06] active:scale-[0.98] transition-all cursor-pointer`,nu=`date-field h-9 w-[10.5rem] shrink-0 px-3 text-[13px] font-semibold bg-transparent border border-[var(--panel-border)] text-foreground focus:outline-none focus:border-accent transition-colors`,ru={from:`09:00`,to:`13:00`};function iu(e,t){return{upcoming:e.filter(e=>e.date>=t),past:e.filter(e=>e.date<t)}}function au({row:e,onChange:n,onRemove:r}){let a=e.windows.length===0,o=(t,r)=>n({...e,windows:e.windows.map((e,n)=>n===t?{...e,...r}:e)});return(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 py-2.5`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,i.jsx)(`input`,{type:`date`,value:e.date,"aria-label":`The date`,onChange:t=>n({...e,date:t.target.value}),className:nu,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`div`,{className:`w-[11rem] shrink-0`,children:(0,i.jsx)(t.sr,{ariaLabel:`${e.date} — how much of it`,value:a?`all`:`some`,options:[{value:`all`,label:`All day`},{value:`some`,label:`Only some hours`}],onChange:t=>n({...e,windows:t===`all`?[]:[ru]}),className:`console-select`,compact:!0,dense:!0,portal:!0,direction:`auto`})}),(0,i.jsx)(`button`,{type:`button`,title:`Remove ${e.date||`this date`}`,"aria-label":`Remove ${e.date||`this date`}`,onClick:r,className:`${tu} ml-auto`,children:(0,i.jsx)(t._r,{className:`w-3.5 h-3.5`})})]}),!a&&(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 sm:pl-[0.125rem]`,children:[e.windows.map((r,a)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`div`,{className:eu,children:(0,i.jsx)(t.sr,{ariaLabel:`${e.date} from${a?` (${a+1})`:``}`,value:r.from,options:t.Ot,onChange:e=>o(a,{from:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),(0,i.jsx)(`span`,{className:`w-3 text-center text-foreground/40 text-[13px] shrink-0 select-none`,children:`–`}),(0,i.jsx)(`div`,{className:eu,children:(0,i.jsx)(t.sr,{ariaLabel:`${e.date} to${a?` (${a+1})`:``}`,value:r.to,options:t.Tt,onChange:e=>o(a,{to:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),e.windows.length>1&&(0,i.jsx)(`button`,{type:`button`,title:`Remove these hours on ${e.date}`,"aria-label":`Remove ${e.date} hours ${a+1}`,onClick:()=>n({...e,windows:e.windows.filter((e,t)=>t!==a)}),className:tu,children:(0,i.jsx)(t._r,{className:`w-3.5 h-3.5`})})]},a)),e.windows.length<2&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>n({...e,windows:[...e.windows,{from:`14:00`,to:`18:00`}]}),className:`self-start h-6 px-1 text-[11.5px] font-semibold text-foreground/45 hover:text-accent transition-colors cursor-pointer`,children:`+ Add a second stretch`})]})]})}function ou({blocked:e,onChange:n,now:a}){let o=t.qn(a?a():new Date),[s,c]=(0,r.useState)(!1),{upcoming:l,past:u}=iu(e,o),d=s?[...u,...l]:l,f=(t,r)=>n(e.map(e=>e===t?r:e));return(0,i.jsx)(t.Z,{label:`Days away`,hint:`Dates this week's hours do not apply to — a holiday, a flight, an afternoon out. Nobody can book them, on any link on these hours.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-1`,children:[d.length===0?(0,i.jsx)(`p`,{className:`${t.$} py-3`,children:`No days blocked out. Add one for a holiday or a day off.`}):d.map((t,r)=>(0,i.jsx)(au,{row:t,onChange:e=>f(t,e),onRemove:()=>n(e.filter(e=>e!==t))},`${t.date}-${r}`)),(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 py-2.5`,children:[(0,i.jsx)(t.Q,{icon:t.Hr,compact:!0,title:`Add a day away`,onClick:()=>n([...e,{date:o,windows:[]}]),children:`Add a date`}),u.length>0&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>c(e=>!e),className:`h-6 px-1 text-[11.5px] font-semibold text-foreground/45 hover:text-accent transition-colors cursor-pointer`,children:s?`Hide past dates`:`Show ${u.length} past date${u.length===1?``:`s`}`})]})]})})}var su=e=>t.xt.find(t=>t.value===e)?.label||`Short text`;function cu({options:e,onChange:n}){return(0,i.jsx)(t.Z,{label:`Choices`,hint:`What people pick from.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.length===0&&(0,i.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug px-1`,children:`No choices yet — add the first one.`}),e.map((r,a)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`input`,{type:`text`,value:r,"aria-label":`Choice ${a+1}`,placeholder:`e.g. At my place`,onChange:t=>n(e.map((e,n)=>n===a?t.target.value:e)),className:t.et}),(0,i.jsx)(t.Q,{icon:t._r,tone:`danger`,compact:!0,title:`Remove choice ${a+1}`,onClick:()=>n(e.filter((e,t)=>t!==a)),children:`Remove`})]},a)),(0,i.jsx)(`div`,{children:(0,i.jsx)(t.Q,{icon:t.Hr,onClick:()=>n([...e,``]),children:`Add choice`})})]})})}function lu({question:e,index:n,count:a,siblings:o,fixed:s,onChange:c,onMove:l,onRemove:u}){let[d,f]=(0,r.useState)(!e.label.trim()),p=e.label.trim()||`A new question`;return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 sm:gap-2.5 pr-2.5 sm:pr-3.5`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:()=>f(e=>!e),"aria-expanded":d,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3.5 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:p}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(`span`,{className:`${t.$} max-sm:hidden`,children:s?`Always asked`:`${su(e.type)}${e.required?` · must be answered`:``}`}),(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${d?`rotate-180`:``}`})]})]}),!s&&(0,i.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-1.5 shrink-0`,children:[(0,i.jsx)(t.Q,{icon:t.Wi,compact:!0,disabled:n===0,title:`Move ${p} up`,onClick:()=>l(-1),children:`Up`}),(0,i.jsx)(t.Q,{icon:t.Ji,compact:!0,disabled:n===a-1,title:`Move ${p} down`,onClick:()=>l(1),children:`Down`}),(0,i.jsx)(`span`,{className:`max-sm:hidden w-px h-5 bg-[var(--panel-border)] mx-0.5`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${p}`,onClick:u,children:`Remove`})]})]}),d&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.ft,{label:`What are you asking?`,hint:s?`The words above the box. Every booking asks this one — you can only change how it is put.`:`The words above the box, as the person booking reads them.`,value:e.label,placeholder:s?`e.g. Who is coming?`:`e.g. What is your phone number?`,onChange:n=>c({...e,label:n,name:s?e.name:t.tn(e,n,o)})}),!s&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.ct,{label:`Kind of answer`,hint:`Sets the box they type into. The example below follows what you pick.`,value:e.type,options:t.xt,allowEmpty:!1,onChange:n=>c({...e,type:n,options:n===`select`?e.options:[],placeholder:t.$t(e,n)})}),(0,i.jsx)(t.mt,{label:`Must be answered`,hint:`On means they cannot book until it is filled in.`,hintWideOnly:!0,enabled:e.required,onChange:t=>c({...e,required:t})})]}),e.type===`select`&&(0,i.jsx)(cu,{options:e.options,onChange:t=>c({...e,options:t})}),t.en(e.type)&&(0,i.jsx)(t.ft,{label:`Example answer`,hint:e.type===`tel`?`Shown under the box — a phone box already starts with a dial code, so the example stands below it.`:`Faint grey words inside the empty box.`,value:e.placeholder,placeholder:t.bt[e.type]||`e.g. +1 555 0123`,onChange:t=>c({...e,placeholder:t})})]})]})}function uu({questions:e,onChange:n}){let r=e.filter(e=>t.vn(e.name)),a=e.filter(e=>!t.vn(e.name)),o=e=>n([...r,...e]);return(0,i.jsx)(t.Z,{label:`What does a booking ask for?`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-3.5`,children:[r.map(t=>(0,i.jsx)(lu,{question:t,index:0,count:1,siblings:e,fixed:!0,onChange:r=>n(e.map(e=>e.name===t.name?r:e)),onMove:()=>{},onRemove:()=>{}},t.name)),a.map((t,n)=>(0,i.jsx)(lu,{question:t,index:n,count:a.length,siblings:e,onChange:e=>o(a.map((t,r)=>r===n?e:t)),onMove:e=>{let t=n+e;if(t<0||t>=a.length)return;let r=[...a];[r[n],r[t]]=[r[t],r[n]],o(r)},onRemove:()=>o(a.filter((e,t)=>t!==n))},n)),(0,i.jsxs)(`div`,{className:`flex flex-col items-start sm:flex-row sm:items-center gap-3 rounded-2xl border border-dashed border-[var(--panel-border)] px-4 py-3.5`,children:[(0,i.jsx)(t.Q,{icon:t.Hr,title:`Add a question`,onClick:()=>o([...a,t.Vt()]),children:`Add a question`}),a.length===0&&(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:`Nothing else is asked — just a name and an email.`})]})]})})}var du=(e,t,n=72)=>e>=n&&e<=Math.max(n,t*.45);function fu(e,t=340){if(!e)return null;let n=()=>{let t=e.getBoundingClientRect?.(),n=typeof window<`u`&&window.innerHeight||0;t&&n&&du(t.top,n)||e.scrollIntoView?.({behavior:`smooth`,block:`start`})};return typeof setTimeout==`function`?setTimeout(n,t):(n(),null)}var pu=`__new_payment__`;function mu(){let[e,n]=(0,r.useState)([]);return(0,r.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(t.Ca,Nn),e=>{let t=[];e.forEach(e=>{e.id!==`_settings`&&t.push(Gn(e.id,e.data()))}),n(t.filter(e=>e.kind===`once`).sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)))},()=>n([]));return()=>e()},[]),e}function hu({service:e,what:n,path:r,screen:a,children:o}){return e.loading?null:e.configured?e.on?(0,i.jsx)(i.Fragment,{children:o}):null:(0,i.jsxs)(`div`,{className:`rounded-2xl border border-accent/25 bg-accent/[0.05] px-4 py-3.5 flex flex-wrap items-center justify-between gap-x-4 gap-y-2`,children:[(0,i.jsxs)(`span`,{className:`text-[13px] font-medium text-foreground/70`,children:[`You do not have `,n,` set up yet.`]}),(0,i.jsxs)(c.Link,{to:r,className:`inline-flex items-center gap-1 text-[12px] font-bold text-accent hover:underline whitespace-nowrap`,children:[`Set it up on the `,a,` screen`,(0,i.jsx)(t.Ki,{className:`w-3 h-3`})]})]})}function gu({value:e,products:n,meetingName:a,canCreate:o,onChange:s,onCreate:c}){let[l,u]=(0,r.useState)(!1),[d,f]=(0,r.useState)(``),[p,m]=(0,r.useState)(``),[h,g]=(0,r.useState)(!1),_=[...n.map(e=>({value:e.id,label:`${Zn(e)} — ${zn(e).map(e=>e.amount).filter(Boolean).join(` + `)||`no price yet`}`})),...o?[{value:pu,label:`+ A new one-time payment`}]:[]],v=n.find(t=>t.id===e),y=d.trim()&&Bn(d)===null?`Just a number, like 25.`:void 0;return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsx)(t.ct,{label:`Payment for this meeting`,hint:v?`Taken on the booking page before the time is confirmed. Its price and its link are on the Payments screen.`:o?`Optional. A one-time payment taken on the booking page before the time is confirmed.`:n.length?`Optional. One of the payments your admin set up, taken on the booking page before the time is confirmed.`:`Your admin has not set up a payment to charge for a meeting yet.`,value:l?pu:e,placeholder:`No payment`,options:_,onChange:e=>{if(e===`__new_payment__`){u(!0);return}u(!1),s(e)}}),l&&(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-3`,children:[(0,i.jsx)(t.ft,{label:`The price`,hint:`Just the number — 25 charges 25 in your Stripe account's currency. The payment is called ${a} and appears on the Payments screen too.`,value:d,onChange:e=>{f(e),p&&m(``)},placeholder:`25`,error:p||y}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(t.Q,{icon:t.Hr,busy:h,onClick:async()=>{if(Bn(d)===null){m(`Just a number for the price, like 25.`);return}m(``),g(!0);let e=await c(a,d.trim());if(g(!1),e){m(e);return}u(!1),f(``)},children:`Create it`}),(0,i.jsx)(t.Q,{onClick:()=>{u(!1),m(``),f(``)},children:`Never mind`})]})]})]})}function _u({link:e,onChange:n}){return(0,i.jsx)(t.Z,{label:`Emails about bookings`,hint:`Sent the moment a time is taken. Every booking is in your Inbox and on the calendar regardless.`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5`,children:[(0,i.jsx)(t.mt,{label:`Email me when someone books`,hint:`A note at your address — the sale alert, when they paid.`,hintWideOnly:!0,enabled:e.notifyOwner,onChange:e=>n({notifyOwner:e})}),(0,i.jsx)(t.mt,{label:`Email them a confirmation`,hint:`Their receipt when they pay. For a free booking, a note that the time is theirs — to people who book signed in.`,hintWideOnly:!0,enabled:e.confirmBooker,onChange:e=>n({confirmBooker:e})})]})})}var vu=e=>{let n={...t.A(t.I(),e),createdAt:Date.now()};return{...n,name:t.Rt(n),description:t.Lt(n)}};function yu({link:e,schedules:n,products:r,services:a,isAdmin:o=!0,onChange:s,onCreatePayment:c}){let l=n.find(t=>t.id===e.scheduleId),u=t=>s({...e,...t}),d=t.N(e,l),f=l?t.j(e,l):null,p=n=>{let r={...e,...n};return{...n,...e.name.trim()===t.Rt(e)?{name:t.Rt(r)}:{},...e.description.trim()===t.Lt(e)?{description:t.Lt(r)}:{}}};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.ct,{label:`Which hours is it booked in?`,hint:`Change the hours and every meeting booked in them changes with it — one holiday, entered once, closes them all.`,value:e.scheduleId,options:n.map(e=>({value:e.id,label:t.pn(e)})),allowEmpty:!1,onChange:t=>{let r=n.find(e=>e.id===t);if(!r)return;let i=!l||e.memberName.trim()===l.memberName.trim();u(p({scheduleId:r.id,memberId:r.memberId,...i?{memberName:r.memberName}:{}}))}}),(0,i.jsx)(t.ft,{label:`What is it called?`,hint:`Visitors read this on the booking page. It starts named after its length — call it whatever you like. Left blank it goes back to ${t.Rt(e)}.`,value:e.name,onChange:e=>u({name:e}),placeholder:t.Rt(e)}),(0,i.jsx)(t.dt,{label:`A line or two about it`,hint:`Visitors read it under the name — what it is for, what to bring, what happens after. Emptied, the booking page simply shows none.`,value:e.description,onChange:e=>u({description:e}),placeholder:`A first conversation about what you need and how I can help.`}),(0,i.jsx)(t.ft,{label:`The name visitors see`,value:e.memberName,onChange:e=>u(p({memberName:e})),placeholder:`Anna`}),(0,i.jsx)(t.ct,{label:`How long is one booking?`,value:String(e.slotMinutes),options:t.Mt,allowEmpty:!1,onChange:e=>u(p({slotMinutes:Number(e)}))}),(0,i.jsx)(t.ct,{label:`How far ahead can people book?`,value:String(e.horizonDays),options:t.kt,allowEmpty:!1,onChange:e=>u({horizonDays:Number(e)})}),(0,i.jsx)(t.ct,{label:`How much notice do you need?`,value:String(e.noticeHours),options:t.At,allowEmpty:!1,onChange:e=>u({noticeHours:Number(e)})}),(0,i.jsx)(uu,{questions:e.questions,onChange:e=>u({questions:e})}),(0,i.jsx)(hu,{service:a.payments,what:`Stripe`,path:`/payments`,screen:`Payments`,children:(0,i.jsx)(gu,{value:e.paymentId,products:r,meetingName:t.F(e),canCreate:o,onChange:e=>u({paymentId:e}),onCreate:async(e,t)=>{let n=await c(e,t);return n&&n.startsWith(`p_`)?(u({paymentId:n}),null):n||`The payment could not be made — make sure you are signed in as an admin and try again.`}})}),(0,i.jsx)(hu,{service:a.email,what:`emails`,path:`/email`,screen:`Email`,children:(0,i.jsx)(_u,{link:e,onChange:u})}),(0,i.jsx)(t.Z,{label:`Booking link`,hint:f&&!d&&e.enabled?`Send it to anyone. They see the free times in their own time zone, pick one and book — and pay first, when a payment is attached.`:`The link opens once the meeting is complete and turned on.`,children:(0,i.jsx)(nc,{title:t.F(e),path:t.Qt(e.id)})}),(0,i.jsx)(`div`,{className:`pt-1`,children:d?e.enabled?(0,i.jsxs)(`span`,{className:`text-[11.5px] font-semibold text-amber-500`,children:[`Turned on, but not bookable yet — `,d]}):(0,i.jsx)(`span`,{className:t.$,children:d}):e.enabled?(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Bookable — send the link, pick it on a page under Booking on this page, or add a Pick-a-time question to a form.`}):(0,i.jsx)(`span`,{className:t.$,children:`Complete — flip the switch at the top of the row to offer it.`})})]})}function bu({link:e,schedules:n,products:a,services:o,isAdmin:s=!0,open:c,fresh:l,error:u,onToggle:d,onChange:f,onRemove:p,onCreatePayment:m}){let h=n.find(t=>t.id===e.scheduleId),g=t.M(e,h),[_,v]=(0,r.useState)(!1),y=t.F(e),b=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!l)return;let e=fu(b.current);return()=>{e&&clearTimeout(e)}},[l]),(0,i.jsxs)(`div`,{ref:b,className:`scroll-mt-4 rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 sm:gap-2.5 pr-3`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:d,"aria-expanded":c,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:t.P(e,h)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:(0,i.jsx)(t.lt,{state:g.state,label:g.label})}),(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${c?`rotate-180`:``}`})]})]}),(0,i.jsx)(t.pt,{enabled:e.enabled,onChange:t=>f({...e,enabled:t}),label:`${y} — can be booked`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${y}`,onClick:()=>v(!0),children:`Remove`})]}),(0,i.jsx)(He,{isOpen:_,title:`Remove ${y}?`,message:`Its booking link stops working and it leaves every page and form it was picked on. The hours it was booked in stay, and so do the bookings already taken.`,confirmText:`Yes, remove`,cancelText:`Keep it`,onCancel:()=>v(!1),onConfirm:()=>{v(!1),p()}}),c&&(0,i.jsx)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:(0,i.jsx)(yu,{link:e,schedules:n,products:a,services:o,isAdmin:s,onChange:f,onCreatePayment:m})}),u&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-4 pb-3`,children:u})]})}function xu({isAdmin:e=!0}={}){let{user:n}=t.Qi(),{loading:a,docs:s}=t.b(),c=mu(),l={payments:dl(`payments`),email:dl(`email`)},[u,d]=(0,r.useState)({}),[f,p]=(0,r.useState)([]),[m,h]=(0,r.useState)(null),[g,_]=(0,r.useState)(null),[v,y]=(0,r.useState)({}),b=(0,r.useRef)(new Map),x=n?.uid||``,S=(0,r.useMemo)(()=>[...e?s.schedules:s.schedules.filter(e=>e.memberId===x)].sort((e,t)=>Number(t.memberId===x)-Number(e.memberId===x)),[s.schedules,e,x]),C=(0,r.useMemo)(()=>{let t=new Map(s.links.map(e=>[e.id,e]));for(let e of Object.values(u))t.set(e.id,e);for(let e of f)t.delete(e);return[...t.values()].filter(t=>e||t.memberId===x).sort((e,t)=>Number(t.memberId===x)-Number(e.memberId===x)||(e.createdAt||0)-(t.createdAt||0)||e.id.localeCompare(t.id))},[s.links,u,f,e,x]),w=e=>{let n=b.current.get(e.id);n&&clearTimeout(n),b.current.set(e.id,setTimeout(async()=>{b.current.delete(e.id);let n=await t.d(e);y(t=>{let r={...t};return n?r[e.id]=n:delete r[e.id],r})},600))},T=e=>{d(t=>({...t,[e.id]:e})),w(e)},E=()=>{let e=S.find(e=>e.memberId===x)||S[0];if(!e)return;let t=vu(e);d(e=>({...e,[t.id]:t})),h(t.id),_(t.id),w(t)},D=async e=>{let n=b.current.get(e);n&&(clearTimeout(n),b.current.delete(e)),d(t=>{let n={...t};return delete n[e],n}),p(t=>[...t,e]),m===e&&h(null);let r=await t.l(e);r&&(p(t=>t.filter(t=>t!==e)),y(t=>({...t,[e]:r})))},O=async(e,n)=>{let r={...Rn(`p_${Date.now().toString(36)}`),kind:`once`,items:[{name:e,amount:n}]};try{let{id:e,...n}=r;return await(0,o.setDoc)((0,o.doc)(t.Ca,Nn,e),n),e}catch(e){return console.error(`Could not make the payment`,e),null}};return(0,i.jsx)(t.at,{icon:t.ri,title:`Booking links`,description:`One per kind of meeting — pick the hours it is booked in, say how long it lasts and what it asks, and send the link.`,actions:!a&&S.length>0?({open:e})=>(0,i.jsx)(t.Q,{icon:t.Hr,compact:!0,title:`Add a booking link`,onClick:()=>{e(),E()},children:`Add a booking link`}):void 0,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:a?(0,i.jsx)(`p`,{className:t.$,children:`Loading your booking links…`}):S.length===0?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Add a schedule above first — a booking link is a meeting booked in somebody's hours, so there have to be hours to put it on.`}):C.length===0?(0,i.jsxs)(`p`,{className:`${t.$} px-1`,children:[`No booking link yet — press Add a booking link. It is what turns `,t.mn(S[0]),` into something people can book.`]}):C.map(t=>(0,i.jsx)(bu,{link:t,schedules:S,products:c,services:l,isAdmin:e,open:m===t.id,fresh:g===t.id,error:v[t.id],onToggle:()=>h(m===t.id?null:t.id),onChange:T,onRemove:()=>D(t.id),onCreatePayment:O},t.id))})})}var Su=(e,n=`host`)=>e.heldOnly?`Held time`:n===`booker`?e.scheduleName.trim()||`A meeting`:t.cn(e),Cu=(e,t=`host`)=>e.heldOnly?`Held with no booking behind it`:e.own?`Your own event`:t===`booker`?e.memberName.trim()?`With ${e.memberName.trim()}`:`Booked`:e.scheduleName||e.email||`Booked`,wu=(e,n=`host`)=>n===`booker`&&!e.heldOnly?t.Yt(e):Su(e,n),Tu=e=>!e.pending||e.cancelled||e.own||e.heldOnly?``:e.partySize>1?`${e.partyAccepted} of ${e.partySize}`:`Pending`;function Eu({value:e,onChange:n}){return(0,i.jsx)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:t.Et.map(r=>{let a=r.value===e;return(0,i.jsx)(`button`,{type:`button`,title:r.label,"aria-label":r.label,"aria-pressed":a,onClick:()=>n(r.value),className:`w-8 h-8 rounded-full transition-all cursor-pointer active:scale-95 flex items-center justify-center ${r.value?`border-2`:`border-2 border-dashed`} ${a?`scale-105`:`hover:scale-105`}`,style:{background:t.ln(r.value,a?55:30),borderColor:a?t.sn(r.value):t.ln(r.value,40)},children:a&&(0,i.jsx)(`span`,{className:`w-2 h-2 rounded-full`,style:{background:t.sn(r.value)}})},r.value||`theme`)})})}function Du({className:e=``}){return(0,i.jsx)(`span`,{className:`inline-flex items-center h-[18px] px-1.5 rounded-md shrink-0 border border-red-500/25 bg-red-500/10 text-[10px] font-bold uppercase tracking-[0.08em] text-red-500/90 ${e}`,children:`Cancelled`})}function Ou({label:e=`Pending`,className:t=``}){return(0,i.jsx)(`span`,{title:`Waiting to be accepted`,className:`inline-flex items-center h-[18px] px-1.5 rounded-md shrink-0 border border-amber-500/25 bg-amber-500/10 text-[10px] font-bold uppercase tracking-[0.08em] text-amber-600 dark:text-amber-400 ${t}`,children:e})}function ku({className:e=``}){return(0,i.jsx)(`span`,{title:`Held with nothing booked`,className:`inline-flex items-center h-[18px] px-1.5 rounded-md shrink-0 border border-[var(--panel-border)] bg-foreground/[0.04] text-[10px] font-bold uppercase tracking-[0.08em] text-foreground/45 ${e}`,children:`Held`})}function Au({booking:e,zone:n,chip:r,withMember:a=!1,side:o=`host`,onOpen:s,now:c}){let l=e.end<(c?c():new Date).toISOString(),u=e.cancelled,d=Tu(e),f=e.color;return(0,i.jsxs)(`button`,{type:`button`,onClick:s,"aria-label":`${t.dn(new Date(e.start),n)} — ${Su(e,o)}${u?` (cancelled)`:``}`,className:`group relative w-full text-left rounded-2xl border overflow-hidden flex items-stretch gap-2.5 p-2.5 transition-all cursor-pointer active:scale-[0.99] ${l&&!u?`opacity-60`:``} ${u||e.heldOnly?`border-dashed border-[var(--panel-border)]/60 bg-foreground/[0.02]`:``}`,style:u||e.heldOnly?void 0:{background:t.ln(f,7),borderColor:t.ln(f,26)},children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-1 rounded-full shrink-0 ${u||e.heldOnly?`bg-foreground/15`:``}`,style:u||e.heldOnly?void 0:{background:t.ln(f,85)}}),(0,i.jsx)(`span`,{"aria-hidden":!0,className:`absolute inset-0 bg-foreground/0 group-hover:bg-foreground/[0.04] transition-colors`}),(0,i.jsxs)(`span`,{className:`relative flex-1 min-w-0 flex flex-col gap-0.5 py-0.5`,children:[(0,i.jsxs)(`span`,{className:`flex items-baseline gap-2 min-w-0`,children:[(0,i.jsx)(`span`,{className:`text-[12.5px] font-bold tabular-nums shrink-0 ${u?`text-foreground/45 line-through`:`text-foreground`}`,children:t.dn(new Date(e.start),n)}),(0,i.jsx)(`span`,{className:`text-[12.5px] font-semibold truncate ${u?`text-foreground/45 line-through`:`text-foreground/80`}`,children:Su(e,o)})]}),(0,i.jsxs)(`span`,{className:`flex items-center justify-between gap-2 min-w-0`,children:[(0,i.jsx)(`span`,{className:`text-[11.5px] font-medium text-foreground/45 truncate`,children:a&&e.memberName?`${e.memberName} · ${Cu(e,o)}`:Cu(e,o)}),u?(0,i.jsx)(Du,{}):e.heldOnly?(0,i.jsx)(ku,{}):d?(0,i.jsx)(Ou,{label:d}):r&&(0,i.jsx)(t.lt,{state:r.state,label:r.label})]})]})]})}var ju=e=>{let t=e.replace(/_/g,` `).trim();return t.charAt(0).toUpperCase()+t.slice(1)};function Mu(e,t){let n=e.memberName.trim();if(e.partySize>1){let n=`${e.partyAccepted} of ${e.partySize} have accepted.`;return t?`${n} Yours is still to come.`:n}return t?`This is waiting for you to accept.`:n?`Waiting for ${n} to accept.`:`Waiting to be accepted.`}function Nu(e){let t=e.memberName.trim();return e.partySize>1?e.partyAccepted>0?`${e.partyAccepted} of ${e.partySize} have confirmed so far. You will hear once they all have.`:`Waiting to be confirmed. You will hear as soon as it is.`:t?`Waiting for ${t} to confirm. You will hear as soon as they do.`:`Waiting to be confirmed. You will hear as soon as it is.`}function Pu({open:e,onClose:n,children:a}){return(0,r.useEffect)(()=>{if(!e)return;let t=e=>{e.key===`Escape`&&n()};return window.addEventListener(`keydown`,t),()=>window.removeEventListener(`keydown`,t)},[e,n]),(0,i.jsx)(t.pr,{children:e&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:n,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/80 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(t.fr.div,{role:`dialog`,"aria-modal":`true`,initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`w-full max-w-[420px] max-h-[85vh] overflow-y-auto styled-scrollbars-mini p-5 sm:p-6 rounded-3xl glass-popover border border-[var(--panel-border)] shadow-2xl relative z-10 text-left`,children:a})]})})}function Fu({color:e,title:n,line:r,cancelled:a,onClose:o}){return(0,i.jsxs)(`div`,{className:`flex items-start gap-3 mb-4`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-1 self-stretch rounded-full shrink-0 ${a?`bg-foreground/15`:``}`,style:a?void 0:{background:t.ln(e,85)}}),(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,i.jsx)(`h3`,{className:`text-[17px] font-extrabold tracking-tight leading-tight break-words ${a?`text-foreground/50 line-through`:`text-foreground`}`,children:n}),a&&(0,i.jsx)(Du,{})]}),(0,i.jsx)(`p`,{className:`text-[12.5px] font-medium text-foreground/50 leading-snug mt-0.5`,children:r})]}),(0,i.jsx)(`button`,{type:`button`,onClick:o,"aria-label":`Close`,className:t.R,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]})}function Iu({label:e,children:t}){return(0,i.jsxs)(`div`,{className:`flex items-start justify-between gap-3 px-3.5 py-2.5`,children:[(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 shrink-0`,children:e}),(0,i.jsx)(`span`,{className:`text-[12.5px] font-semibold text-foreground/80 text-right break-words min-w-0`,children:t})]})}function Lu({booking:e,zone:n,chip:a,me:o=``,side:s=`host`,onClose:c,onColor:l,onAccept:u,onCancel:d,onDelete:f,onRelease:p}){let[m,h]=(0,r.useState)(!1),[g,_]=(0,r.useState)(!1),[v,y]=(0,r.useState)(``),[b,x]=(0,r.useState)(!1),[S,C]=(0,r.useState)(``),w=t.Hn(e,n),T=e.end<new Date().toISOString(),E=!e.own&&e.timeZone&&e.timeZone!==n?e.timeZone:``,D=Object.entries(e.answers).filter(([,e])=>e),O=s===`booker`,k=!e.heldOnly&&(D.length>0||!!E||!!a||!O&&!e.own&&(!!e.scheduleName||!!e.email||e.createdAt>0)),A=e.heldOnly,j=!A&&(e.own||e.cancelled||T),M=!O&&!!o&&e.memberId===o,N=Tu(e),P=!!N&&M&&!!u,F=A?`Free this held time`:e.own?`Delete this event`:e.cancelled?`Remove this cancelled booking`:T?`Remove this booking`:N&&M?`Decline this booking`:`Cancel this booking`,I=A?!!p:j&&!!f,L=!j&&!A,R=!!N&&M&&!j;return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(Pu,{open:!0,onClose:c,children:[(0,i.jsx)(Fu,{color:e.color,title:wu(e,s),line:`${w.day} · ${w.time}`,cancelled:e.cancelled,onClose:c}),e.cancelled&&(0,i.jsxs)(`div`,{className:`mb-4 px-3.5 py-2.5 rounded-2xl border border-[var(--panel-border)] bg-foreground/[0.03] flex flex-col gap-1.5`,children:[(0,i.jsxs)(`p`,{className:`text-[12.5px] font-medium text-foreground/70 leading-snug`,children:[Ru(e),` The time is free again — it stays here so you have the record.`]}),!!e.cancelReason&&(0,i.jsxs)(`p`,{className:`text-[12.5px] font-semibold text-foreground/80 leading-snug border-l-2 border-[var(--panel-border)] pl-2.5`,children:[`“`,e.cancelReason,`”`]})]}),!!N&&(0,i.jsxs)(`div`,{className:`mb-4 px-3.5 py-3 rounded-2xl border border-amber-500/25 bg-amber-500/[0.07] flex flex-col gap-2.5`,children:[(0,i.jsxs)(`div`,{className:`flex items-start gap-2.5`,children:[(0,i.jsx)(t.Ei,{className:`w-4 h-4 shrink-0 mt-[1px] text-amber-600 dark:text-amber-400`,"aria-hidden":!0}),(0,i.jsx)(`p`,{className:`text-[12.5px] font-semibold text-foreground/75 leading-snug flex-1 min-w-0`,children:O?Nu(e):Mu(e,M)}),e.partySize>1&&(0,i.jsx)(Ou,{label:N})]}),P&&!g&&(0,i.jsxs)(t.cr,{onClick:async()=>{x(!0),C(``);let e=await u();x(!1),e&&C(e)},isLoading:b,className:`py-2 px-4 text-[13px] font-bold rounded-xl self-start`,children:[(0,i.jsx)(t.Fi,{className:`w-3.5 h-3.5 shrink-0`,"aria-hidden":!0}),`Accept`]})]}),A&&(0,i.jsx)(`p`,{className:`mb-4 px-3.5 py-2.5 rounded-2xl border border-[var(--panel-border)] bg-foreground/[0.03] text-[12.5px] font-medium text-foreground/70 leading-snug`,children:`This hour is held with no booking behind it — a booking that was started and never finished. Nobody can take the time until it is freed, and there is nothing here to cancel.`}),k&&(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 bg-foreground/[0.015] divide-y divide-[var(--panel-border)]/40`,children:[!O&&!e.own&&e.scheduleName&&(0,i.jsx)(Iu,{label:`Meeting`,children:e.scheduleName}),!O&&e.email&&(0,i.jsx)(Iu,{label:`Email`,children:(0,i.jsx)(`a`,{href:`mailto:${e.email}`,className:`text-accent hover:underline break-all`,children:e.email})}),D.map(([e,n])=>(0,i.jsx)(Iu,{label:e===`note`?`Note`:ju(e),children:t.rr(n)?(0,i.jsx)(`span`,{className:`flex flex-col items-end gap-1 min-w-0`,children:t.nr(n).map(e=>(0,i.jsxs)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,title:t.tr(e),className:`inline-flex items-center gap-1.5 max-w-full min-w-0 text-accent hover:underline`,children:[(0,i.jsx)(t.Kr,{className:`w-3.5 h-3.5 shrink-0`}),(0,i.jsx)(`span`,{className:`truncate min-w-0`,children:t.tr(e)})]},e))}):n},e)),E&&(0,i.jsxs)(Iu,{label:O?`The time you booked in`:`Their time`,children:[t.dn(new Date(e.start),E),` — `,t.Kn(E)]}),a&&(0,i.jsx)(Iu,{label:`Payment`,children:(0,i.jsx)(t.lt,{state:a.state,label:a.label})}),!O&&!e.own&&e.createdAt>0&&(0,i.jsx)(Iu,{label:`Booked`,children:new Intl.DateTimeFormat(void 0,{dateStyle:`medium`}).format(new Date(e.createdAt))})]}),!e.cancelled&&!A&&!!l&&(0,i.jsxs)(`div`,{className:`mt-4 flex flex-col gap-2`,children:[(0,i.jsx)(`span`,{className:`text-[12.5px] sm:text-[13px] font-medium text-foreground/50 select-none ml-1`,children:`Colour`}),(0,i.jsx)(Eu,{value:e.color,onChange:async e=>{C(``);let t=await l(e);t&&C(t)}}),(0,i.jsx)(`p`,{className:`text-[11px] font-medium text-foreground/40 leading-snug ml-1 mt-0.5`,children:`Shown on the calendar and in the day beside it.`})]}),g&&(0,i.jsxs)(`div`,{className:`mt-4 flex flex-col gap-3 p-3.5 rounded-2xl border border-[var(--panel-border)] bg-foreground/[0.02]`,children:[(0,i.jsx)(t.dt,{label:R?`Why are you turning it down?`:O?`Why can you not make it?`:`Why are you cancelling?`,value:v,onChange:y,placeholder:O?`Something has come up — I would like to book another time.`:`Something has come up and I cannot make this time — do book another.`,hint:O?`${e.memberName.trim()||`Whoever you booked with`} will see this.`:`${e.name.trim()||`Whoever booked`} will see this on the meeting.`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,i.jsx)(t.cr,{variant:`secondary`,onClick:()=>{_(!1),C(``)},disabled:b,className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl`,children:`Keep it`}),(0,i.jsx)(t.cr,{onClick:async()=>{x(!0),C(``);let e=await d(v.trim());if(x(!1),e){C(e);return}_(!1),c()},isLoading:b,disabled:!v.trim(),className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl bg-red-500 hover:bg-red-600 border-none text-white shadow-lg hover:shadow-red-500/20 disabled:opacity-40 disabled:hover:bg-red-500 disabled:hover:shadow-none`,children:R?`Decline it`:`Cancel it`})]})]}),!g&&!L&&!I&&!O&&!A&&(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug mt-4 ml-1`,children:`Nothing left to do here — only an admin can take a booking off the calendar for good.`}),!!S&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 mt-3 ml-1`,children:S}),!g&&(0,i.jsxs)(`div`,{className:`mt-5 flex items-center gap-3 ${I||L?`justify-between`:`justify-end`}`,children:[(I||L)&&(0,i.jsx)(t.Q,{icon:I?t.Or:t.Ri,tone:`danger`,title:F,onClick:()=>I?h(!0):_(!0),children:A?`Free the time`:e.own?`Delete`:I?`Remove`:R?`Decline`:`Cancel booking`}),(0,i.jsx)(t.cr,{variant:`secondary`,onClick:c,className:`py-2 px-4 text-[13px] font-bold rounded-xl`,children:`Close`})]})]}),(0,i.jsx)(He,{isOpen:m,title:`${F}?`,message:A?`The hour goes back on offer. There is no booking behind it, so nothing else is lost.`:e.own?`It leaves your calendar and the time can be booked again.`:`It goes from the calendar for good, with everything it holds — in every diary it was booked into. This cannot be undone.`,confirmText:A?`Yes, free it`:e.own?`Yes, delete`:`Yes, remove`,cancelText:`Keep it`,isProcessing:b,onCancel:()=>h(!1),onConfirm:async()=>{x(!0);let e=await(A?p?.()??null:f?.()??null);x(!1),h(!1),e?C(e):c()}})]})}function Ru(e){let t=e.cancelledAt>0?` on ${new Intl.DateTimeFormat(void 0,{dateStyle:`medium`}).format(new Date(e.cancelledAt))}`:``,n=e.cancelledBy.trim();return e.cancelledSide===`booker`?`${n||`The person who booked`} cancelled this${t}.`:e.cancelledSide===`host`?`${n||`Your team`} cancelled this${t}.`:`This booking was cancelled${t}.`}var zu=(e,n,r,i)=>({title:``,time:e===i?t.Tn(r,n):`09:00`,minutes:`60`,color:``,note:``});function Bu({dateKey:e,dayLabel:n,zone:a,today:o,now:s,onClose:c,onAdd:l}){let[u,d]=(0,r.useState)(()=>zu(e,a,s?s():new Date,o)),[f,p]=(0,r.useState)(!1),[m,h]=(0,r.useState)(``),g=e=>d(t=>({...t,...e}));return(0,i.jsxs)(Pu,{open:!0,onClose:c,children:[(0,i.jsx)(Fu,{color:u.color,title:u.title.trim()||`Add an event`,line:`${n} · your time, ${t.Kn(a)}`,onClose:c}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3.5`,children:[(0,i.jsx)(t.ft,{label:`What is it?`,value:u.title,onChange:e=>g({title:e}),placeholder:`Lunch with Sam`,hint:`Leave it empty and the time simply shows as busy.`}),(0,i.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,i.jsx)(t.ct,{label:`Starts at`,value:u.time,onChange:e=>g({time:e}),options:t.jt,allowEmpty:!1}),(0,i.jsx)(t.ct,{label:`Lasts`,value:u.minutes,onChange:e=>g({minutes:e}),options:t.Dt,allowEmpty:!1})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsx)(`span`,{className:`${t.nt} ml-1`,children:`Colour`}),(0,i.jsx)(Eu,{value:u.color,onChange:e=>g({color:e})})]}),(0,i.jsx)(t.dt,{label:`Note`,value:u.note,onChange:e=>g({note:e}),placeholder:`Anything to remember`})]}),(0,i.jsx)(`p`,{className:`text-[11.5px] font-medium text-foreground/40 leading-snug mt-3 ml-1`,children:`Nobody can book this time once it is here.`}),!!m&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 mt-3 ml-1`,children:m}),(0,i.jsxs)(`div`,{className:`mt-5 flex items-center gap-3`,children:[(0,i.jsx)(t.cr,{variant:`secondary`,onClick:c,disabled:f,className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl`,children:`Cancel`}),(0,i.jsx)(t.cr,{onClick:async()=>{p(!0),h(``);let n=t.Qn(e,u.time,a),r=new Date(n.getTime()+Number(u.minutes)*6e4),i=await l({title:u.title.trim(),start:n.toISOString(),end:r.toISOString(),color:u.color,note:u.note.trim()});p(!1),i?h(i):c()},isLoading:f,className:`flex-1 py-2.5 text-[13px] font-bold rounded-xl`,children:`Add it`})]})]})}var Vu=(e,t)=>new Intl.DateTimeFormat(t,{timeZone:`UTC`,weekday:`short`,day:`numeric`,month:`long`}).format(new Date(`${e}T00:00:00Z`)),Hu=[`M`,`T`,`W`,`T`,`F`,`S`,`S`],Uu=e=>e.slice(0,7),Wu=(e,n,r)=>t.dn(e,n,r).replace(/[\s\u00a0\u202f]+/g,``).toLowerCase();function Gu(e,t=3){return e.length<=t?{shown:e,extra:0}:{shown:e.slice(0,t-1),extra:e.length-(t-1)}}var Ku=(e,t,n=`host`)=>n===`booker`?wu(e,n):t&&e.memberName?`${Su(e)} · ${e.memberName}`:Su(e);function qu(e,n){let r=new Map;for(let i of e){let e=t.Zn(new Date(i.start),n).dateKey,a=r.get(e)||[];a.push(i),r.set(e,a)}for(let e of r.values())e.sort((e,t)=>e.start.localeCompare(t.start));return r}function Ju(e,t,n=!0){return!n||!e.paymentId&&!e.paymentSession?null:e.paymentSession?t===void 0?{state:`saving`,label:`Checking payment`}:t?{state:`saved`,label:`Paid`}:{state:`off`,label:`Awaiting payment`}:{state:`off`,label:`Not paid`}}var Yu=`h-8 px-3 rounded-xl border border-[var(--panel-border)]/60 inline-flex items-center gap-1.5 text-[12.5px] font-semibold text-foreground/60 hover:text-foreground hover:border-accent/40 hover:bg-foreground/5 active:scale-[0.98] transition-all cursor-pointer`;function Xu({bookings:e,zone:n,paid:a,openBookingId:o,onOpened:s,withMember:c=!1,me:l=``,side:u=`host`,onAccept:d,onCancel:f,onDelete:p,canDelete:m,onColor:h,onRelease:g,onAdd:_,now:v}){let y=t.Zn(v?v():new Date,n).dateKey,b=(0,r.useMemo)(()=>qu(e,n),[e,n]),[x,S]=(0,r.useState)(Uu(y)),[C,w]=(0,r.useState)(y),[T,E]=(0,r.useState)(null),[D,O]=(0,r.useState)(!1),k=(0,r.useRef)(``);(0,r.useEffect)(()=>{if(!o){k.current=``;return}if(k.current===o)return;let r=e.find(e=>e.id===o);if(!r)return;k.current=o;let i=t.Zn(new Date(r.start),n).dateKey;S(Uu(i)),w(i),E(r.id),s?.()},[o,e,n,s]);let A=t.U(x),j=b.get(C)||[],M=(v?v():new Date).toISOString(),N=Vu(C),P=T?e.find(e=>e.id===T):void 0,{ref:F,moreBelow:I}=t.W(j.length,C);return(0,i.jsxs)(`div`,{className:`flex flex-col md:flex-row gap-3 md:gap-4 w-full md:items-stretch`,children:[(0,i.jsxs)(`div`,{className:`${t.B} w-full md:flex-1 min-w-0`,children:[(0,i.jsxs)(`div`,{className:t.V,children:[(0,i.jsx)(`h4`,{className:`text-[14px] font-bold text-foreground tracking-tight truncate`,children:t.wn(x)}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 shrink-0`,children:[(0,i.jsx)(`button`,{type:`button`,onClick:()=>{S(Uu(y)),w(y)},className:Yu,children:`Today`}),(0,i.jsx)(`button`,{type:`button`,"aria-label":`Previous month`,onClick:()=>S(e=>t.Rn(e,-1)),className:t.R,children:(0,i.jsx)(t.Ni,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{type:`button`,"aria-label":`Next month`,onClick:()=>S(e=>t.Rn(e,1)),className:t.R,children:(0,i.jsx)(t.Mi,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`p-2 sm:p-3`,children:(0,i.jsxs)(`div`,{className:`grid grid-cols-7 gap-1`,role:`grid`,"aria-label":t.wn(x),children:[Hu.map((e,t)=>(0,i.jsx)(`div`,{className:`text-center text-[10.5px] font-bold uppercase tracking-wider text-foreground/35 pb-1`,children:e},t)),A.map((e,r)=>{if(!e)return(0,i.jsx)(`div`,{"aria-hidden":!0},`blank-${r}`);let a=b.get(e)||[],{shown:o,extra:s}=Gu(a),l=e===C,d=e===y;return(0,i.jsxs)(`button`,{type:`button`,role:`gridcell`,"aria-label":`${e}${a.length?`, ${a.length} booked`:``}`,"aria-selected":l,onClick:()=>w(e),className:`relative flex flex-col items-center sm:items-stretch justify-center sm:justify-start h-10 sm:h-[86px] rounded-xl sm:p-1 text-left transition-all cursor-pointer border ${l?`border-accent/70 bg-accent/[0.08] shadow-sm shadow-accent/10`:a.length?`border-transparent hover:bg-foreground/[0.05] hover:border-[var(--panel-border)]/60`:`border-transparent hover:bg-foreground/[0.03]`} ${d&&!l?`ring-1 ring-inset ring-accent/45`:``}`,children:[(0,i.jsx)(`span`,{className:`text-[13px] tabular-nums leading-none sm:px-1 sm:pt-0.5 sm:pb-1 ${l||d?`font-bold text-accent`:a.length?`font-bold text-foreground`:`font-semibold text-foreground/35`}`,children:Number(e.slice(8,10))}),(0,i.jsxs)(`span`,{"aria-hidden":!0,className:`max-sm:hidden sm:flex flex-col gap-[2px] w-full min-w-0`,children:[o.map(e=>(0,i.jsxs)(`span`,{className:`flex items-center gap-1 min-w-0 rounded-md pr-1 py-[2px] leading-[1.2] overflow-hidden ${e.end<M&&!e.cancelled?`opacity-50`:``} ${e.cancelled?`bg-foreground/[0.04] line-through`:``}`,style:e.cancelled?void 0:{background:t.ln(e.color,12)},children:[(0,i.jsx)(`span`,{className:`w-[3px] self-stretch rounded-full shrink-0 ${e.cancelled?`bg-foreground/15`:``}`,style:e.cancelled?void 0:{background:t.ln(e.color,85)}}),(0,i.jsx)(`span`,{className:`text-[9.5px] font-bold tabular-nums shrink-0 ${e.cancelled?`text-foreground/40`:`text-foreground/85`}`,children:Wu(new Date(e.start),n)}),(0,i.jsx)(`span`,{className:`text-[9.5px] font-medium truncate ${e.cancelled?`text-foreground/40`:`text-foreground/60`}`,children:Ku(e,c,u)})]},e.id)),s>0&&(0,i.jsxs)(`span`,{className:`px-1 text-[9.5px] font-bold text-foreground/45 leading-[1.2]`,children:[`+`,s,` more`]})]})]},e)})]})})]}),(0,i.jsx)(`div`,{className:`w-full md:w-[320px] shrink-0 md:relative md:min-h-[360px]`,children:(0,i.jsxs)(`div`,{className:`${t.B} flex flex-col md:absolute md:inset-0`,children:[(0,i.jsxs)(`div`,{className:t.V,children:[(0,i.jsx)(`p`,{className:`text-[13px] font-bold text-foreground tracking-tight truncate`,children:N}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[j.length>0&&(0,i.jsxs)(`span`,{className:`text-[11.5px] font-semibold text-foreground/40 tabular-nums max-sm:hidden`,children:[j.length,` `,j.length===1?`event`:`events`]}),_&&(0,i.jsxs)(`button`,{type:`button`,onClick:()=>O(!0),title:`Add an event on ${N}`,className:Yu,children:[(0,i.jsx)(t.Hr,{className:`w-3.5 h-3.5 shrink-0`}),`Add`]})]})]}),(0,i.jsxs)(`div`,{className:`relative flex-1 min-h-0`,children:[(0,i.jsx)(`div`,{ref:F,className:`p-3 h-full overflow-y-auto styled-scrollbars-mini flex flex-col gap-2`,children:j.length===0?(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center text-center gap-2 py-8 px-2`,children:[(0,i.jsx)(t.zi,{className:`w-5 h-5 text-foreground/25`,"aria-hidden":!0}),(0,i.jsx)(`p`,{className:`text-[12.5px] font-medium text-foreground/45 leading-relaxed`,children:`Nothing on this day yet.`})]}):j.map(e=>(0,i.jsx)(Au,{booking:e,zone:n,now:v,chip:Ju(e,a?.[e.paymentSession],!!a),withMember:c,side:u,onOpen:()=>E(e.id)},e.id))}),I&&(0,i.jsx)(t.H,{})]})]})}),P&&(0,i.jsx)(Lu,{booking:P,zone:n,chip:Ju(P,a?.[P.paymentSession],!!a),onClose:()=>E(null),me:l,side:u,onColor:h?e=>h(P.id,e):void 0,onAccept:d?()=>d(P):void 0,onCancel:e=>f(P,e),onDelete:p&&(!m||m(P))?()=>p(P):void 0,onRelease:g?()=>g(P):void 0}),D&&_&&(0,i.jsx)(Bu,{dateKey:C,dayLabel:N,zone:n,today:y,now:v,onClose:()=>O(!1),onAdd:_})]})}var Zu=`team`,Qu=e=>`m:${e}`,$u=`__nobody__`;function ed(e,n,r){return[{value:`me`,label:`My calendar`},{value:Zu,label:`My team's calendar`},...e.filter(e=>e.id!==r).map(e=>({value:Qu(e.id),label:t.h(e)||e.email,disabled:!n.has(e.id)}))]}var td=e=>e.startsWith(`m:`)?e.slice(2):``;function nd(e){let[t,n]=(0,r.useState)({});return(0,r.useEffect)(()=>{let r=e.filter(e=>e.paymentSession&&t[e.paymentSession]===void 0);if(!r.length)return;let i=!1;return Promise.all(r.map(async e=>[e.paymentSession,(await K(e.paymentSession)).paid])).then(e=>{i||n(t=>({...t,...Object.fromEntries(e)}))}),()=>{i=!0}},[e,t]),t}function rd(e,n,r,i=``){if(!e.email)return Promise.resolve();let a=t.Hn(e,e.timeZone||r);return Qr(n,t.ht,e.id,{when:`${a.day}, ${a.time}`,memberName:e.memberName,scheduleName:e.scheduleName,reason:i.trim()}).then(()=>{}).catch(()=>{})}function id(e,t,n){let r=e=>[...new Set(e.map(e=>String(e||``).trim()))].filter(e=>e&&e!==n),i=r([e.memberId,...t.map(e=>e.memberId),...e.copyIds.map(e=>e.split(`__`)[0])]);return{members:i,bookers:r([e.uid,...t.map(e=>e.uid)]).filter(e=>e!==`guest`).filter(e=>!i.includes(e))}}async function ad(e,n,r,i){if(e.own||e.heldOnly)return;let a={title:`Meeting removed`,body:`${t.Yt(e)} · ${t.un(new Date(e.start),i)}`};await rd(e,`booking_cancelled`,i,`The meeting was removed from the calendar.`);let{members:o,bookers:s}=id(e,n,r);await T(o,{...a,link:`/schedule`}),await T(s,{...a,link:`/my-bookings`})}function od({isAdmin:e}){let{user:n}=t.Qi(),a=n?.uid||``,o=t.an(),[s,l]=(0,c.useSearchParams)(),u=s.get(`open`)||s.get(`booking`)||``,{schedules:d}=t.S(),{members:f}=t.C(),p=(0,r.useMemo)(()=>new Set(d.map(e=>e.memberId)),[d]),m=(0,r.useMemo)(()=>ed(f,p,a),[f,p,a]),[h,g]=(0,r.useState)(null);(0,r.useEffect)(()=>{u&&e&&g(e=>e??`team`)},[u,e]);let _=h??`me`,v=new Set(m.filter(e=>!e.disabled).map(e=>e.value)).has(_)?_:`me`,y=td(v),{loading:b,bookings:x,error:S}=t.g({members:v===`team`?void 0:[y||a||$u],includePast:!0}),C=nd(x),w=t.x((0,r.useMemo)(()=>(v===`team`?f.map(e=>e.id):[y||a]).filter(Boolean),[v,f,y,a]),(0,r.useMemo)(()=>{let e=new Date;return new Date(Date.UTC(e.getUTCFullYear(),e.getUTCMonth()-1,1))},[])),[T,E]=(0,r.useState)(()=>Date.now());(0,r.useEffect)(()=>{let e=setInterval(()=>E(Date.now()),6e4);return()=>clearInterval(e)},[]);let D=(0,r.useMemo)(()=>t.O(x),[x]),O=(0,r.useMemo)(()=>{let e=x.map(e=>{let t=D.get(e.id);return t?{...e,...t}:e}),n=e=>{let n=f.find(t=>t.id===e);return d.find(t=>t.memberId===e)?.memberName||(n?t.h(n):``)},r=t.k(w,x,T).map(e=>t.D(e,n(e.memberId)));return r.length?[...e,...r]:e},[x,D,w,T,f,d]),k=y||a,A=f.find(e=>e.id===k),j=d.find(e=>e.memberId===k)?.memberName||(A?t.h(A):``)||(k===a?String(n?.displayName||``):``);return O.length===0?null:(0,i.jsx)(t.at,{icon:t.zi,title:`Calendar`,description:v===`team`?`Every booking made with your team, and the events they put on their own days — in your time, ${t.Kn(o)}.`:y?`${j||`Their`} calendar, read as they read it — in your time, ${t.Kn(o)}.`:`Every booking made with you, under every schedule of yours — in your time, ${t.Kn(o)}.`,actions:e&&m.length>2?(0,i.jsx)(t.sr,{ariaLabel:`Whose calendar`,value:v,options:m,onChange:g,className:`console-select`,compact:!0,dense:!0,portal:!0,direction:`auto`}):void 0,children:b?(0,i.jsx)(`p`,{className:t.$,children:`Loading the calendar…`}):S?(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:S}):(0,i.jsx)(Xu,{bookings:O,zone:o,paid:C,openBookingId:u||void 0,onOpened:u?()=>l(e=>(e.delete(`open`),e.delete(`booking`),e),{replace:!0}):void 0,withMember:v===Zu,me:a,onAccept:async e=>{let n=await t.n(e.id);return n||rd(e,`booking_confirmed`,o),n},onCancel:async(e,r)=>{let i=await t.i(e.id,{ids:e.copyIds,reason:r,side:`host`,by:e.memberId===a?j||String(n?.displayName||``):e.memberName,byUid:a});return i||rd(e,`booking_cancelled`,o,r),i},onDelete:async e=>(await ad(e,x,a,o),t.o(e.id,e.copyIds)),canDelete:t=>e||t.own&&t.memberId===a,onRelease:e=>t.s(e.memberId,e.start),onColor:t.p,onAdd:v===`team`?void 0:e=>t.r({...e,memberId:k,memberName:j,timeZone:o})})})}function sd(e,t){if(!e.enabled)return{state:`off`,label:`Off`};if(di(e,t))return{state:`error`,label:`Unfinished`};let n=e.schedules.length;return{state:`saved`,label:n===1?`1 meeting`:`${n} meetings`}}var cd=e=>{let t=e.schedules.length;return`${fi(e)} — ${t===0?`nothing on it yet`:t===1?`1 meeting`:`${t} meetings`}`};function ld({page:e,schedules:n,onChange:r}){return n.length?(0,i.jsx)(t.Z,{label:`Meetings on this page`,hint:`They appear in the order you tick them. A meeting switched off above is kept off the page too.`,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-1.5`,children:n.map(n=>{let a=e.schedules.includes(n.id);return(0,i.jsxs)(`button`,{type:`button`,role:`checkbox`,"aria-checked":a,onClick:()=>r(ui(e,n.id)),className:`flex items-center gap-3 px-3 py-2.5 rounded-xl border text-left transition-all cursor-pointer active:scale-[0.995] ${a?`border-accent/45 bg-accent/[0.07]`:`border-[var(--panel-border)]/70 hover:border-accent/30 hover:bg-foreground/[0.03]`}`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-[5px] border flex items-center justify-center shrink-0 transition-all ${a?`border-accent bg-accent`:`border-foreground/25`}`,children:a&&(0,i.jsx)(`span`,{className:`w-[7px] h-[7px] rounded-[2px] bg-[var(--button-fg,#fff)]`})}),(0,i.jsx)(`span`,{className:`flex-1 min-w-0 text-[13px] font-semibold text-foreground/80 truncate`,children:t.Fn(n)})]},n.id)})})}):(0,i.jsx)(t.Z,{label:`Meetings on this page`,children:(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Make a schedule above first — a page offers the meetings you have set up.`})})}function ud({page:e,taken:n,onRename:a}){let[o,s]=(0,r.useState)(e.id),c=ri(o),l=!!c&&c!==e.id&&n.includes(c);return(0,i.jsx)(t.ft,{label:`Its address`,prefix:`/meet/`,value:o,onChange:s,onBlur:()=>{if(!c||l||c===e.id){s(e.id);return}a(c)},placeholder:`anna-bell`,error:l?`Another page already has that address.`:void 0,hint:`Change it and the old link stops working, so change it before you send it out.`})}function dd({page:e,schedules:n,taken:a,open:o,fresh:s,error:c,onToggle:l,onChange:u,onRename:d,onRemove:f}){let[p,m]=(0,r.useState)(!1),h=sd(e,n),g=fi(e),_=di(e,n),v=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!s)return;let e=fu(v.current);return()=>{e&&clearTimeout(e)}},[s]),(0,i.jsxs)(`div`,{ref:v,className:`scroll-mt-4 rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 sm:gap-2.5 pr-3`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:l,"aria-expanded":o,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:cd(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:(0,i.jsx)(t.lt,{state:h.state,label:h.label})}),(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${o?`rotate-180`:``}`})]})]}),(0,i.jsx)(t.pt,{enabled:e.enabled,onChange:t=>u({...e,enabled:t}),label:`${g} — page is live`}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${g}`,onClick:()=>m(!0),children:`Remove`})]}),(0,i.jsx)(He,{isOpen:p,title:`Remove ${g}?`,message:`Its link stops working. The meetings on it are untouched and keep their own links, and bookings already taken are kept.`,confirmText:`Yes, remove`,cancelText:`Keep it`,onCancel:()=>m(!1),onConfirm:()=>{m(!1),f()}}),o&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,i.jsx)(t.ft,{label:`Name on the page`,value:e.title,onChange:t=>u({...e,title:t}),placeholder:`Anna Bell`,hint:`Usually the name of whoever the page is for.`}),(0,i.jsx)(ct,{label:`Photo`,hint:`Shown at the top of the page. A square picture of the person works best.`,value:e.photo,onChange:t=>u({...e,photo:t})}),(0,i.jsx)(t.dt,{label:`About this page`,value:e.intro,onChange:t=>u({...e,intro:t}),rows:3,placeholder:`I help small studios get their bookkeeping straight. Pick a time below and tell me what you need.`}),(0,i.jsx)(ld,{page:e,schedules:n,onChange:u}),(0,i.jsx)(ud,{page:e,taken:a,onRename:d}),_?(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-amber-500 px-1`,children:_}):(0,i.jsx)(nc,{title:g,path:ai(e.id)})]}),c&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-4 pb-3`,children:c})]})}function fd({schedules:e,myName:n,isAdmin:a=!0,meId:o=``}){let{loading:s,pages:c}=pi(),[l,u]=(0,r.useState)({}),[d,f]=(0,r.useState)([]),[p,m]=(0,r.useState)(null),[h,g]=(0,r.useState)(null),[_,v]=(0,r.useState)({}),y=(0,r.useRef)(new Map),b=new Map(c.map(e=>[e.id,e]));for(let e of Object.values(l))b.set(e.id,e);for(let e of d)b.delete(e);let x=[...b.values()].sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)||e.id.localeCompare(t.id)),S=x.map(e=>e.id),C=si(x,o,a),w=a?e:e.filter(e=>e.memberId===o),T=e=>{let t=y.current.get(e.id);t&&clearTimeout(t),y.current.set(e.id,setTimeout(async()=>{y.current.delete(e.id);let t=await mi(e);v(n=>{let r={...n};return t?r[e.id]=t:delete r[e.id],r})},600))},E=e=>{u(t=>({...t,[e.id]:e})),T(e)},D=()=>{let e=ni(ii(n||`my page`,S),n,o);u(t=>({...t,[e.id]:e})),f(t=>t.filter(t=>t!==e.id)),m(e.id),g(e.id),T(e)},O=async(e,t)=>{let n=y.current.get(e.id);n&&(clearTimeout(n),y.current.delete(e.id));let r={...e,id:t};u(n=>{let i={...n};return delete i[e.id],i[t]=r,i}),f(n=>[...n.filter(e=>e!==t),e.id]),p===e.id&&m(t);let i=await gi(e.id,r);i&&v(e=>({...e,[t]:i}))},k=async e=>{let t=y.current.get(e);t&&(clearTimeout(t),y.current.delete(e)),u(t=>{let n={...t};return delete n[e],n}),f(t=>[...t,e]),p===e&&m(null);let n=await hi(e);n&&(f(t=>t.filter(t=>t!==e)),v(t=>({...t,[e]:n})))};return(0,i.jsx)(t.at,{icon:t.ri,title:`Your booking pages`,description:`One link with a photo, a line about you and every meeting you offer.`,actions:({open:e})=>(0,i.jsx)(t.Q,{icon:t.Hr,compact:!0,title:`Create a page`,onClick:()=>{e(),D()},children:`Create a page`}),children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:s?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Loading pages…`}):C.length===0?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`No pages yet. Create one to hand out a single link — a visitor sees your photo, what you do and every meeting you offer, and picks the one they want.`}):C.map(e=>(0,i.jsx)(dd,{page:e,schedules:w,taken:S,open:p===e.id,fresh:h===e.id,error:_[e.id],onToggle:()=>m(t=>t===e.id?null:e.id),onChange:E,onRename:t=>O(e,t),onRemove:()=>k(e.id)},e.id))})})}var pd={from:`09:00`,to:`17:00`},md=e=>t.gn(e)?{state:`saved`,label:`Ready`}:{state:`off`,label:`In progress`},hd=e=>({...t.Ht(t.L(),e.id,t.h(e),t.an()),name:`Working hours`,enabled:!0,createdAt:Date.now()}),gd=`w-[6.5rem] shrink-0`,_d=`w-9 h-9 rounded-[var(--btn-radius,0.75rem)] border border-[var(--panel-border)] flex items-center justify-center shrink-0 text-foreground/45 hover:text-red-500 hover:border-red-500/40 hover:bg-red-500/[0.06] active:scale-[0.98] transition-all cursor-pointer`;function vd({day:e,windows:n,onChange:r}){let a=n.length>0,o=(e,t)=>r(n.map((n,r)=>r===e?{...n,...t}:n));return(0,i.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-[8.5rem_minmax(0,1fr)] items-start gap-x-4 gap-y-2 py-2.5`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 h-9`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-medium ${a?`text-foreground/80`:`text-foreground/40`}`,children:t.wt[e]}),(0,i.jsx)(t.pt,{enabled:a,onChange:e=>r(e?[pd]:[]),label:`${t.wt[e]} — bookable`})]}),a&&(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 min-w-0`,children:[n.map((a,s)=>(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`div`,{className:gd,children:(0,i.jsx)(t.sr,{ariaLabel:`${t.wt[e]} from${s?` (${s+1})`:``}`,value:a.from,options:t.Ot,onChange:e=>o(s,{from:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),(0,i.jsx)(`span`,{className:`w-3 text-center text-foreground/40 text-[13px] shrink-0 select-none`,children:`–`}),(0,i.jsx)(`div`,{className:gd,children:(0,i.jsx)(t.sr,{ariaLabel:`${t.wt[e]} to${s?` (${s+1})`:``}`,value:a.to,options:t.Tt,onChange:e=>o(s,{to:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),n.length>1&&(0,i.jsx)(`button`,{type:`button`,title:`Remove these hours on ${t.wt[e]}`,"aria-label":`Remove ${t.wt[e]} hours ${s+1}`,onClick:()=>r(n.filter((e,t)=>t!==s)),className:_d,children:(0,i.jsx)(t._r,{className:`w-3.5 h-3.5`})})]},s)),n.length<2&&(0,i.jsx)(`button`,{type:`button`,onClick:()=>r([...n,{from:`18:00`,to:`20:00`}]),className:`self-start h-6 px-1 text-[11.5px] font-semibold text-foreground/45 hover:text-accent transition-colors cursor-pointer`,children:`+ Add a second stretch`})]})]})}function yd({schedule:e,onChange:n}){let r=t=>n({...e,...t}),a=t.hn(e);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.ft,{label:`What are these hours called?`,hint:`Only you and your team read this — it is how a booking link names the hours it is booked in. Working hours, Evenings, Studio days.`,value:e.name,onChange:e=>r({name:e}),placeholder:`Working hours`}),(0,i.jsx)(t.Y,{value:e.timeZone,onChange:e=>r({timeZone:e})}),(0,i.jsx)(t.Z,{label:`When`,hint:`The hours on each day, in this person's own time zone. Add a second stretch for a break in the middle. A time booked in any of their hours is taken here too.`,children:(0,i.jsx)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-1`,children:t.Ct.map(t=>(0,i.jsx)(vd,{day:t,windows:e.days[t]||[],onChange:n=>r({days:{...e.days,[t]:n}})},t))})}),(0,i.jsx)(ou,{blocked:e.blocked,onChange:e=>r({blocked:e})}),(0,i.jsx)(`div`,{className:`pt-1`,children:a?(0,i.jsxs)(`span`,{className:`text-[11.5px] font-semibold text-amber-500`,children:[`Not usable yet — `,a]}):(0,i.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Ready — add a booking link below to let people book these hours, or ask for a page built on them.`})})]})}function bd({schedule:e,open:n,stale:a,fresh:o,error:s,onToggle:c,onChange:l,onRemove:u}){let d=md(e),[f,p]=(0,r.useState)(!1),m=t.mn(e),h=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!o)return;let e=fu(h.current);return()=>{e&&clearTimeout(e)}},[o]),(0,i.jsxs)(`div`,{ref:h,className:`scroll-mt-4 rounded-2xl border border-[var(--panel-border)] ${a?`opacity-60`:``}`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 sm:gap-2.5 pr-3`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:c,"aria-expanded":n,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:t._n(e)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[a?(0,i.jsx)(`span`,{className:`${t.$} max-sm:hidden`,children:`No longer on the team`}):(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:(0,i.jsx)(t.lt,{state:d.state,label:d.label})}),(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${n?`rotate-180`:``}`})]})]}),(0,i.jsx)(t.Q,{icon:t.Or,tone:`danger`,compact:!0,title:`Remove ${m}`,onClick:()=>p(!0),children:`Remove`})]}),(0,i.jsx)(He,{isOpen:f,title:`Remove ${m}?`,message:a?`They are no longer on the team, so nobody can book them. Bookings already taken are kept.`:`Every booking link booked in these hours stops working, and they leave every page and form they were picked on. Bookings already taken are kept.`,confirmText:`Yes, remove`,cancelText:`Keep it`,onCancel:()=>p(!1),onConfirm:()=>{p(!1),u()}}),n&&(0,i.jsx)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:(0,i.jsx)(yd,{schedule:e,onChange:l})}),s&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-4 pb-3`,children:s})]})}function xd({name:e,schedules:n,stale:a,open:o,onToggle:s,onAdd:c,openScheduleId:l,freshId:u,errors:d,onToggleSchedule:f,onChange:p,onRemove:m}){let h=a?`No longer on the team`:n.length===0?`No schedules yet`:`${n.length} schedule${n.length===1?``:`s`}`,g=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!o)return;let e=fu(g.current);return()=>{e&&clearTimeout(e)}},[o]),(0,i.jsxs)(`div`,{ref:g,className:`scroll-mt-4 rounded-2xl border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`button`,{type:`button`,onClick:s,"aria-expanded":o,className:`w-full flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:e}),(0,i.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,i.jsx)(`span`,{className:`${t.$} max-sm:hidden`,children:h}),(0,i.jsx)(t.Pi,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${o?`rotate-180`:``}`})]})]}),o&&(0,i.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-3`,children:[n.map(e=>(0,i.jsx)(bd,{schedule:e,stale:a,fresh:u===e.id,open:l===e.id,error:d[e.id],onToggle:()=>f(e.id),onChange:p,onRemove:()=>m(e.id)},e.id)),a?n.length===0&&(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`No schedule yet for `,e,`.`]}):(0,i.jsxs)(`div`,{className:`flex flex-col items-start sm:flex-row sm:items-center gap-3 rounded-2xl border border-dashed border-[var(--panel-border)] px-4 py-3`,children:[(0,i.jsx)(t.Q,{icon:t.Hr,title:`Add a schedule for ${e}`,onClick:c,children:`Add a schedule`}),n.length===0&&(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`No schedule yet for `,e,`.`]})]})]})]})}var Sd=e=>({id:e.uid,name:String(e.displayName||``),email:String(e.email||``),role:`admin`});function Cd({isAdmin:e=!0}={}){let{user:n}=t.Qi(),{loading:a,members:o}=t.C(),{loading:s,docs:l}=t.b(),u=l.schedules,[d,f]=(0,r.useState)({}),[p,m]=(0,r.useState)([]),[h,g]=(0,r.useState)(null),[_,v]=(0,r.useState)(null),[y,b]=(0,r.useState)(null),[x,S]=(0,r.useState)({}),C=(0,r.useRef)(new Map),w=(0,r.useMemo)(()=>{let e=new Map(u.map(e=>[e.id,e]));for(let t of Object.values(d))e.set(t.id,t);for(let t of p)e.delete(t);return[...e.values()].sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)||e.id.localeCompare(t.id))},[u,d,p]),T=e=>{let n=C.current.get(e.id);n&&clearTimeout(n),C.current.set(e.id,setTimeout(async()=>{C.current.delete(e.id);let n=await t.f(e);S(t=>{let r={...t};return n?r[e.id]=n:delete r[e.id],r})},600))},E=e=>{f(t=>({...t,[e.id]:e})),T(e)},D=(0,r.useMemo)(()=>n?o.find(e=>e.id===n.uid)||Sd(n):null,[n,o]),O=(0,r.useMemo)(()=>D&&!o.some(e=>e.id===D.id)?[D,...o]:o,[D,o]),k=(0,r.useRef)(!1),[A,j]=(0,r.useState)(``),M=(0,r.useMemo)(()=>l.schedules.filter(t=>l.legacyIds.includes(t.id)&&(e||t.memberId===D?.id)),[l.schedules,l.legacyIds,e,D]);(0,r.useEffect)(()=>{k.current||M.length===0||(k.current=!0,t.m(M).then(e=>{e&&j(e)}))},[M]);let N=e=>{let t=hd(e);f(e=>({...e,[t.id]:t})),g(t.id),v(t.id),D&&e.id!==D.id&&b(e.id),T(t)},P=()=>{D&&N(D)},F=async e=>{let n=C.current.get(e);n&&(clearTimeout(n),C.current.delete(e)),f(t=>{let n={...t};return delete n[e],n}),m(t=>[...t,e]),h===e&&g(null);let r=await t.u(e);r&&(m(t=>t.filter(t=>t!==e)),S(t=>({...t,[e]:r})))},I=a||s,L=new Set(O.map(e=>e.id)),R=D?w.filter(e=>e.memberId===D.id):[],z=(0,r.useMemo)(()=>{if(!D)return[];let e=new Map;for(let t of w){if(t.memberId===D.id)continue;let n=e.get(t.memberId);n?n.push(t):e.set(t.memberId,[t])}let n=[];for(let r of O)r.id!==D.id&&(n.push({id:r.id,name:t.h(r)||r.email,stale:!1,schedules:e.get(r.id)||[]}),e.delete(r.id));for(let[t,r]of e)n.push({id:t,name:r[0].memberName.trim()||`Someone no longer on the team`,stale:!0,schedules:r});return n},[w,O,D]);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.at,{icon:t.Bi,title:`Your schedules`,description:`When you are free — a name, a time zone, the week's hours and the days you are away. The base for anything booked on them.`,actions:I?void 0:({open:e})=>(0,i.jsx)(t.Q,{icon:t.Hr,compact:!0,title:`Add a schedule`,onClick:()=>{e(),P()},children:`Add a schedule`}),children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[I?(0,i.jsx)(`p`,{className:t.$,children:`Loading your schedules…`}):R.length===0?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`No hours of your own yet — press Add a schedule. Everything booked in them shares one availability, so a time taken once is gone from all of it.`}):R.map(e=>(0,i.jsx)(bd,{schedule:e,stale:!L.has(e.memberId),fresh:_===e.id,open:h===e.id,error:x[e.id],onToggle:()=>g(h===e.id?null:e.id),onChange:E,onRemove:()=>F(e.id)},e.id)),!!A&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:A})]})}),e&&(0,i.jsx)(t.at,{icon:t.xr,title:`Your team's schedules`,description:`When everyone else is free — one folded row per person; open a name to add their hours or see what they keep.`,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-3`,children:I?(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:`Loading your team's schedules…`}):z.length===0?(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug px-1`,children:[`Nobody else is marked Internal or Admin yet. Add them on the`,` `,(0,i.jsx)(c.Link,{to:`/users`,className:`text-accent font-bold hover:underline`,children:`Users screen`}),` and a folded row for them appears here.`]}):z.map(e=>(0,i.jsx)(xd,{name:e.name,schedules:e.schedules,stale:e.stale,open:y===e.id,onToggle:()=>{let t=y!==e.id;b(t?e.id:null),t&&e.schedules.length&&g(e.schedules[0].id)},onAdd:()=>{let t=O.find(t=>t.id===e.id);t&&N(t)},openScheduleId:h,freshId:_,errors:x,onToggleSchedule:e=>g(h===e?null:e),onChange:E,onRemove:F},e.id))})})]})}function wd(){let{user:e,userRole:n}=t.Qi(),r=n===`admin`,{schedules:a}=t._(),o=e&&(e.displayName||e.email?.split(`@`)[0])||``;return t.ca(n)?(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(we,{children:`Schedule`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/schedule`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col min-h-[600px]`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsx)(`div`,{className:`flex flex-col gap-1.5 px-1`,children:(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/60 leading-relaxed`,children:r?`When you and your team are free, and everything built on it. A schedule is a week of hours in one person’s own time zone; a booking link turns those hours into a meeting people can book, with an address to send. The same hours are what a page you ask for is built on.`:`When you are free, and what people can book in it. Your schedule is your week of hours; a booking link turns it into a meeting, with an address of its own to send — they pick a free time and it lands on your calendar. A booking page gathers your meetings under one address to hand out.`})}),(0,i.jsx)(od,{isAdmin:r}),(0,i.jsx)(Cd,{isAdmin:r}),(0,i.jsx)(xu,{isAdmin:r}),(0,i.jsx)(fd,{schedules:a,myName:o,isAdmin:r,meId:e?.uid||``})]})})]})]}):(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:(0,i.jsx)(Tn,{})})}function Td(){let{user:e}=t.Qi(),n=t.an(),{loading:a,bookings:o,error:s}=t.v(e?.uid||``,e?.email||``),{docs:c}=t.b(),l=(0,r.useMemo)(()=>t.w(c),[c]),u=(0,r.useMemo)(()=>t.T(o,l),[o,l]);return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(we,{children:`My bookings`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/my-bookings`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col min-h-[600px]`,children:(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/60 leading-relaxed px-1`,children:[`Every meeting booked with your email address — including any you booked before you had an account. Shown in your time, `,t.Kn(n),`.`]}),a?(0,i.jsx)(`p`,{className:`${t.$} px-1`,children:`Loading your bookings…`}):s?(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:s}):u.length===0?(0,i.jsx)(t.at,{icon:t.Bi,title:`Nothing booked yet`,description:`Meetings you book appear here.`,children:(0,i.jsxs)(`p`,{className:`${t.$} px-1`,children:[`When you book a time through one of `,e?.displayName?`their`:`our`,` booking links, it lands here — and stays here afterwards, so you always have the record.`]})}):(0,i.jsx)(t.at,{icon:t.Bi,title:`Your calendar`,description:`Press a day to see what is on it. Everything you have booked is here, including the meetings that have been and the ones called off.`,children:(0,i.jsx)(Xu,{bookings:u,zone:n,side:`booker`,onCancel:async(r,i)=>{let a=await t.i(r.id,{ids:r.copyIds,reason:i,side:`booker`,by:r.name.trim()||String(e?.displayName||``)});if(!a){let e=t.Hn(r,n);Zr(`heads_up`,{title:`Booking cancelled`,summary:`${r.name.trim()||`Someone`} cancelled ${t.Yt(r)} — ${e.day}, ${e.time}`,details:{Who:r.name.trim(),Email:r.email,When:`${e.day}, ${e.time}`,Reason:i}}).catch(()=>{})}return a}})}),!a&&!s&&u.length>0&&(0,i.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug px-1 flex items-start gap-1.5`,children:[(0,i.jsx)(t.Cr,{className:`w-3.5 h-3.5 shrink-0 mt-[1px]`,"aria-hidden":!0}),(0,i.jsx)(`span`,{children:`Cancelling gives the time back straight away. To MOVE a meeting, cancel it and book another — or reply to its confirmation email.`})]})]})})]})]})}var Ed=(0,r.lazy)(()=>Promise.resolve().then(()=>require(`./PhoneInputField-CkAv_5Lw.cjs`)).then(e=>e.n)),Dd=`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,Od=`text-[12px] font-semibold text-red-500 mt-1 ml-1`,kd=`flex w-full text-[15px] text-foreground px-4 py-3 transition-all duration-300 placeholder:text-foreground/40 focus:outline-none focus:border-accent glow-focus glass-panel resize-none`;function Ad({children:e}){return(0,i.jsx)(`div`,{className:`flex flex-col w-full min-w-0`,children:e})}function jd({question:e,value:n,error:a,onChange:o}){let s=e.label.trim(),c=e.required?`${s} *`:s;return e.type===`textarea`?(0,i.jsxs)(Ad,{children:[(0,i.jsx)(`label`,{className:Dd,htmlFor:`q_${e.name}`,children:c}),(0,i.jsx)(`textarea`,{id:`q_${e.name}`,rows:3,value:n,placeholder:e.placeholder,onChange:e=>o(e.target.value),className:`${kd} rounded-xl min-h-[90px]`}),a&&(0,i.jsx)(`p`,{className:Od,children:a})]}):e.type===`checkbox`?(0,i.jsxs)(Ad,{children:[(0,i.jsxs)(`label`,{className:`flex items-center gap-3 w-full cursor-pointer group py-1.5`,children:[(0,i.jsxs)(`span`,{className:`relative flex items-center justify-center w-5 h-5 rounded border border-foreground/20 bg-background/50 group-hover:border-accent transition-colors shrink-0`,children:[(0,i.jsx)(`input`,{type:`checkbox`,checked:n===`Yes`,onChange:e=>o(e.target.checked?`Yes`:``),className:`absolute opacity-0 w-full h-full cursor-pointer`}),n===`Yes`&&(0,i.jsx)(`span`,{className:`w-2.5 h-2.5 bg-accent rounded-sm shrink-0`})]}),(0,i.jsx)(`span`,{className:`text-[14px] font-medium text-foreground/80 leading-snug group-hover:text-foreground transition-colors`,children:c})]}),a&&(0,i.jsx)(`p`,{className:Od,children:a})]}):e.type===`select`?(0,i.jsxs)(Ad,{children:[(0,i.jsx)(t.sr,{label:c,direction:`auto`,value:n,options:[{value:``,label:(0,i.jsx)(`span`,{className:`text-foreground/40`,children:e.placeholder||`Choose one…`})},...e.options.filter(Boolean).map(e=>({value:e,label:e}))],onChange:o}),a&&(0,i.jsx)(`p`,{className:Od,children:a})]}):e.type===`tel`?(0,i.jsxs)(Ad,{children:[(0,i.jsx)(r.Suspense,{fallback:(0,i.jsx)(`div`,{className:`h-12 w-full glass-panel animate-pulse rounded-xl`}),children:(0,i.jsx)(Ed,{field:{label:c,required:!1,placeholder:e.placeholder},value:n,onChange:o})}),a&&(0,i.jsx)(`p`,{className:Od,children:a})]}):e.type===`file`?(0,i.jsx)(Ad,{children:(0,i.jsx)(t.$n,{field:{label:c,placeholder:e.placeholder},value:n,error:a,onChange:e=>o(e(n))})}):e.type===`date`?(0,i.jsxs)(Ad,{children:[(0,i.jsx)(`label`,{className:Dd,htmlFor:`q_${e.name}`,children:c}),(0,i.jsxs)(`div`,{className:`relative flex items-center lift-focus`,children:[(0,i.jsx)(`input`,{id:`q_${e.name}`,type:`date`,value:n,onChange:e=>o(e.target.value),className:`date-field block h-12 w-full text-[15px] pl-4 pr-11 py-2 transition-all duration-300 focus:outline-none focus:border-accent glow-focus glass-panel ${n?`text-foreground`:`text-foreground/40`}`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(t.Li,{className:`w-4 h-4 text-foreground/50 absolute right-4 pointer-events-none`,"aria-hidden":!0})]}),a&&(0,i.jsx)(`p`,{className:Od,children:a})]}):(0,i.jsx)(Ad,{children:(0,i.jsx)(t.lr,{label:c,type:e.type,value:n,error:a,placeholder:e.placeholder,onChange:e=>o(e.target.value)})})}function Md({questions:e,answers:n,errors:r,onChange:a}){return(0,i.jsx)(i.Fragment,{children:t.It(e).map(e=>(0,i.jsx)(jd,{question:e,value:n[e.name]||``,error:r[e.name],onChange:t=>a(e.name,t)},e.name))})}var Nd=/^[^\s@,;]+@[^\s@,;.]+(\.[^\s@,;.]+)*\.[a-z]{2,}$/i;function Pd(e){if(!e||e.kind!==`once`)return null;let t=zn(e),n=t.reduce((e,t)=>e+(Bn(t.amount)||0),0),r=e.name.trim()||t.map(e=>e.name.trim()).filter(Boolean).join(` and `)||Zn(e);return n>0?{amount:n,name:r}:null}var Fd=(e,t=`usd`)=>{try{return new Intl.NumberFormat(void 0,{style:`currency`,currency:t.toUpperCase()}).format(e)}catch{return`${e} ${t.toUpperCase()}`}};function Id(e){let[n,i]=(0,r.useState)({id:``,product:null});return(0,r.useEffect)(()=>{if(!e)return;let n=!1;return(0,o.getDoc)((0,o.doc)(t.Ca,Nn,e)).then(t=>{n||i({id:e,product:t.exists()?Gn(t.id,t.data()):null})}).catch(()=>{n||i({id:e,product:null})}),()=>{n=!0}},[e]),e?n.id===e?{loading:!1,product:n.product}:{loading:!0,product:null}:{loading:!1,product:null}}function Ld({icon:e,accent:t,children:n}){return(0,i.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 h-7 px-3 rounded-full border text-[12.5px] font-semibold whitespace-nowrap ${t?`border-accent/40 bg-accent/10 text-accent`:`border-[var(--panel-border)]/70 text-foreground/65`}`,children:[e&&(0,i.jsx)(e,{className:`w-3.5 h-3.5 text-accent shrink-0`,"aria-hidden":!0}),n]})}function Rd({children:e,wide:n,form:r}){return(0,i.jsx)(`main`,{className:`flex-1 w-full mx-auto px-4 py-8 md:py-12 z-10 flex flex-col justify-center transition-[max-width] duration-500 ease-out ${n?`max-w-4xl`:r?`max-w-2xl`:`max-w-xl`}`,children:(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},transition:{duration:.4},className:`w-full rounded-3xl glass-panel border border-[var(--panel-border)] p-5 sm:p-8 md:p-10 shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:e})})}function zd({children:e}){return(0,i.jsx)(`h1`,{ref:Ce([e]),className:`text-2xl sm:text-3xl font-extrabold tracking-tight text-gradient leading-tight whitespace-nowrap data-[fold]:whitespace-normal data-[fold]:text-balance`,children:e})}function Bd({icon:e,title:n,children:r}){return(0,i.jsxs)(`div`,{className:`flex flex-col items-center text-center py-8 gap-4`,children:[(0,i.jsx)(`div`,{className:`w-14 h-14 ${t.K}`,children:(0,i.jsx)(e,{className:`w-6 h-6`})}),(0,i.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold text-foreground tracking-tight`,children:n}),r&&(0,i.jsx)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed max-w-md`,children:r}),(0,i.jsx)(c.Link,{to:`/`,className:`text-[13px] font-bold text-accent hover:underline mt-2`,children:`Back to the site`})]})}function Vd({sessionId:e,schedule:n}){let[a,o]=(0,r.useState)(null);if((0,r.useEffect)(()=>{let t=!1;return K(e).then(e=>{t||o(e)}),()=>{t=!0}},[e]),!a)return(0,i.jsx)(Bd,{icon:t.ei,title:`Confirming your payment…`,children:`One moment — checking with the payment provider.`});let s=a.metadata?.when||``;return a.paid?(0,i.jsx)(Bd,{icon:t.Vi,title:`Paid — your time is held`,children:(0,i.jsxs)(`p`,{children:[s?`${s} — `:``,t.In(n),`. Held for you while it is confirmed.`,a.customerEmail?` A receipt is on its way to ${a.customerEmail}.`:``]})}):(0,i.jsx)(Bd,{icon:t.Ti,title:`Not confirmed yet`,children:(0,i.jsx)(`p`,{children:a.error||`The payment provider has not confirmed this payment yet. Your time is held; if a receipt arrives by email, the booking is yours.`})})}function Hd(){let{id:e=``}=(0,c.useParams)(),[n]=(0,c.useSearchParams)(),{activeConfig:a}=t.Da(),{loading:o,schedule:s}=t.y(e),{loading:l,product:u}=Id(s?.paymentId||``),d=Pd(u),f=X(),[p,m]=(0,r.useState)(()=>t.an()),[h]=(0,r.useState)(()=>new Date),g=t.x(s?[s.memberId]:[],h),_=(0,r.useMemo)(()=>s&&t.Wt(s)?[s]:[],[s]),[v,y]=(0,r.useState)(null),[b,x]=(0,r.useState)(()=>t.Sa.currentUser?.displayName||``),[S,C]=(0,r.useState)(()=>t.Sa.currentUser?.email||``),[w,T]=(0,r.useState)({}),[E,D]=(0,r.useState)({}),[O,k]=(0,r.useState)(!1),[A,j]=(0,r.useState)(``),[M,N]=(0,r.useState)(``),[P,F]=(0,r.useState)(``),I=n.get(`session_id`)||``,L=n.get(`cancelled`)===`1`;if(o)return(0,i.jsx)(Rd,{children:(0,i.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-16 text-foreground/50`,children:[(0,i.jsx)(t.ei,{className:`w-4 h-4 animate-spin text-accent`}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium`,children:`Loading…`})]})});if(!s)return(0,i.jsx)(Rd,{children:(0,i.jsx)(Bd,{icon:t.Ri,title:`This booking link is no longer open`,children:`It may have been taken down. Ask whoever sent it for a new one.`})});if(I)return(0,i.jsx)(Rd,{children:(0,i.jsx)(Vd,{sessionId:I,schedule:s})});if(M)return(0,i.jsx)(Rd,{children:(0,i.jsx)(Bd,{icon:t.Ti,title:`Your time is held`,children:(0,i.jsxs)(`p`,{children:[M,` — held for you while `,s.memberName.trim()||`the person you booked with`,` confirms it.`,P?` We have sent the details to ${P}, and will write again the moment it is confirmed.`:``]})})});if(!t.Wt(s))return(0,i.jsx)(Rd,{children:(0,i.jsx)(Bd,{icon:t.Ri,title:t.In(s),children:`This is not taking bookings at the moment.`})});let z=!!s.paymentId&&!l&&(!d||!f.loading&&!f.configured),B=async()=>{if(!v||O)return;let e={...t.qt(s.questions,w)};if(b.trim()||(e._name=`Your name, please.`),Nd.test(S.trim())||(e._email=`That does not look like an email address — check for a typo, e.g. jane@example.com`),D(e),Object.keys(e).length)return;k(!0),j(``);let n=t.nn(v,s.memberName,p),r=await t.a(v);if(r){j(r),y(null),k(!1);return}let i=null;if(d){let e=await G({amount:d.amount,productName:`${t.In(s)} — ${n}`,metadata:{bookingId:t.zn(v.memberId,v.start),scheduleId:s.id,page:t.Qt(s.id),when:n,emailReceipt:s.confirmBooker?`yes`:`no`,notifyOwner:s.notifyOwner?`yes`:`no`},successPath:t.Qt(s.id),cancelPath:`${t.Qt(s.id)}?cancelled=1`});if(typeof e==`string`){await t.c(v),j(e),k(!1);return}i=e}let a=t.zn(v.memberId,v.start),o=await t.E(v,{memberName:s.memberName,scheduleId:s.id,scheduleName:t.Mn(s),paymentId:s.paymentId,paymentSession:i?.sessionId||``,timeZone:p,name:b.trim(),email:S.trim(),answers:t.Gt(s.questions,w),formId:t.gt,entryId:``});if(o){await t.c(v),j(o),k(!1);return}if(i){R.goTo(i.url);return}if(s.notifyOwner&&Zr(`heads_up`,{title:`New booking`,summary:`${b.trim()} booked ${t.In(s)} — ${n}`,details:{Name:b.trim(),Email:S.trim(),When:n,...t.Kt(s.questions,w)}}).catch(()=>{}),s.confirmBooker&&t.Sa.currentUser){let e=S.trim();Qr(`booking_requested`,`mem_bookings`,a,{when:n,memberName:s.memberName,scheduleName:t.In(s),details:{When:n,With:s.memberName,What:t.In(s)}}).then(t=>{t||F(e)}).catch(()=>{})}N(n),k(!1)},V=!z&&!v,H=!z&&!!v,U=t.Ft(s.questions,`name`),W=t.Ft(s.questions,`email`);return(0,i.jsxs)(Rd,{wide:V,form:H,children:[L&&(0,i.jsx)(`p`,{className:`mb-5 px-4 py-3 rounded-xl bg-amber-500/10 border border-amber-500/20 text-[13px] font-medium text-foreground/80`,children:`Nothing was charged. Pick a time again to book.`}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 mb-5 sm:mb-6`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3.5 min-w-0`,children:[(0,i.jsx)(`div`,{className:`w-11 h-11 ${t.K}`,children:(0,i.jsx)(t.Bi,{className:`w-5 h-5`})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[a?.appName&&(0,i.jsx)(`span`,{className:`text-[10.5px] font-bold uppercase tracking-[0.18em] text-foreground/40 truncate`,children:a.appName}),(0,i.jsx)(zd,{children:t.In(s)})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[!s.memberName.trim()&&(0,i.jsx)(Ld,{icon:t.Cr,children:`with your host`}),(0,i.jsx)(Ld,{icon:t.Ti,children:t.Bn(s.slotMinutes)}),d&&(0,i.jsx)(Ld,{accent:!0,children:Fd(d.amount)})]}),t.jn(s)&&(0,i.jsx)(`p`,{className:`text-[13.5px] sm:text-[14px] text-foreground/60 font-medium leading-relaxed max-w-2xl whitespace-pre-line`,children:t.jn(s)})]}),(0,i.jsx)(`div`,{className:`h-px bg-[var(--panel-border)]/60 mb-5 sm:mb-6`}),z?(0,i.jsx)(`p`,{className:`text-[14px] font-medium text-foreground/60`,children:`This booking cannot be paid for right now — please try again later.`}):v?(0,i.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,i.jsx)(t.G,{slot:v,timeZone:p,onChange:()=>y(null)}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsx)(t.lr,{label:U.label,value:b,onChange:e=>x(e.target.value),error:E._name,placeholder:U.placeholder}),(0,i.jsx)(t.lr,{label:W.label,type:`email`,value:S,onChange:e=>C(e.target.value),error:E._email,placeholder:W.placeholder}),(0,i.jsx)(Md,{questions:s.questions,answers:w,errors:E,onChange:(e,t)=>{T(n=>({...n,[e]:t})),D(t=>t[e]?{...t,[e]:``}:t)}})]}),A&&(0,i.jsx)(`p`,{role:`alert`,className:`text-[13px] font-semibold text-red-500`,children:A}),(0,i.jsx)(`div`,{className:`h-px bg-[var(--panel-border)]/60`}),(0,i.jsx)(t.J,{timeZone:p,onTimeZone:m,action:(0,i.jsx)(t.cr,{variant:`primary`,onClick:B,disabled:O||l,className:`max-sm:w-full h-11 px-6 text-[13.5px] font-bold shrink-0`,children:O?d?`Opening checkout…`:`Booking…`:d?`Book and pay ${Fd(d.amount)}`:`Confirm booking`})})]}):(0,i.jsxs)(i.Fragment,{children:[A&&(0,i.jsx)(`p`,{role:`alert`,className:`mb-3 text-[13px] font-semibold text-red-500`,children:A}),(0,i.jsx)(t.z,{members:_,value:v,onChange:y,taken:g,timeZone:p,onTimeZone:m})]})]})}var Ud=`rounded-2xl flex items-center justify-center shrink-0 border border-[var(--panel-border)]/50 bg-accent/10 text-accent`,Wd=`rounded-2xl border border-[var(--panel-border)]/60 bg-foreground/[0.015]`;function Gd(e){let[n,i]=(0,r.useState)(new Map),a=e.join(`,`);return(0,r.useEffect)(()=>{let e=a?a.split(`,`):[];if(!e.length)return;let n=!1;return Promise.all(e.map(async e=>{try{let n=await(0,o.getDoc)((0,o.doc)(t.Ca,Nn,e));return n.exists()?Gn(e,n.data()):null}catch{return null}})).then(e=>{if(n)return;let t=new Map;e.forEach(e=>{e&&t.set(e.id,e)}),i(t)}),()=>{n=!0}},[a]),n}function Kd({children:e}){return(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-2xl mx-auto px-4 py-8 md:py-12 z-10 flex flex-col justify-center`,children:(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},transition:{duration:.4},className:`w-full rounded-3xl glass-panel border border-[var(--panel-border)] p-5 sm:p-8 md:p-10 shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:e})})}function qd({icon:e,title:t,children:n}){return(0,i.jsxs)(`div`,{className:`flex flex-col items-center text-center py-8 gap-4`,children:[(0,i.jsx)(`div`,{className:`w-14 h-14 ${Ud}`,children:(0,i.jsx)(e,{className:`w-6 h-6`})}),(0,i.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold text-foreground tracking-tight`,children:t}),n&&(0,i.jsx)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed max-w-md`,children:n}),(0,i.jsx)(c.Link,{to:`/`,className:`text-[13px] font-bold text-accent hover:underline mt-2`,children:`Back to the site`})]})}function Jd({icon:e,accent:t,children:n}){return(0,i.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 h-6 px-2.5 rounded-full border text-[11.5px] font-semibold whitespace-nowrap ${t?`border-accent/40 bg-accent/10 text-accent`:`border-[var(--panel-border)]/70 text-foreground/60`}`,children:[e&&(0,i.jsx)(e,{className:`w-3 h-3 text-accent shrink-0`,"aria-hidden":!0}),n]})}function Yd({schedule:e,price:n}){let r=t.jn(e),a=t.Vn(e.slotMinutes);return(0,i.jsxs)(c.Link,{to:t.Qt(e.id),className:`${Wd} group relative overflow-hidden flex items-center gap-3.5 sm:gap-4 p-3 sm:p-4 transition-all duration-300
|
|
673
667
|
hover:border-accent/50 hover:shadow-[0_10px_30px_-12px_rgba(0,0,0,0.28)] hover:-translate-y-[2px] active:translate-y-0 active:scale-[0.995]`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity duration-300 bg-gradient-to-r from-accent/[0.09] via-accent/[0.03] to-transparent`}),(0,i.jsx)(`span`,{"aria-hidden":!0,className:`absolute left-0 top-0 bottom-0 w-[3px] bg-accent origin-center scale-y-0 group-hover:scale-y-100 transition-transform duration-300`}),(0,i.jsxs)(`span`,{"aria-hidden":!0,className:`relative shrink-0 w-[52px] h-[52px] rounded-2xl border border-[var(--panel-border)]/60 bg-accent/[0.07] text-accent
|
|
674
|
-
flex flex-col items-center justify-center leading-none gap-0.5 transition-colors duration-300 group-hover:bg-accent/[0.13] group-hover:border-accent/30`,children:[(0,i.jsx)(`span`,{className:`text-[17px] font-extrabold tracking-tight tabular-nums`,children:a.value}),(0,i.jsx)(`span`,{className:`text-[9.5px] font-bold uppercase tracking-[0.08em] opacity-70`,children:a.unit})]}),(0,i.jsxs)(`span`,{className:`relative flex-1 min-w-0 flex flex-col gap-1`,children:[(0,i.jsx)(`span`,{className:`text-[14.5px] sm:text-[15px] font-bold text-foreground tracking-tight leading-snug break-words`,children:t.In(e)}),(0,i.jsxs)(`span`,{className:`flex flex-wrap items-center gap-1.5`,children:[(0,i.jsx)(
|
|
675
|
-
text-foreground/35 transition-all duration-300 group-hover:border-accent/50 group-hover:bg-accent group-hover:text-[var(--button-fg,#fff)]`,children:(0,i.jsx)(t.Xi,{className:`w-4 h-4 transition-transform duration-300 group-hover:translate-x-[1px]`})})]})}function Jp({page:e}){let n=`w-24 h-24 sm:w-28 sm:h-28`;return(0,i.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`absolute -inset-3 rounded-[2rem] bg-accent/15 blur-2xl`}),e.photo?(0,i.jsx)(`img`,{src:e.photo,alt:``,className:`relative ${n} rounded-2xl object-cover border border-[var(--panel-border)] shadow-[0_10px_30px_rgba(0,0,0,0.12)]`}):(0,i.jsx)(`div`,{className:`relative ${n} ${Vp}`,children:(0,i.jsx)(t.Cr,{className:`w-9 h-9`})})]})}function Yp(){let{id:e=``}=(0,c.useParams)(),{activeConfig:n}=t.ja(),{loading:a,pages:o}=fo(),{loading:s,schedules:l}=t._(),u=o.find(t=>t.id===e)||null,d=(0,r.useMemo)(()=>u?so(u,l):[],[u,l]),f=Up((0,r.useMemo)(()=>[...new Set(d.map(e=>e.paymentId).filter(Boolean))],[d]));if(a||s)return(0,i.jsx)(Wp,{children:(0,i.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-16 text-foreground/50`,children:[(0,i.jsx)(t.ti,{className:`w-4 h-4 animate-spin text-accent`}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium`,children:`Loading…`})]})});if(!u||!u.enabled)return(0,i.jsx)(Wp,{children:(0,i.jsx)(Gp,{icon:t.Hi,title:`This page is no longer open`,children:`It may have been taken down. Ask whoever sent it for a new link.`})});if(!d.length){let e=oo(u,l).length;return(0,i.jsx)(Wp,{children:(0,i.jsx)(Gp,{icon:t.Hi,title:uo(u),children:e?`Nothing here is taking bookings at the moment. Please check back later.`:`There is nothing to book here at the moment. Please check back later.`})})}let p=u.intro.trim();return(0,i.jsxs)(Wp,{children:[(0,i.jsxs)(`div`,{className:`flex flex-col items-center text-center gap-4`,children:[(0,i.jsx)(Jp,{page:u}),(0,i.jsxs)(`div`,{className:`flex flex-col items-center gap-1.5 w-full min-w-0`,children:[n?.appName&&(0,i.jsx)(`span`,{className:`text-[10.5px] font-bold uppercase tracking-[0.18em] text-foreground/40 truncate max-w-full`,children:n.appName}),(0,i.jsx)(`h1`,{className:`text-[26px] sm:text-4xl font-extrabold tracking-tight text-gradient leading-[1.1] break-words`,children:uo(u)}),p&&(0,i.jsx)(`p`,{className:`mt-1.5 max-w-md text-[13.5px] sm:text-[14.5px] text-foreground/60 font-medium leading-relaxed whitespace-pre-line`,children:p})]})]}),(0,i.jsx)(`div`,{className:`h-px bg-[var(--panel-border)]/60 my-5 sm:my-7`}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-1`,children:[(0,i.jsx)(`p`,{className:`text-[11px] font-bold uppercase tracking-[0.16em] text-foreground/40`,children:d.length===1?`Book a time`:`Pick what to book`}),d.length>1&&(0,i.jsxs)(`span`,{className:`text-[11px] font-semibold text-foreground/35 tabular-nums`,children:[d.length,` meetings`]})]}),d.map(e=>(0,i.jsx)(qp,{schedule:e,price:Mp(f.get(e.paymentId)||null)},e.id))]})]})}function Xp({children:e,className:n,variant:a=`primary`,pendingLabel:o=`Opening checkout…`,...s}){let{loading:c,configured:l}=Y(),{userRole:u}=t.na(),[d,f]=(0,r.useState)(!1),[p,m]=(0,r.useState)(null);return c?null:l?(0,i.jsxs)(`span`,{className:`inline-flex flex-col items-stretch gap-2`,children:[(0,i.jsx)(t.cr,{variant:a,className:n,onClick:async()=>{if(d)return;f(!0),m(null);let e=await U(s);e&&(m(e),f(!1))},disabled:d,children:d?o:e??`Pay`}),p&&(0,i.jsx)(`span`,{role:`alert`,className:`text-[13px] font-semibold text-red-400 leading-snug`,children:p})]}):t.pa(u)?(0,i.jsx)(`span`,{className:`text-[12.5px] font-medium text-foreground/50 leading-snug`,children:`Only admins see this: payments are not on yet, so this button is hidden. Connect Stripe and switch payments on at /payments and it appears here.`}):null}function Zp(){let{id:e=``}=(0,c.useParams)(),{activeConfig:n}=t.ja(),a=Y(),[s,l]=(0,r.useState)({loading:!0,product:null});(0,r.useEffect)(()=>{let n=!1;return(0,o.getDoc)((0,o.doc)(t.Da,ji,e)).then(e=>{n||l({loading:!1,product:e.exists()?Ui(e.id,e.data()):null})}).catch(()=>{n||l({loading:!1,product:null})}),()=>{n=!0}},[e]);let u=s.product,d=u?.customPath.trim()||``;if(d)return(0,i.jsx)(c.Navigate,{to:d.startsWith(`/`)?d:`/${d}`,replace:!0});let f=u?Li(u).filter(e=>Ri(e.amount)):[],p=u?.name.trim()||f[0]?.name.trim()||`Pay`;return(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-3xl mx-auto px-4 pt-2 pb-16 md:pt-4 z-10 flex flex-col`,children:(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},transition:{duration:.4},className:`w-full rounded-3xl glass-panel border border-[var(--panel-border)] p-5 sm:p-8 md:p-10 shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:s.loading?(0,i.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-16 text-foreground/50`,children:[(0,i.jsx)(t.ti,{className:`w-4 h-4 animate-spin text-accent`}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium`,children:`Loading…`})]}):!u||u.kind!==`once`||!f.length?(0,i.jsxs)(`div`,{className:`flex flex-col items-center text-center py-8 gap-4`,children:[(0,i.jsx)(`div`,{className:`w-14 h-14 rounded-2xl glass-panel border border-[var(--panel-border)] flex items-center justify-center shadow-xl`,children:(0,i.jsx)(t.Pr,{className:`w-7 h-7 text-accent`})}),(0,i.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold text-foreground tracking-tight`,children:`This payment link is no longer open`}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/60 max-w-md`,children:`Ask whoever sent it for a new one.`}),(0,i.jsx)(c.Link,{to:`/`,className:`text-[13px] font-bold text-accent hover:underline mt-2`,children:`Back to the site`})]}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[n?.appName&&(0,i.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-[0.2em] text-foreground/40`,children:n.appName}),(0,i.jsx)(`h1`,{className:`text-2xl sm:text-3xl md:text-4xl font-extrabold text-foreground tracking-tight`,children:p}),u.description.trim()&&(0,i.jsx)(`p`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed mt-1 max-w-2xl whitespace-pre-line`,children:u.description.trim()})]}),!a.loading&&!a.configured&&(0,i.jsx)(`p`,{className:`text-[14px] font-medium text-foreground/60`,children:`Payments are not open right now — please try again later.`}),(0,i.jsx)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60`,children:f.map((e,n)=>(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-4 px-4 py-3.5`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex flex-col`,children:[(0,i.jsx)(`span`,{className:`text-[15px] font-semibold text-foreground truncate`,children:e.name.trim()||p}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/50`,children:Np(Ri(e.amount)||0)})]}),(0,i.jsxs)(Xp,{amount:Ri(e.amount)||0,productName:e.name.trim()||p,metadata:{productId:u.id,page:t.kn(u.id),emailReceipt:u.emailReceipt?`yes`:`no`,notifyOwner:u.notifyOwner?`yes`:`no`},successPath:`/payment-complete`,cancelPath:t.kn(u.id),className:`px-5 py-2.5 text-[14px] font-bold`,children:[`Pay `,Np(Ri(e.amount)||0)]})]},n))})]})})})}function Qp({trailing:e,onSent:n}){let[a,o]=(0,r.useState)(`idle`),[s,c]=(0,r.useState)(``);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5 flex-wrap`,children:[(0,i.jsx)(t.Q,{compact:!0,icon:t.qi,busy:a===`sending`,onClick:async()=>{o(`sending`),c(``);try{let e=await fetch(`/api/_selftest/email`),t=await e.json().catch(()=>({}));e.ok&&t?.ok?(o(`sent`),n?.(typeof t.from==`string`&&t.from.trim()?t.from:null)):(o(`failed`),c(String(t?.error||t?.message||`The server answered ${e.status}.`)))}catch{o(`failed`),c(`The server could not be reached.`)}},title:`Sends the test email to your own admin address`,children:`Send yourself a test email`}),e]}),a===`sent`&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-emerald-500 px-1`,children:`Sent. If you do not receive it within a minute, check your spam.`}),a===`failed`&&(0,i.jsxs)(`p`,{className:`text-[12px] font-medium text-red-500 px-1 leading-relaxed`,children:[`It did not send: `,s,` If the sending address uses your own domain, that domain must be verified under `,(0,i.jsx)(`strong`,{children:`Domains`}),` in your Resend account — an unverified domain makes every send fail.`]})]})}var{collection:$p,doc:em}=Zu.email,tm=(e,t)=>{let n=String(e||``).trim().toLowerCase(),r=String(t||``).trim().toLowerCase();return!!n&&n===r};function nm(){let[e,n]=(0,r.useState)({loading:!0,testedFrom:null});return(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(t.Da,$p,em),e=>{let t=e.exists()?e.data()?.testedFrom:null;n({loading:!1,testedFrom:typeof t==`string`&&t.trim()?t:null})},()=>n({loading:!1,testedFrom:null})),[]),{loading:e.loading,testedFrom:e.testedFrom,mark:async e=>{if(e.trim()){n({loading:!1,testedFrom:e});try{await(0,o.setDoc)((0,o.doc)(t.Da,$p,em),{testedFrom:e},{merge:!0})}catch(e){console.error(`Could not remember the test send`,e)}}}}}var rm=e=>[{title:`Hear about what happens`,body:`A booking, a form entry, a new member — at your address the moment it happens.`,icon:t.Ki,where:{path:`/pages`,label:`Pages screen`}},{title:`Confirm to the people who write in`,body:`Whoever books or writes gets a note that it arrived, in your words.`,icon:t.Qr,where:{path:`/pages`,label:`Pages screen`}},{title:`Receipts and sale alerts`,body:`Every payment emails the buyer a receipt and tells you something sold.`,icon:t.Vr,where:{path:`/payments`,label:`Payments screen`}},{title:`Write to anyone from your app`,body:`A page for your team can write to any address, from ${e}.`,icon:t.Ir,where:{path:`/pages`,label:`Pages screen`}}],im=e=>String(e||``).toLowerCase().endsWith(`@resend.dev`),am=e=>String(e||``).split(`@`)[1]||``,om=e=>e?{description:`Every page you told to send email does. Switch it off to stop all of it at once.`,chip:{state:`saved`,label:`On`}}:{description:`Nothing sends. Your pages keep their settings and wait for this to come back on.`,chip:{state:`off`,label:`Off`}};function sm({from:e}){return(0,i.jsx)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60`,children:rm(e).map(e=>{let n=e.icon;return(0,i.jsxs)(`div`,{className:`grid grid-cols-[auto_minmax(0,1fr)] sm:grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-x-3 sm:gap-x-3.5 gap-y-0.5 px-4 py-3`,children:[(0,i.jsx)(`div`,{className:`row-start-1 row-span-2 col-start-1 self-center w-9 h-9 rounded-xl flex items-center justify-center shrink-0 border border-[var(--panel-border)]/50 bg-accent/10 text-accent`,children:(0,i.jsx)(n,{className:`w-4 h-4`})}),(0,i.jsx)(`span`,{className:`row-start-1 col-start-2 min-w-0 text-[13px] font-bold text-foreground leading-tight self-end`,children:e.title}),(0,i.jsx)(`span`,{className:`row-start-2 col-start-2 min-w-0 text-[12px] text-foreground/50 font-normal leading-snug self-start`,children:e.body}),(0,i.jsxs)(c.Link,{to:e.where.path,className:`max-sm:hidden sm:inline-flex row-start-1 row-span-2 col-start-3 self-center justify-self-end items-center gap-1.5 text-[11.5px] font-semibold text-foreground/45 hover:text-accent whitespace-nowrap transition-colors`,children:[e.where.label,(0,i.jsx)(t.Xi,{className:`w-3 h-3`})]})]},e.title)})})}function cm({adminCount:e,onSetUp:n}){return(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5 px-1 flex-wrap`,children:[(0,i.jsx)(t.lt,{state:e?`saved`:`off`,label:e?`Your mail reaches ${e} address${e===1?``:`es`}`:`No address for your mail`}),!e&&(0,i.jsxs)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Sale, booking and form alerts have nowhere to go —`,` `,(0,i.jsx)(t.rt,{onClick:n,children:`add ADMIN_EMAILS`}),`.`]})]})}function lm(){let{status:e,error:n,reread:a}=od(),o=$u(`email`),[s,c]=(0,r.useState)(``),l=nm(),[u,d]=(0,r.useState)(!1),[f,p]=(0,r.useState)(!1),m=()=>{d(!1),a().then(()=>p(!0))},h=!!(e&&!e.configured),g=im(e?.from),_=om(o.on),v=!l.loading&&tm(l.testedFrom,e?.from);return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(Ce,{children:`Email`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/email`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col min-h-[600px]`,children:!e&&!n?(0,i.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,i.jsx)(t.ti,{className:`w-6 h-6 animate-spin text-accent`})}):h?(0,i.jsx)(Vd,{icon:t.Zr,title:`Connect email`,description:`This app is not sending email yet.`,stepsDescription:`Three steps — a key, two secrets, and the domain your mail goes out as.`,button:`Set up email`,secret:`RESEND_API_KEY`,open:u,onOpen:()=>d(!0),confirmed:f,steps:(0,i.jsx)(Ud,{onConfirm:m}),children:(0,i.jsx)(t.st,{children:`Email runs through Resend, and connecting it is two pasted rows — a key, and your own address for the mail that is meant for you. Once they are in, this screen fills itself: what your app can do with email, and where it goes.`})}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsx)(t.ut,{icon:t.Hr,title:`Send email`,description:_.description,chip:_.chip,enabled:o.loading?null:o.on,onChange:async e=>c(await o.set(e)||``),children:s?(0,i.jsx)(t.st,{tone:`error`,children:s}):null}),(0,i.jsx)(t.at,{icon:t.Qr,title:`Connection`,description:v&&!n?`Mail goes out as ${e?.from}.`:`Whether this app can send email right now.`,defaultOpen:!v||!e?.adminCount,actions:n?(0,i.jsx)(t.lt,{state:`error`,label:`Unreachable`}):(0,i.jsx)(t.lt,{state:`saved`,label:`Connected`}),children:n?(0,i.jsx)(t.st,{tone:`error`,children:n}):(0,i.jsxs)(i.Fragment,{children:[!v&&(0,i.jsxs)(t.st,{children:[`Mail goes out as `,(0,i.jsx)(`span`,{className:`font-bold text-foreground/70`,children:e?.from}),`.`,g?` That is Resend’s shared practice address: it delivers only to the address you made your Resend account with, so a test to yourself works and a customer’s email does not arrive. Before anyone else should get one, verify your own domain in Resend and add EMAIL_FROM — `:` That only works if ${am(e?.from)} is verified under Domains in your Resend account — an unverified domain makes every send fail. Every send also appears in your Resend dashboard, with nothing to sync.`,g&&(0,i.jsx)(t.rt,{onClick:()=>d(!0),children:`show me how`}),g&&`.`]}),(0,i.jsx)(cm,{adminCount:e?.adminCount||0,onSetUp:()=>d(!0)}),u&&(0,i.jsx)(`div`,{className:`px-1 pt-1`,children:(0,i.jsx)(Ud,{onConfirm:m})}),!v&&(0,i.jsx)(`div`,{className:`px-1`,children:(0,i.jsx)(Qp,{onSent:t=>l.mark(t||e?.from||``),trailing:(0,i.jsxs)(`a`,{href:`https://resend.com/emails`,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1.5 text-[12px] font-bold text-accent hover:underline`,children:[`See everything sent, in Resend`,(0,i.jsx)(t.bi,{className:`w-3 h-3`})]})})})]})}),(0,i.jsx)(t.at,{icon:t.Nr,title:`What you can do with email`,description:`Each is switched on where it happens — a page on the Pages screen, a payment on the Payments screen.`,children:(0,i.jsx)(sm,{from:e?.from||``})})]})})]})]})}var um=`src/your-ai-workflow-firebase-os`;function dm(){let e=new Set;for(let[t,n]of b()){let r=n?.config?.route,i=typeof r==`string`&&r.trim()?r.startsWith(`/`)?r:`/`+r:`/`+t.toLowerCase();e.add(i)}return[...e].sort()}var fm=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``);function pm(e){let t=e?.contentKey||e?.tabName||e?.pageName||e?.pageId||`Page`;return`${um}/microcomponents/${fm(String(t))||`Page`}Content.tsx`}function mm(e,t){let n=t.replace(/^.*\//,``).replace(/\.tsx$/,``),r=n.replace(/Content$/,``).replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();return[`My app has a page at ${e} and it is still empty after you said it was done. The ONLY thing that fills this page is one file: ${t}, with a default export, registered in ${um}/microcomponents/registry.ts.`,`Check these in order and fix whatever is wrong, without asking me questions:`,`1. The file exists at exactly that path and name — not another folder, not another spelling. If you put it somewhere else, move it there.`,`2. It has a default export. A named-only export is silently ignored.`,`3. ${um}/microcomponents/registry.ts contains these two lines: import ${n} from './${n}'; and registerMicrocomponent('${r}', ${n}); — registerMicrocomponent is imported there from 'your-ai-workflow-firebase-os'. Add them if they are missing, and never remove another page's lines.`,`4. You created nothing else for this page — no config file, no route, no page, and no edit to src/App.tsx or src/main.tsx. Undo any of those you made.`,`Then tell me, in one sentence, which of these was wrong.`].join(`
|
|
676
|
-
`)}function
|
|
677
|
-
`)}function gm({config:e,customContent:n}){let{config:a}=t.ja(),{userRole:o}=t.na();return(0,r.useEffect)(()=>{document.title=e.pageName||e.pageTitle||a.appName||`Your AI Firebase`},[e.pageName,e.pageTitle,a.appName]),(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col relative min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[(0,i.jsx)(Wt,{}),(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(Ce,{children:e.pageTitle||e.pageName||`New Page`}),e.route&&(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})]}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`glass-panel border border-[var(--panel-border)] rounded-3xl shadow-2xl relative flex flex-col flex-1 bg-background/50 h-full min-h-[400px]`,children:n?(0,i.jsx)(`div`,{className:`fbos-content-slot flex-1 p-4 md:p-8`,children:(0,i.jsx)(n,{config:e})}):e.form?(0,i.jsx)(`div`,{className:`fbos-content-slot flex-1 flex flex-col items-center justify-start p-4 md:p-8`,children:(0,i.jsx)(t.t,{isInline:!0,formId:e.form})}):(0,i.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center m-4 md:m-8 gap-6`,children:[(0,i.jsxs)(`div`,{className:`w-full glass-panel border border-[var(--panel-border)]/50 border-dashed rounded-2xl p-8 py-16 text-center opacity-70`,children:[(0,i.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/70`,children:`This page is empty`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 max-w-sm leading-relaxed mx-auto`,children:`Open the Pages screen, say what you would like on it, and copy the sentence there into your assistant's chat.`})]}),t.pa(o)&&(0,i.jsx)(`div`,{className:`w-full max-w-lg`,children:(0,i.jsx)(it,{compact:!0,title:`Already asked, and it is still empty? Paste this`,prompt:mm(e.route||`/`,pm(e))})})]})})]})}function _m({config:e,customContent:n}){let{user:a}=t.na(),{config:c}=t.ja(),[u,d]=(0,r.useState)([]),[f,p]=(0,r.useState)(!0),[m,h]=(0,r.useState)(!1),[g,_]=(0,r.useState)(``),[v,y]=(0,r.useState)(``),[b,x]=(0,r.useState)(!1),[S,C]=(0,r.useState)(null),w=(0,r.useRef)(null),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(null),[k,A]=(0,r.useState)(null),j=e=>{if(A(e),e){let t=e.fileType||``;P(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},M=k,[N,P]=(0,r.useState)(!0),[F,I]=(0,r.useState)(!1),[L,R]=(0,r.useState)(null),[z,B]=(0,r.useState)(``),[V,H]=(0,r.useState)(``),[U,W]=(0,r.useState)([]),G=(0,r.useRef)(null),ee=(e.tabName||e.pageId||`user_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`),K=t.va({...e,pageType:`user`}),q=`${K}${ee}_records`,J=K.startsWith(`role_`);(0,r.useEffect)(()=>{document.title=e.tabTitle||e.tabName||c.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,c.appName]),(0,r.useEffect)(()=>{if(!a)return;try{let e=Wa(q,a.uid);e?(d(e),p(!1)):p(!0)}catch{}let e=e=>e.map(e=>{let t=e.data();return{id:e.id,...t,createdAt:t.createdAt?.toMillis?t.createdAt.toMillis():t.createdAt}}),n=(0,o.onSnapshot)(J?(0,o.query)((0,o.collection)(t.Da,q),(0,o.limit)(150)):(0,o.query)((0,o.collection)(t.Da,q),(0,o.where)(`uid`,`==`,a.uid),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),d(n),p(!1),Ga(q,a.uid,n)},e=>{console.warn(`${q}: this account cannot read its records here (${e?.code||`permission-denied`}). Signed-in pages need a verified email address; the records themselves are only ever the signer's own.`),d(e=>e.length?[]:e),p(!1)});return()=>n()},[a,q,J]),(0,r.useEffect)(()=>{!f&&a&&Ga(q,a.uid,u)},[u,f,q,a]);let Y=async e=>{if(e.preventDefault(),!(!a||!g.trim())){x(!0);try{let e=await(0,o.addDoc)((0,o.collection)(t.Da,q),{name:g.trim(),note:v.trim(),uid:a.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)()});d(t=>[{id:e.id,name:g.trim(),note:v.trim(),uid:a.uid,recordType:`record`,createdAt:Date.now()},...t]),_(``),y(``),h(!1)}catch(e){console.error(`Error saving record:`,e)}x(!1)}},te=async e=>{let n=e.target.files?.[0];if(!n||!a)return;let r=await t.or(n);E(!0);try{let e=`user_files/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,n=(0,s.ref)(t.ka,e);await(0,s.uploadBytes)(n,r,{customMetadata:{ownerId:a.uid}});let i=await(0,s.getDownloadURL)(n);if(w.current)w.current(r,i,{uid:a.uid,storagePath:e});else{let e=await(0,o.addDoc)((0,o.collection)(t.Da,q),{name:r.name,note:`${r.type||`File`} · ${ge(r.size)}`,uid:a.uid,recordType:`file`,fileName:r.name,fileType:r.type||`unknown`,fileSize:r.size,downloadURL:i,createdAt:(0,o.serverTimestamp)()});d(t=>[{id:e.id,name:r.name,note:`${r.type||`File`} · ${ge(r.size)}`,uid:a.uid,recordType:`file`,fileName:r.name,fileType:r.type,fileSize:r.size,downloadURL:i,createdAt:Date.now()},...t])}}catch(e){console.error(`Error uploading file:`,e)}E(!1),G.current&&(G.current.value=``)},ne=async()=>{if(D){I(!0);try{let e=u.find(e=>e.id===D);if(await(0,o.deleteDoc)((0,o.doc)(t.Da,q,D)),e?.recordType===`file`&&e.downloadURL)try{let n=e.downloadURL.split(`user_files%2F`)[1]?.split(`?`)[0];n&&await(0,s.deleteObject)((0,s.ref)(t.ka,`user_files/${decodeURIComponent(n)}`)).catch(()=>{})}catch(e){console.error(`Error cleaning up user file:`,e)}d(e=>e.filter(e=>e.id!==D)),O(null)}catch(e){console.error(`Error deleting record:`,e)}I(!1)}},[re,X]=(0,r.useState)(null),[Z,Q]=(0,r.useState)(``),[ie,ae]=(0,r.useState)(!1),[oe,se]=(0,r.useState)(null),ce=(0,r.useRef)([]),le=e=>{if(e.recordType===`file`){X(e.id),Q(e.name);return}R(e.id),B(e.name),H(e.note||``);let t=[`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`createdAt`],n=Object.entries(e).filter(([e])=>!t.includes(e)&&e!==`id`).map(([e,t])=>({key:e,value:String(t??``)}));W(n),ce.current=n.map(e=>e.key)},ue=async()=>{if(!re||!Z.trim()){X(null);return}let e=u.find(e=>e.id===re);if(e&&e.name===Z.trim()){X(null);return}ae(!0);try{await(0,o.updateDoc)((0,o.doc)(t.Da,q,re),{name:Z.trim()}),d(e=>e.map(e=>e.id===re?{...e,name:Z.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}ae(!1),X(null)},de=async()=>{await fe(),R(null)},fe=async()=>{if(!L||!z.trim())return;x(!0);let e={};U.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let n=U.map(e=>e.key.trim()).filter(Boolean),r=ce.current.filter(e=>!n.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(t.Da,q,L),{name:z.trim(),note:V.trim(),...e}),d(e=>e.map(e=>{if(e.id!==L)return e;let t={...e,name:z.trim(),note:V.trim()};return r.forEach(e=>{delete t[e]}),U.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),ce.current=n}catch(e){console.error(`Error saving record:`,e)}x(!1)},pe=(e,n)=>e?e.startsWith(`image/`)?n?(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${n})`}}):(0,i.jsx)(t.fi,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,i.jsx)(t.br,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,i.jsx)(t.gi,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,i.jsx)(t.ea,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,i.jsx)(t.Ei,{className:`w-4 h-4`}):(0,i.jsx)(t.hi,{className:`w-4 h-4`}):(0,i.jsx)(t.gi,{className:`w-4 h-4`}),me=e=>e?e.startsWith(`image/`)?`bg-emerald-500/10 text-emerald-500`:e.startsWith(`video/`)||e.startsWith(`audio/`)?`bg-accent/10 text-accent`:e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?`bg-blue-500/10 text-blue-500`:e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?`bg-yellow-500/10 text-yellow-500`:e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?`bg-emerald-500/10 text-emerald-500`:`bg-foreground/5 text-foreground/40`:`bg-foreground/5 text-foreground/40`,he=e=>{if(!e)return`FILE`;let t={"application/pdf":`PDF`,"application/zip":`ZIP`,"application/x-zip-compressed":`ZIP`,"application/x-rar-compressed":`RAR`,"application/x-7z-compressed":`7Z`,"application/json":`JSON`,"application/xml":`XML`,"application/javascript":`JS`,"application/typescript":`TS`,"application/msword":`DOC`,"application/vnd.openxmlformats-officedocument.wordprocessingml.document":`DOCX`,"application/vnd.ms-excel":`XLS`,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":`XLSX`,"application/vnd.ms-powerpoint":`PPT`,"application/vnd.openxmlformats-officedocument.presentationml.presentation":`PPTX`,"application/rtf":`RTF`,"application/x-tar":`TAR`,"application/gzip":`GZ`,"text/plain":`TXT`,"text/html":`HTML`,"text/css":`CSS`,"text/csv":`CSV`,"text/markdown":`MD`},n=e.toLowerCase();if(t[n])return t[n];let r=n.split(`/`);return r[r.length-1].replace(/^x-/,``).replace(/^vnd\..*\./,``).toUpperCase().slice(0,10)},ge=e=>{if(!e)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**+r).toFixed(2))+` `+n[r]},_e=e=>{if(!e)return``;let t=e.toMillis?e.toMillis():e;return new Date(t).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})},ve=(()=>{let n=(e.buttonStorageIcon||`upload`).trim(),r=n.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return t.mr[r]?t.mr[r]:t.mr[n]?t.mr[n]:t.wr||t.Ur})(),ye=e.buttonStyle!==`secondary`,be=e.buttonStorageStyle===`primary`;return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(Ce,{children:e.tabTitle||e.tabName||`User Page`}),e.route&&(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background`,children:[(0,i.jsx)(`input`,{type:`file`,ref:G,onChange:te,className:`hidden`}),!n&&(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4 p-4 sm:p-6 md:px-8 md:py-6 border-b border-[var(--panel-border)]/50 bg-background/50 shrink-0`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:f?`Loading…`:`${u.length} ${u.length===1?`item`:`items`}`})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,i.jsx)(i.Fragment,{children:(0,i.jsxs)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>G.current?.click(),disabled:T,title:e.buttonStorageText||`Upload File`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed ${e.buttonStorageText?`px-4`:`w-10`} ${be?`btn-primary`:`btn-secondary`}`,children:[T?(0,i.jsx)(t.ti,{className:`w-4 h-4 animate-spin`}):(0,i.jsx)(ve,{className:`w-4 h-4`}),e.buttonStorageText&&(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>h(!0),title:`Add New`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer ${e.buttonText&&e.buttonText!==`+`?`px-5`:`w-10`} ${ye?`btn-primary`:`btn-secondary`}`,children:e.buttonText===`+`||!e.buttonText?(0,i.jsx)(t.Ur,{className:`w-4 h-4`}):(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,i.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[f&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,i.jsx)(t.ti,{className:`w-8 h-8 text-accent animate-spin`})}),n?(0,i.jsx)(`div`,{className:`fbos-content-slot`,children:(0,i.jsx)(n,{config:e,actions:{records:u,loading:f,collection:q,user:a,saveRecord:async e=>{let n=(0,o.doc)((0,o.collection)(t.Da,q)),r={id:n.id,uid:a.uid,recordType:`record`,createdAt:Date.now(),...e};d(e=>[r,...e]),await(0,o.setDoc)(n,{uid:a.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,n)=>{d(t=>t.map(t=>t.id===e?{...t,...n}:t)),await(0,o.updateDoc)((0,o.doc)(t.Da,q,e),n)},deleteRecord:async e=>{await(0,o.deleteDoc)((0,o.doc)(t.Da,q,e))},startEdit:e=>le(e),confirmDelete:e=>O(e),uploadFile:()=>G.current?.click(),openAddForm:()=>h(!0),setAddForm:e=>C(()=>e),setFileHandler:e=>{w.current=e}}})}):(0,i.jsxs)(i.Fragment,{children:[!f&&u.length===0&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex-1 flex flex-col items-center justify-center border border-[var(--panel-border)]/50 border-dashed rounded-2xl p-8 py-20 text-center min-h-[350px]`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-2xl bg-accent/5 border border-accent/10 flex items-center justify-center mb-5`,children:(0,i.jsx)(t.Ur,{className:`w-6 h-6 text-accent/40`})}),(0,i.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/35 max-w-xs leading-relaxed`,children:`Use the buttons above to add records or upload files to get started`})]}),!f&&u.length>0&&(0,i.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,i.jsx)(t.pr,{children:u.map((e,n)=>{let r=L===e.id;return(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},transition:{delay:n*.03,duration:.25},onClick:()=>le(e),className:`group flex flex-col bg-background border rounded-2xl p-5 transition-all relative cursor-pointer ${r?`border-accent/40 shadow-lg ring-1 ring-accent/20`:`border-[var(--panel-border)] hover:border-accent/30 hover:shadow-lg`}`,children:[(0,i.jsxs)(`div`,{className:`absolute top-3 right-3 flex items-center gap-0.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-all z-10`,children:[e.recordType===`file`&&e.downloadURL&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),se(e.id),setTimeout(()=>se(null),2e3)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-emerald-500 hover:bg-emerald-500/10 transition-all cursor-pointer`,title:`Copy Link`,children:oe===e.id?(0,i.jsx)(t.zi,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,i.jsx)(t.ri,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`a`,{href:e.downloadURL,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),className:`p-1.5 rounded-lg text-foreground/25 hover:text-blue-500 hover:bg-blue-500/10 transition-all`,title:`Download`,children:(0,i.jsx)(t.Si,{className:`w-3.5 h-3.5`})})]}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),le(e)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-accent hover:bg-accent/10 transition-all cursor-pointer`,title:`Edit`,children:(0,i.jsx)(t.Kr,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),O(e.id)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-red-500 hover:bg-red-500/10 transition-all cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-3.5 h-3.5`})})]}),(0,i.jsxs)(`div`,{className:`flex items-start gap-3 mb-3`,children:[(0,i.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&j(e)},className:`w-9 h-9 rounded-xl flex items-center justify-center shrink-0 ${e.recordType===`file`?`cursor-pointer hover:scale-105 transition-transform ${me(e.fileType)}`:`bg-accent/10 text-accent`}`,children:e.recordType===`file`?pe(e.fileType,e.downloadURL):(0,i.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[re===e.id?(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,value:Z,onChange:e=>Q(e.target.value),onBlur:()=>ue(),onKeyDown:e=>{e.key===`Enter`&&ue(),e.key===`Escape`&&X(null)},onClick:e=>e.stopPropagation(),className:`no-glow text-[14px] font-bold text-foreground bg-transparent border-b border-accent/30 outline-none pb-0.5 w-full pr-12`}):(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>j(e)}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:_e(e.createdAt)})]})]}),e.note&&(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/55 font-medium leading-relaxed line-clamp-3 mb-1`,children:e.note}),Object.entries(e).filter(([e])=>![`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`createdAt`,`creatorName`,`creatorEmail`,`creatorAvatar`].includes(e)&&e!==`id`).slice(0,3).map(([e,t])=>(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,i.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e))]},e.id)})})})]})]})]})]}),(0,i.jsx)(t.pr,{children:m&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>!b&&h(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[360px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:S?r.default.createElement(S,{onSave:async e=>{x(!0);try{await(0,o.addDoc)((0,o.collection)(t.Da,q),{uid:a.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)(),...e}),h(!1)}catch(e){console.error(`Error saving record:`,e)}x(!1)},onClose:()=>!b&&h(!1),saving:b}):(0,i.jsxs)(`form`,{onSubmit:Y,className:`p-5 flex flex-col gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>!b&&h(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:g,onChange:e=>_(e.target.value),placeholder:`Name *`,disabled:b,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-semibold text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`textarea`,{value:v,onChange:e=>y(e.target.value),placeholder:`Note (optional)`,disabled:b,rows:2,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-medium text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30 resize-none`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,i.jsx)(t.cr,{type:`submit`,isLoading:b,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:b?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,l.createPortal)((0,i.jsx)(t.pr,{children:M&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>j(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(`button`,{onClick:()=>j(null),className:`absolute top-6 right-6 z-[160] w-12 h-12 bg-foreground/10 hover:bg-foreground/20 text-foreground rounded-full flex items-center justify-center backdrop-blur-md transition-all cursor-pointer outline-none`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`relative z-10 w-full max-w-6xl max-h-[85vh] flex flex-col pointer-events-auto shadow-2xl rounded-3xl overflow-hidden glass-panel border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between p-6 bg-background/80 backdrop-blur-md border-b border-[var(--panel-border)] shrink-0 shadow-sm z-20`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,i.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:M.fileName||M.name}),(0,i.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[he(M.fileType),` • `,ge(M.fileSize||0)]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(M.downloadURL),se(`preview`),setTimeout(()=>se(null),2e3)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 transition-colors rounded-xl shadow-sm hover:text-emerald-500 cursor-pointer`,title:`Copy Link`,children:oe===`preview`?(0,i.jsx)(t.zi,{className:`w-4 h-4 text-emerald-500`}):(0,i.jsx)(t.ri,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),X(M.id),Q(M.name)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 hover:text-accent transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Rename`,children:(0,i.jsx)(t.Kr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),O(M.id)},className:`p-2.5 bg-red-500/10 hover:bg-red-500/20 text-red-500 transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})}),(0,i.jsx)(`a`,{href:M.downloadURL,download:!0,target:`_blank`,rel:`noreferrer`,className:`p-2.5 btn-primary transition-colors rounded-xl shadow-lg ml-1`,title:`Download`,children:(0,i.jsx)(t.Si,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>j(null),children:(0,i.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[N&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,i.jsx)(`div`,{className:`w-12 h-12 rounded-full bg-background/80 backdrop-blur-md shadow-xl flex items-center justify-center border border-[var(--panel-border)]/50`,children:(0,i.jsx)(t.ti,{className:`w-5 h-5 text-accent animate-spin`})})}),M.fileType?.startsWith(`image/`)?(0,i.jsx)(`img`,{onLoad:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,alt:M.fileName||M.name,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full object-contain drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] rounded-lg pointer-events-auto transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType?.startsWith(`video/`)?(0,i.jsx)(`video`,{onLoadedData:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,controls:!0,autoPlay:!0,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full outline-none bg-black/40 rounded-lg pointer-events-auto drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType===`application/pdf`?(0,i.jsx)(`iframe`,{onLoad:()=>P(!1),src:M.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,i.jsxs)(`div`,{className:`w-full h-full flex flex-col items-center justify-center text-foreground/40 text-center relative z-10`,onClick:e=>{e.stopPropagation(),P(!1)},children:[(0,i.jsx)(t.gi,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,i.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,i.jsx)(`span`,{className:`text-[14px] mt-2 text-foreground/60 font-medium max-w-xs`,children:`This file format cannot be previewed. Please download it instead.`})]})]})})]})]})}),document.body),(0,i.jsx)(t.pr,{children:L&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>de(),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[440px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:(0,i.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),b&&(0,i.jsx)(t.ti,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>de(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NAME`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`input`,{autoFocus:!0,required:!0,value:z,onChange:e=>B(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>fe(),placeholder:`Name *`,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NOTE`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:V,onChange:e=>{H(e.target.value),e.target.style.height=`auto`,e.target.style.height=e.target.scrollHeight+`px`},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),e.target.blur())},onBlur:()=>fe(),placeholder:`Add a note...`,rows:1,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50 resize-none overflow-hidden`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),U.map((e,n)=>(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let t=[...U];t[n].key=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>fe(),className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none placeholder:text-foreground/15 pt-3 pb-0.5 caret-foreground/40`}),(0,i.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let t=[...U];t[n].value=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>fe(),className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pt-1.5 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>W(U.filter((e,t)=>t!==n)),className:`absolute top-3 right-0 p-1 text-foreground/0 group-hover/field:text-foreground/20 hover:!text-red-400 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})})]},n)),(0,i.jsxs)(`button`,{type:`button`,onClick:()=>W([...U,{key:``,value:``}]),className:`flex items-center gap-1.5 text-[11px] font-medium text-foreground/25 hover:text-foreground/40 transition-colors cursor-pointer mt-4 mb-4`,children:[(0,i.jsx)(t.Ur,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,i.jsx)(Ve,{isOpen:!!D,onCancel:()=>O(null),onConfirm:ne,title:`Delete Record`,message:(0,i.jsxs)(i.Fragment,{children:[`Are you sure you want to delete `,(0,i.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:u.find(e=>e.id===D)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:F})]})}function vm({config:e,customContent:n}){let{user:a}=t.na(),{config:c}=t.ja(),[u,d]=(0,r.useState)([]),[f,p]=(0,r.useState)(!0),[m,h]=(0,r.useState)(!1),[g,_]=(0,r.useState)(``),[v,y]=(0,r.useState)(``),[b,x]=(0,r.useState)(!1),[S,C]=(0,r.useState)(null),w=(0,r.useRef)(null),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(null),[k,A]=(0,r.useState)(null),j=e=>{if(A(e),e){let t=e.fileType||``;P(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},M=k,[N,P]=(0,r.useState)(!0),[F,I]=(0,r.useState)(!1),[L,R]=(0,r.useState)(null),[z,B]=(0,r.useState)(``),[V,H]=(0,r.useState)(``),[U,W]=(0,r.useState)([]),G=(0,r.useRef)(null),[ee,K]=(0,r.useState)(null),q=(0,r.useRef)([]),J=`admin_${(e.tabName||e.pageId||`admin_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`)}_records`;(0,r.useEffect)(()=>{document.title=e.tabTitle||e.tabName||c.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,c.appName]);let Y=()=>({name:a.displayName||a.email?.split(`@`)[0]||`Admin`,email:a.email||``,avatar:a.photoURL||``});(0,r.useEffect)(()=>{if(!a)return;try{let e=Wa(J,a.uid);e?(d(e),p(!1)):p(!0)}catch{}let e=e=>e.map(e=>{let t=e.data();return{id:e.id,...t,createdAt:t.createdAt?.toMillis?t.createdAt.toMillis():t.createdAt}}),n=(0,o.onSnapshot)((0,o.query)((0,o.collection)(t.Da,J),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(150)),t=>{let n=e(t.docs);d(n),p(!1),Ga(J,a.uid,n)},n=>{console.error(`Error listening to admin records:`,n);let r=(0,o.onSnapshot)((0,o.query)((0,o.collection)(t.Da,J),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),d(n),p(!1),Ga(J,a.uid,n)});return()=>r()});return()=>n()},[a,J]);let te=async e=>{if(e.preventDefault(),!(!a||!g.trim())){x(!0);try{let e=Y();await(0,o.addDoc)((0,o.collection)(t.Da,J),{name:g.trim(),note:v.trim(),uid:a.uid,recordType:`record`,creatorName:e.name,creatorEmail:e.email,creatorAvatar:e.avatar,createdAt:(0,o.serverTimestamp)()}),_(``),y(``),h(!1)}catch(e){console.error(`Error saving admin record:`,e)}x(!1)}},ne=async e=>{let n=e.target.files?.[0];if(!n||!a)return;let r=await t.or(n);E(!0);try{let e=`admin_files/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,n=(0,s.ref)(t.ka,e);await(0,s.uploadBytes)(n,r,{customMetadata:{ownerId:a.uid}});let i=await(0,s.getDownloadURL)(n);if(w.current)w.current(r,i,{uid:a.uid,storagePath:e});else{let e=Y();await(0,o.addDoc)((0,o.collection)(t.Da,J),{name:r.name,note:`${r.type||`File`} · ${me(r.size)}`,uid:a.uid,recordType:`file`,fileName:r.name,fileType:r.type||`unknown`,fileSize:r.size,downloadURL:i,creatorName:e.name,creatorEmail:e.email,creatorAvatar:e.avatar,createdAt:(0,o.serverTimestamp)()})}}catch(e){console.error(`Error uploading admin file:`,e)}E(!1),G.current&&(G.current.value=``)},re=async()=>{if(D){I(!0);try{let e=u.find(e=>e.id===D);if(await(0,o.deleteDoc)((0,o.doc)(t.Da,J,D)),e?.recordType===`file`&&e.downloadURL)try{let n=e.downloadURL.split(`admin_files%2F`)[1]?.split(`?`)[0];n&&await(0,s.deleteObject)((0,s.ref)(t.ka,`admin_files/${decodeURIComponent(n)}`)).catch(()=>{})}catch(e){console.error(`Error cleaning up admin file:`,e)}O(null)}catch(e){console.error(`Error deleting admin record:`,e)}I(!1)}},[X,Z]=(0,r.useState)(null),[Q,ie]=(0,r.useState)(``),[ae,oe]=(0,r.useState)(!1),se=e=>{if(e.recordType===`file`){Z(e.id),ie(e.name);return}R(e.id),B(e.name),H(e.note||``);let t=[`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`createdAt`,`creatorName`,`creatorEmail`,`creatorAvatar`],n=Object.entries(e).filter(([e])=>!t.includes(e)&&e!==`id`).map(([e,t])=>({key:e,value:String(t??``)}));W(n),q.current=n.map(e=>e.key)},ce=async()=>{if(!X||!Q.trim()){Z(null);return}let e=u.find(e=>e.id===X);if(e&&e.name===Q.trim()){Z(null);return}oe(!0);try{await(0,o.updateDoc)((0,o.doc)(t.Da,J,X),{name:Q.trim()}),d(e=>e.map(e=>e.id===X?{...e,name:Q.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}oe(!1),Z(null)},le=async()=>{if(!L||!z.trim()){R(null);return}x(!0);let e={};U.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let n=U.map(e=>e.key.trim()).filter(Boolean),r=q.current.filter(e=>!n.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(t.Da,J,L),{name:z.trim(),note:V.trim(),...e}),d(e=>e.map(e=>{if(e.id!==L)return e;let t={...e,name:z.trim(),note:V.trim()};return r.forEach(e=>{delete t[e]}),U.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),q.current=n}catch(e){console.error(`Error updating record:`,e)}x(!1),R(null)},ue=async()=>{if(!L||!z.trim())return;let e={};U.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let n=U.map(e=>e.key.trim()).filter(Boolean),r=q.current.filter(e=>!n.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(t.Da,J,L),{name:z.trim(),note:V.trim(),...e}),d(e=>e.map(e=>{if(e.id!==L)return e;let t={...e,name:z.trim(),note:V.trim()};return r.forEach(e=>{delete t[e]}),U.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),q.current=n}catch(e){console.error(`Error silently saving record:`,e)}},de=(e,n)=>e?e.startsWith(`image/`)?n?(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${n})`}}):(0,i.jsx)(t.fi,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,i.jsx)(t.br,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,i.jsx)(t.gi,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,i.jsx)(t.ea,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,i.jsx)(t.Ei,{className:`w-4 h-4`}):(0,i.jsx)(t.hi,{className:`w-4 h-4`}):(0,i.jsx)(t.gi,{className:`w-4 h-4`}),fe=e=>e?e.startsWith(`image/`)?`bg-emerald-500/10 text-emerald-500`:e.startsWith(`video/`)||e.startsWith(`audio/`)?`bg-accent/10 text-accent`:e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?`bg-blue-500/10 text-blue-500`:e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?`bg-yellow-500/10 text-yellow-500`:e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?`bg-emerald-500/10 text-emerald-500`:`bg-foreground/5 text-foreground/40`:`bg-foreground/5 text-foreground/40`,pe=e=>{if(!e)return`FILE`;let t={"application/pdf":`PDF`,"application/zip":`ZIP`,"application/x-zip-compressed":`ZIP`,"application/x-rar-compressed":`RAR`,"application/x-7z-compressed":`7Z`,"application/json":`JSON`,"application/xml":`XML`,"application/javascript":`JS`,"application/typescript":`TS`,"application/msword":`DOC`,"application/vnd.openxmlformats-officedocument.wordprocessingml.document":`DOCX`,"application/vnd.ms-excel":`XLS`,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":`XLSX`,"application/vnd.ms-powerpoint":`PPT`,"application/vnd.openxmlformats-officedocument.presentationml.presentation":`PPTX`,"application/rtf":`RTF`,"application/x-tar":`TAR`,"application/gzip":`GZ`,"text/plain":`TXT`,"text/html":`HTML`,"text/css":`CSS`,"text/csv":`CSV`,"text/markdown":`MD`},n=e.toLowerCase();if(t[n])return t[n];let r=n.split(`/`);return r[r.length-1].replace(/^x-/,``).replace(/^vnd\..*\./,``).toUpperCase().slice(0,10)},me=e=>{if(!e)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**+r).toFixed(2))+` `+n[r]},he=e=>{if(!e)return``;let t=e.toMillis?e.toMillis():e;return new Date(t).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})},ge=(()=>{let n=(e.buttonStorageIcon||`upload`).trim(),r=n.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return t.mr[r]?t.mr[r]:t.mr[n]?t.mr[n]:t.wr||t.Ur})(),_e=e.buttonStyle!==`secondary`,ve=e.buttonStorageStyle===`primary`,ye=e=>e.uid===a?.uid,be=({record:e})=>{let t=e.creatorName||e.creatorEmail?.split(`@`)[0]||`Admin`,n=e.creatorEmail||``,r=e.creatorAvatar||``,a=t.split(` `).map(e=>e[0]).join(``).toUpperCase().slice(0,2);return(0,i.jsxs)(`div`,{className:`flex items-center gap-2 mt-2 pt-2 border-t border-[var(--panel-border)]/30`,children:[r?(0,i.jsx)(`img`,{src:r,alt:``,className:`w-5 h-5 rounded-full object-cover shrink-0`}):(0,i.jsx)(`div`,{className:`w-5 h-5 rounded-full bg-accent/15 text-accent flex items-center justify-center text-[8px] font-extrabold shrink-0`,children:a}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 truncate`,children:t}),n&&(0,i.jsxs)(`span`,{className:`text-[10px] text-foreground/25 truncate`,children:[`· `,n]})]})]})};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(Ce,{children:e.tabTitle||e.tabName||`Admin Page`}),e.route&&(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background`,children:[(0,i.jsx)(`input`,{type:`file`,ref:G,onChange:ne,className:`hidden`}),!n&&(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4 p-4 sm:p-6 md:px-8 md:py-6 border-b border-[var(--panel-border)]/50 bg-background/50 shrink-0`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:f?`Loading…`:`${u.length} ${u.length===1?`item`:`items`}`})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,i.jsx)(i.Fragment,{children:(0,i.jsxs)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>G.current?.click(),disabled:T,title:e.buttonStorageText||`Upload File`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed ${e.buttonStorageText?`px-4`:`w-10`} ${ve?`btn-primary`:`btn-secondary`}`,children:[T?(0,i.jsx)(t.ti,{className:`w-4 h-4 animate-spin`}):(0,i.jsx)(ge,{className:`w-4 h-4`}),e.buttonStorageText&&(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>h(!0),title:`Add New`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer ${e.buttonText&&e.buttonText!==`+`?`px-5`:`w-10`} ${_e?`btn-primary`:`btn-secondary`}`,children:e.buttonText===`+`||!e.buttonText?(0,i.jsx)(t.Ur,{className:`w-4 h-4`}):(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,i.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[f&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,i.jsx)(t.ti,{className:`w-8 h-8 text-accent animate-spin`})}),n?(0,i.jsx)(`div`,{className:`fbos-content-slot`,children:(0,i.jsx)(n,{config:e,actions:{records:u,loading:f,collection:J,user:a,saveRecord:async e=>{let n=(0,o.doc)((0,o.collection)(t.Da,J)),r=Y(),i={id:n.id,uid:a.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:Date.now(),...e};d(e=>[i,...e]),await(0,o.setDoc)(n,{uid:a.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,n)=>{d(t=>t.map(t=>t.id===e?{...t,...n}:t)),await(0,o.updateDoc)((0,o.doc)(t.Da,J,e),n)},deleteRecord:async e=>{await(0,o.deleteDoc)((0,o.doc)(t.Da,J,e))},startEdit:e=>se(e),confirmDelete:e=>O(e),uploadFile:()=>G.current?.click(),openAddForm:()=>h(!0),setAddForm:e=>C(()=>e),setFileHandler:e=>{w.current=e}}})}):(0,i.jsxs)(i.Fragment,{children:[!f&&u.length===0&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex-1 flex flex-col items-center justify-center border border-[var(--panel-border)]/50 border-dashed rounded-2xl p-8 py-20 text-center min-h-[350px]`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-2xl bg-accent/5 border border-accent/10 flex items-center justify-center mb-5`,children:(0,i.jsx)(t.Ur,{className:`w-6 h-6 text-accent/40`})}),(0,i.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/35 max-w-xs leading-relaxed`,children:`Use the buttons above to add records or upload files. All admins can view and contribute.`})]}),!f&&u.length>0&&(0,i.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,i.jsx)(t.pr,{children:u.map((e,n)=>{let r=L===e.id,a=ye(e);return(0,i.jsxs)(t.fr.div,{initial:!1,animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},onClick:()=>se(e),className:`group flex flex-col bg-background border rounded-2xl p-5 transition-all relative cursor-pointer ${r?`border-accent/40 shadow-lg ring-1 ring-accent/20`:`border-[var(--panel-border)] hover:border-accent/30 hover:shadow-lg`}`,children:[(0,i.jsxs)(`div`,{className:`absolute top-3 right-3 flex items-center gap-0.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-all z-10`,children:[e.recordType===`file`&&e.downloadURL&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),K(e.id),setTimeout(()=>K(null),2e3)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-emerald-500 hover:bg-emerald-500/10 transition-all cursor-pointer`,title:`Copy Link`,children:ee===e.id?(0,i.jsx)(t.zi,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,i.jsx)(t.ri,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`a`,{href:e.downloadURL,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),className:`p-1.5 rounded-lg text-foreground/25 hover:text-blue-500 hover:bg-blue-500/10 transition-all`,title:`Download`,children:(0,i.jsx)(t.Si,{className:`w-3.5 h-3.5`})})]}),a&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),se(e)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-accent hover:bg-accent/10 transition-all cursor-pointer`,title:`Edit`,children:(0,i.jsx)(t.Kr,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),O(e.id)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-red-500 hover:bg-red-500/10 transition-all cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-3.5 h-3.5`})})]})]}),(0,i.jsxs)(`div`,{className:`flex items-start gap-3 mb-2`,children:[(0,i.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&j(e)},className:`w-9 h-9 rounded-xl flex items-center justify-center shrink-0 ${e.recordType===`file`?`cursor-pointer hover:scale-105 transition-transform ${fe(e.fileType)}`:`bg-accent/10 text-accent`}`,children:e.recordType===`file`?de(e.fileType,e.downloadURL):(0,i.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[X===e.id?(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,value:Q,onChange:e=>ie(e.target.value),onBlur:()=>ce(),onKeyDown:e=>{e.key===`Enter`&&ce(),e.key===`Escape`&&Z(null)},onClick:e=>e.stopPropagation(),className:`no-glow text-[14px] font-bold text-foreground bg-transparent border-b border-accent/30 outline-none pb-0.5 w-full pr-12`}):(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>j(e)}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:he(e.createdAt)})]})]}),e.note&&(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/55 font-medium leading-relaxed line-clamp-3 mb-1`,children:e.note}),Object.entries(e).filter(([e])=>![`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`createdAt`,`creatorName`,`creatorEmail`,`creatorAvatar`].includes(e)&&e!==`id`).slice(0,3).map(([e,t])=>(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,i.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e)),(0,i.jsx)(be,{record:e})]},e.id)})})})]})]})]})]}),(0,i.jsx)(t.pr,{children:m&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>!b&&h(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[360px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:S?r.default.createElement(S,{onSave:async e=>{x(!0);try{let n=Y();await(0,o.addDoc)((0,o.collection)(t.Da,J),{uid:a.uid,recordType:`record`,creatorName:n.name,creatorEmail:n.email,creatorAvatar:n.avatar,createdAt:(0,o.serverTimestamp)(),...e}),h(!1)}catch(e){console.error(`Error saving record:`,e)}x(!1)},onClose:()=>!b&&h(!1),saving:b}):(0,i.jsxs)(`form`,{onSubmit:te,className:`p-5 flex flex-col gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>!b&&h(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:g,onChange:e=>_(e.target.value),placeholder:`Name *`,disabled:b,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-semibold text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`textarea`,{value:v,onChange:e=>y(e.target.value),placeholder:`Note (optional)`,disabled:b,rows:2,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-medium text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30 resize-none`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,i.jsx)(t.cr,{type:`submit`,isLoading:b,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:b?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,l.createPortal)((0,i.jsx)(t.pr,{children:M&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>j(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(`button`,{onClick:()=>j(null),className:`absolute top-6 right-6 z-[160] w-12 h-12 bg-foreground/10 hover:bg-foreground/20 text-foreground rounded-full flex items-center justify-center backdrop-blur-md transition-all cursor-pointer outline-none`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`relative z-10 w-full max-w-6xl max-h-[85vh] flex flex-col pointer-events-auto shadow-2xl rounded-3xl overflow-hidden glass-panel border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between p-6 bg-background/80 backdrop-blur-md border-b border-[var(--panel-border)] shrink-0 shadow-sm z-20`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,i.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:M.fileName||M.name}),(0,i.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[pe(M.fileType),` • `,me(M.fileSize||0)]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(M.downloadURL),K(`preview`),setTimeout(()=>K(null),2e3)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 transition-colors rounded-xl shadow-sm hover:text-emerald-500 cursor-pointer`,title:`Copy Link`,children:ee===`preview`?(0,i.jsx)(t.zi,{className:`w-4 h-4 text-emerald-500`}):(0,i.jsx)(t.ri,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),Z(M.id),ie(M.name)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 hover:text-accent transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Rename`,children:(0,i.jsx)(t.Kr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),O(M.id)},className:`p-2.5 bg-red-500/10 hover:bg-red-500/20 text-red-500 transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})}),(0,i.jsx)(`a`,{href:M.downloadURL,download:!0,target:`_blank`,rel:`noreferrer`,className:`p-2.5 btn-primary transition-colors rounded-xl shadow-lg ml-1`,title:`Download`,children:(0,i.jsx)(t.Si,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>j(null),children:(0,i.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[N&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,i.jsx)(`div`,{className:`w-12 h-12 rounded-full bg-background/80 backdrop-blur-md shadow-xl flex items-center justify-center border border-[var(--panel-border)]/50`,children:(0,i.jsx)(t.ti,{className:`w-5 h-5 text-accent animate-spin`})})}),M.fileType?.startsWith(`image/`)?(0,i.jsx)(`img`,{onLoad:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,alt:M.fileName||M.name,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full object-contain drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] rounded-lg pointer-events-auto transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType?.startsWith(`video/`)?(0,i.jsx)(`video`,{onLoadedData:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,controls:!0,autoPlay:!0,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full outline-none bg-black/40 rounded-lg pointer-events-auto drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType===`application/pdf`?(0,i.jsx)(`iframe`,{onLoad:()=>P(!1),src:M.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,i.jsxs)(`div`,{className:`w-full h-full flex flex-col items-center justify-center text-foreground/40 text-center relative z-10`,onClick:e=>{e.stopPropagation(),P(!1)},children:[(0,i.jsx)(t.gi,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,i.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,i.jsx)(`span`,{className:`text-[14px] mt-2 text-foreground/60 font-medium max-w-xs`,children:`This file format cannot be previewed. Please download it instead.`})]})]})})]})]})}),document.body),(0,i.jsx)(t.pr,{children:L&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>le(),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[440px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:(0,i.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),b&&(0,i.jsx)(t.ti,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>le(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NAME`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`input`,{autoFocus:!0,required:!0,value:z,onChange:e=>B(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>ue(),placeholder:`Name *`,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NOTE`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:V,onChange:e=>{H(e.target.value),e.target.style.height=`auto`,e.target.style.height=e.target.scrollHeight+`px`},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),e.target.blur())},onBlur:()=>ue(),placeholder:`Add a note...`,rows:1,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50 resize-none overflow-hidden`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),U.map((e,n)=>(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let t=[...U];t[n].key=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>ue(),className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none placeholder:text-foreground/15 pt-3 pb-0.5 caret-foreground/40`}),(0,i.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let t=[...U];t[n].value=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>ue(),className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pt-1.5 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>W(U.filter((e,t)=>t!==n)),className:`absolute top-3 right-0 p-1 text-foreground/0 group-hover/field:text-foreground/20 hover:!text-red-400 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})})]},n)),(0,i.jsxs)(`button`,{type:`button`,onClick:()=>W([...U,{key:``,value:``}]),className:`flex items-center gap-1.5 text-[11px] font-medium text-foreground/25 hover:text-foreground/40 transition-colors cursor-pointer mt-4 mb-4`,children:[(0,i.jsx)(t.Ur,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,i.jsx)(Ve,{isOpen:!!D,onCancel:()=>O(null),onConfirm:re,title:`Delete Record`,message:(0,i.jsxs)(i.Fragment,{children:[`Are you sure you want to delete `,(0,i.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:u.find(e=>e.id===D)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:F})]})}function ym({config:e,customContent:n}){let{user:a}=t.na(),{config:c}=t.ja(),[u,d]=(0,r.useState)([]),[f,p]=(0,r.useState)(!0),[m,h]=(0,r.useState)(!1),[g,_]=(0,r.useState)(``),[v,y]=(0,r.useState)(``),[b,x]=(0,r.useState)(!1),[S,C]=(0,r.useState)(null),w=(0,r.useRef)(null),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(null),[k,A]=(0,r.useState)(null),j=e=>{if(A(e),e){let t=e.fileType||``;P(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},M=k,[N,P]=(0,r.useState)(!0),[F,I]=(0,r.useState)(!1),[L,R]=(0,r.useState)(null),[z,B]=(0,r.useState)(``),[V,H]=(0,r.useState)(``),[U,W]=(0,r.useState)([]),G=(0,r.useRef)(null),[ee,K]=(0,r.useState)(null),q=(0,r.useRef)([]),J=`mem_${(e.tabName||e.pageId||`internal_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`)}_records`;(0,r.useEffect)(()=>{document.title=e.tabTitle||e.tabName||c.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,c.appName]),(0,r.useEffect)(()=>{if(!a)return;try{let e=Wa(J,a.uid);e?(d(e),p(!1)):p(!0)}catch{}let e=e=>e.map(e=>{let t=e.data();return{id:e.id,...t,createdAt:t.createdAt?.toMillis?t.createdAt.toMillis():t.createdAt}}),n=(0,o.onSnapshot)((0,o.query)((0,o.collection)(t.Da,J),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(150)),t=>{let n=e(t.docs);d(n),p(!1),Ga(J,a.uid,n)},n=>{console.error(`Error listening to shared records:`,n);let r=(0,o.onSnapshot)((0,o.query)((0,o.collection)(t.Da,J),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),d(n),p(!1),Ga(J,a.uid,n)});return()=>r()});return()=>n()},[a,J]);let Y=()=>({name:a.displayName||a.email?.split(`@`)[0]||`Member`,email:a.email||``,avatar:a.photoURL||``}),te=async e=>{if(e.preventDefault(),!(!a||!g.trim())){x(!0);try{let e=Y();await(0,o.addDoc)((0,o.collection)(t.Da,J),{name:g.trim(),note:v.trim(),uid:a.uid,recordType:`record`,creatorName:e.name,creatorEmail:e.email,creatorAvatar:e.avatar,createdAt:(0,o.serverTimestamp)()}),_(``),y(``),h(!1)}catch(e){console.error(`Error saving shared record:`,e)}x(!1)}},ne=async e=>{let n=e.target.files?.[0];if(!n||!a)return;let r=await t.or(n);E(!0);try{let e=`mem_files/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,n=(0,s.ref)(t.ka,e);await(0,s.uploadBytes)(n,r,{customMetadata:{ownerId:a.uid}});let i=await(0,s.getDownloadURL)(n);if(w.current)w.current(r,i,{uid:a.uid,storagePath:e});else{let e=Y();await(0,o.addDoc)((0,o.collection)(t.Da,J),{name:r.name,note:`${r.type||`File`} · ${me(r.size)}`,uid:a.uid,recordType:`file`,fileName:r.name,fileType:r.type||`unknown`,fileSize:r.size,downloadURL:i,creatorName:e.name,creatorEmail:e.email,creatorAvatar:e.avatar,createdAt:(0,o.serverTimestamp)()})}}catch(e){console.error(`Error uploading shared file:`,e)}E(!1),G.current&&(G.current.value=``)},re=async()=>{if(D){I(!0);try{let e=u.find(e=>e.id===D);if(await(0,o.deleteDoc)((0,o.doc)(t.Da,J,D)),e?.recordType===`file`&&e.downloadURL)try{let n=e.downloadURL.split(`mem_files%2F`)[1]?.split(`?`)[0];n&&await(0,s.deleteObject)((0,s.ref)(t.ka,`mem_files/${decodeURIComponent(n)}`)).catch(()=>{})}catch(e){console.error(`Error cleaning up shared file:`,e)}O(null)}catch(e){console.error(`Error deleting shared record:`,e)}I(!1)}},[X,Z]=(0,r.useState)(null),[Q,ie]=(0,r.useState)(``),[ae,oe]=(0,r.useState)(!1),se=e=>{if(e.recordType===`file`){Z(e.id),ie(e.name);return}R(e.id),B(e.name),H(e.note||``);let t=[`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`createdAt`,`creatorName`,`creatorEmail`,`creatorAvatar`],n=Object.entries(e).filter(([e])=>!t.includes(e)&&e!==`id`).map(([e,t])=>({key:e,value:String(t??``)}));W(n),q.current=n.map(e=>e.key)},ce=async()=>{if(!X||!Q.trim()){Z(null);return}let e=u.find(e=>e.id===X);if(e&&e.name===Q.trim()){Z(null);return}oe(!0);try{await(0,o.updateDoc)((0,o.doc)(t.Da,J,X),{name:Q.trim()}),d(e=>e.map(e=>e.id===X?{...e,name:Q.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}oe(!1),Z(null)},le=async()=>{await ue(),R(null)},ue=async()=>{if(!L||!z.trim())return;x(!0);let e={};U.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let n=U.map(e=>e.key.trim()).filter(Boolean),r=q.current.filter(e=>!n.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(t.Da,J,L),{name:z.trim(),note:V.trim(),...e}),d(e=>e.map(e=>{if(e.id!==L)return e;let t={...e,name:z.trim(),note:V.trim()};return r.forEach(e=>{delete t[e]}),U.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),q.current=n}catch(e){console.error(`Error saving record:`,e)}x(!1)},de=(e,n)=>e?e.startsWith(`image/`)?n?(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${n})`}}):(0,i.jsx)(t.fi,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,i.jsx)(t.br,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,i.jsx)(t.gi,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,i.jsx)(t.ea,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,i.jsx)(t.Ei,{className:`w-4 h-4`}):(0,i.jsx)(t.hi,{className:`w-4 h-4`}):(0,i.jsx)(t.gi,{className:`w-4 h-4`}),fe=e=>e?e.startsWith(`image/`)?`bg-emerald-500/10 text-emerald-500`:e.startsWith(`video/`)||e.startsWith(`audio/`)?`bg-accent/10 text-accent`:e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?`bg-blue-500/10 text-blue-500`:e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?`bg-yellow-500/10 text-yellow-500`:e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?`bg-emerald-500/10 text-emerald-500`:`bg-foreground/5 text-foreground/40`:`bg-foreground/5 text-foreground/40`,pe=e=>{if(!e)return`FILE`;let t={"application/pdf":`PDF`,"application/zip":`ZIP`,"application/x-zip-compressed":`ZIP`,"application/x-rar-compressed":`RAR`,"application/x-7z-compressed":`7Z`,"application/json":`JSON`,"application/xml":`XML`,"application/javascript":`JS`,"application/typescript":`TS`,"application/msword":`DOC`,"application/vnd.openxmlformats-officedocument.wordprocessingml.document":`DOCX`,"application/vnd.ms-excel":`XLS`,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":`XLSX`,"application/vnd.ms-powerpoint":`PPT`,"application/vnd.openxmlformats-officedocument.presentationml.presentation":`PPTX`,"application/rtf":`RTF`,"application/x-tar":`TAR`,"application/gzip":`GZ`,"text/plain":`TXT`,"text/html":`HTML`,"text/css":`CSS`,"text/csv":`CSV`,"text/markdown":`MD`},n=e.toLowerCase();if(t[n])return t[n];let r=n.split(`/`);return r[r.length-1].replace(/^x-/,``).replace(/^vnd\..*\./,``).toUpperCase().slice(0,10)},me=e=>{if(!e)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**+r).toFixed(2))+` `+n[r]},he=e=>{if(!e)return``;let t=e.toMillis?e.toMillis():e;return new Date(t).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})},ge=(()=>{let n=(e.buttonStorageIcon||`upload`).trim(),r=n.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return t.mr[r]?t.mr[r]:t.mr[n]?t.mr[n]:t.wr||t.Ur})(),_e=e.buttonStyle!==`secondary`,ve=e.buttonStorageStyle===`primary`,ye=e=>e.uid===a?.uid,be=({record:e})=>{let t=e.creatorName||e.creatorEmail?.split(`@`)[0]||`Member`,n=e.creatorEmail||``,r=e.creatorAvatar||``,a=t.split(` `).map(e=>e[0]).join(``).toUpperCase().slice(0,2);return(0,i.jsxs)(`div`,{className:`flex items-center gap-2 mt-2 pt-2 border-t border-[var(--panel-border)]/30`,children:[r?(0,i.jsx)(`img`,{src:r,alt:``,className:`w-5 h-5 rounded-full object-cover shrink-0`}):(0,i.jsx)(`div`,{className:`w-5 h-5 rounded-full bg-accent/15 text-accent flex items-center justify-center text-[8px] font-extrabold shrink-0`,children:a}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 truncate`,children:t}),n&&(0,i.jsxs)(`span`,{className:`text-[10px] text-foreground/25 truncate`,children:[`· `,n]})]})]})};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(Ce,{children:e.tabTitle||e.tabName||`Internal Page`}),e.route&&(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background`,children:[(0,i.jsx)(`input`,{type:`file`,ref:G,onChange:ne,className:`hidden`}),!n&&(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4 p-4 sm:p-6 md:px-8 md:py-6 border-b border-[var(--panel-border)]/50 bg-background/50 shrink-0`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:f?`Loading…`:`${u.length} ${u.length===1?`item`:`items`} · Internal`})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,i.jsx)(i.Fragment,{children:(0,i.jsxs)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>G.current?.click(),disabled:T,title:e.buttonStorageText||`Upload File`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed ${e.buttonStorageText?`px-4`:`w-10`} ${ve?`btn-primary`:`btn-secondary`}`,children:[T?(0,i.jsx)(t.ti,{className:`w-4 h-4 animate-spin`}):(0,i.jsx)(ge,{className:`w-4 h-4`}),e.buttonStorageText&&(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>h(!0),title:`Add New`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer ${e.buttonText&&e.buttonText!==`+`?`px-5`:`w-10`} ${_e?`btn-primary`:`btn-secondary`}`,children:e.buttonText===`+`||!e.buttonText?(0,i.jsx)(t.Ur,{className:`w-4 h-4`}):(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,i.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[f&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,i.jsx)(t.ti,{className:`w-8 h-8 text-accent animate-spin`})}),n?(0,i.jsx)(`div`,{className:`fbos-content-slot`,children:(0,i.jsx)(n,{config:e,actions:{records:u,loading:f,collection:J,user:a,saveRecord:async e=>{let n=(0,o.doc)((0,o.collection)(t.Da,J)),r=Y(),i={id:n.id,uid:a.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:Date.now(),...e};d(e=>[i,...e]),await(0,o.setDoc)(n,{uid:a.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,n)=>{d(t=>t.map(t=>t.id===e?{...t,...n}:t)),await(0,o.updateDoc)((0,o.doc)(t.Da,J,e),n)},deleteRecord:async e=>{await(0,o.deleteDoc)((0,o.doc)(t.Da,J,e))},startEdit:e=>se(e),confirmDelete:e=>O(e),uploadFile:()=>G.current?.click(),openAddForm:()=>h(!0),setAddForm:e=>C(()=>e),setFileHandler:e=>{w.current=e}}})}):(0,i.jsxs)(i.Fragment,{children:[!f&&u.length===0&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex-1 flex flex-col items-center justify-center border border-[var(--panel-border)]/50 border-dashed rounded-2xl p-8 py-20 text-center min-h-[350px]`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-2xl bg-accent/5 border border-accent/10 flex items-center justify-center mb-5`,children:(0,i.jsx)(t.Ur,{className:`w-6 h-6 text-accent/40`})}),(0,i.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/35 max-w-xs leading-relaxed`,children:`Use the buttons above to add records or upload files. All team members can view and contribute.`})]}),!f&&u.length>0&&(0,i.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,i.jsx)(t.pr,{children:u.map(e=>{let n=L===e.id,r=ye(e);return(0,i.jsxs)(t.fr.div,{initial:!1,animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},onClick:()=>r?se(e):null,className:`group flex flex-col bg-background border rounded-2xl p-5 transition-all relative ${r?`cursor-pointer`:``} ${n?`border-accent/40 shadow-lg ring-1 ring-accent/20`:`border-[var(--panel-border)] hover:border-accent/30 hover:shadow-lg`}`,children:[(0,i.jsxs)(`div`,{className:`absolute top-3 right-3 flex items-center gap-0.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-all z-10`,children:[e.recordType===`file`&&e.downloadURL&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),K(e.id),setTimeout(()=>K(null),2e3)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-emerald-500 hover:bg-emerald-500/10 transition-all cursor-pointer`,title:`Copy Link`,children:ee===e.id?(0,i.jsx)(t.zi,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,i.jsx)(t.ri,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`a`,{href:e.downloadURL,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),className:`p-1.5 rounded-lg text-foreground/25 hover:text-blue-500 hover:bg-blue-500/10 transition-all`,title:`Download`,children:(0,i.jsx)(t.Si,{className:`w-3.5 h-3.5`})})]}),r&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),se(e)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-accent hover:bg-accent/10 transition-all cursor-pointer`,title:`Edit`,children:(0,i.jsx)(t.Kr,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),O(e.id)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-red-500 hover:bg-red-500/10 transition-all cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-3.5 h-3.5`})})]})]}),(0,i.jsxs)(`div`,{className:`flex items-start gap-3 mb-2`,children:[(0,i.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&j(e)},className:`w-9 h-9 rounded-xl flex items-center justify-center shrink-0 ${e.recordType===`file`?`cursor-pointer hover:scale-105 transition-transform ${fe(e.fileType)}`:`bg-accent/10 text-accent`}`,children:e.recordType===`file`?de(e.fileType,e.downloadURL):(0,i.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[X===e.id?(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,value:Q,onChange:e=>ie(e.target.value),onBlur:()=>ce(),onKeyDown:e=>{e.key===`Enter`&&ce(),e.key===`Escape`&&Z(null)},onClick:e=>e.stopPropagation(),className:`no-glow text-[14px] font-bold text-foreground bg-transparent border-b border-accent/30 outline-none pb-0.5 w-full pr-12`}):(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>j(e)}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:he(e.createdAt)})]})]}),e.note&&(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/55 font-medium leading-relaxed line-clamp-3 mb-1`,children:e.note}),Object.entries(e).filter(([e])=>![`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`createdAt`,`creatorName`,`creatorEmail`,`creatorAvatar`].includes(e)&&e!==`id`).slice(0,3).map(([e,t])=>(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,i.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e)),(0,i.jsx)(be,{record:e})]},e.id)})})})]})]})]})]}),(0,i.jsx)(t.pr,{children:m&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>!b&&h(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[360px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:S?r.default.createElement(S,{onSave:async e=>{x(!0);try{let n=Y();await(0,o.addDoc)((0,o.collection)(t.Da,J),{uid:a.uid,recordType:`record`,creatorName:n.name,creatorEmail:n.email,creatorAvatar:n.avatar,createdAt:(0,o.serverTimestamp)(),...e}),h(!1)}catch(e){console.error(`Error saving record:`,e)}x(!1)},onClose:()=>!b&&h(!1),saving:b}):(0,i.jsxs)(`form`,{onSubmit:te,className:`p-5 flex flex-col gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>!b&&h(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:g,onChange:e=>_(e.target.value),placeholder:`Name *`,disabled:b,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-semibold text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`textarea`,{value:v,onChange:e=>y(e.target.value),placeholder:`Note (optional)`,disabled:b,rows:2,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-medium text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30 resize-none`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,i.jsx)(t.cr,{type:`submit`,isLoading:b,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:b?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,l.createPortal)((0,i.jsx)(t.pr,{children:M&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>j(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(`button`,{onClick:()=>j(null),className:`absolute top-6 right-6 z-[160] w-12 h-12 bg-foreground/10 hover:bg-foreground/20 text-foreground rounded-full flex items-center justify-center backdrop-blur-md transition-all cursor-pointer outline-none`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`relative z-10 w-full max-w-6xl max-h-[85vh] flex flex-col pointer-events-auto shadow-2xl rounded-3xl overflow-hidden glass-panel border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between p-6 bg-background/80 backdrop-blur-md border-b border-[var(--panel-border)] shrink-0 shadow-sm z-20`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,i.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:M.fileName||M.name}),(0,i.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[pe(M.fileType),` • `,me(M.fileSize||0)]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(M.downloadURL),K(`preview`),setTimeout(()=>K(null),2e3)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 transition-colors rounded-xl shadow-sm hover:text-emerald-500 cursor-pointer`,title:`Copy Link`,children:ee===`preview`?(0,i.jsx)(t.zi,{className:`w-4 h-4 text-emerald-500`}):(0,i.jsx)(t.ri,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),Z(M.id),ie(M.name)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 hover:text-accent transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Rename`,children:(0,i.jsx)(t.Kr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),O(M.id)},className:`p-2.5 bg-red-500/10 hover:bg-red-500/20 text-red-500 transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})}),(0,i.jsx)(`a`,{href:M.downloadURL,download:!0,target:`_blank`,rel:`noreferrer`,className:`p-2.5 btn-primary transition-colors rounded-xl shadow-lg ml-1`,title:`Download`,children:(0,i.jsx)(t.Si,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>j(null),children:(0,i.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[N&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,i.jsx)(`div`,{className:`w-12 h-12 rounded-full bg-background/80 backdrop-blur-md shadow-xl flex items-center justify-center border border-[var(--panel-border)]/50`,children:(0,i.jsx)(t.ti,{className:`w-5 h-5 text-accent animate-spin`})})}),M.fileType?.startsWith(`image/`)?(0,i.jsx)(`img`,{onLoad:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,alt:M.fileName||M.name,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full object-contain drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] rounded-lg pointer-events-auto transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType?.startsWith(`video/`)?(0,i.jsx)(`video`,{onLoadedData:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,controls:!0,autoPlay:!0,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full outline-none bg-black/40 rounded-lg pointer-events-auto drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType===`application/pdf`?(0,i.jsx)(`iframe`,{onLoad:()=>P(!1),src:M.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,i.jsxs)(`div`,{className:`w-full h-full flex flex-col items-center justify-center text-foreground/40 text-center relative z-10`,onClick:e=>{e.stopPropagation(),P(!1)},children:[(0,i.jsx)(t.gi,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,i.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,i.jsx)(`span`,{className:`text-[14px] mt-2 text-foreground/60 font-medium max-w-xs`,children:`This file format cannot be previewed. Please download it instead.`})]})]})})]})]})}),document.body),(0,i.jsx)(t.pr,{children:L&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>le(),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[440px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:(0,i.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),b&&(0,i.jsx)(t.ti,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>le(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NAME`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`input`,{autoFocus:!0,required:!0,value:z,onChange:e=>B(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>ue(),placeholder:`Name *`,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NOTE`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:V,onChange:e=>{H(e.target.value),e.target.style.height=`auto`,e.target.style.height=e.target.scrollHeight+`px`},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),e.target.blur())},onBlur:()=>ue(),placeholder:`Add a note...`,rows:1,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50 resize-none overflow-hidden`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),U.map((e,n)=>(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let t=[...U];t[n].key=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>ue(),className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none placeholder:text-foreground/15 pt-3 pb-0.5 caret-foreground/40`}),(0,i.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let t=[...U];t[n].value=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>ue(),className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pt-1.5 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>W(U.filter((e,t)=>t!==n)),className:`absolute top-3 right-0 p-1 text-foreground/0 group-hover/field:text-foreground/20 hover:!text-red-400 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})})]},n)),(0,i.jsxs)(`button`,{type:`button`,onClick:()=>W([...U,{key:``,value:``}]),className:`flex items-center gap-1.5 text-[11px] font-medium text-foreground/25 hover:text-foreground/40 transition-colors cursor-pointer mt-4 mb-4`,children:[(0,i.jsx)(t.Ur,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,i.jsx)(Ve,{isOpen:!!D,onCancel:()=>O(null),onConfirm:re,title:`Delete Record`,message:(0,i.jsxs)(i.Fragment,{children:[`Are you sure you want to delete `,(0,i.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:u.find(e=>e.id===D)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:F})]})}var bm=[`board`,`table`,`calendar`,`drive`],xm=[`inline_form`,`popup_form`],Sm=e=>typeof e!=`string`||e===``||e===`none`||e===`custom`||![...bm,...xm].includes(e),Cm=(e,t)=>Sm(e)||t&&!wm(e),wm=e=>typeof e==`string`&&bm.includes(e),Tm=`/src/your-ai-workflow-firebase-os/microcomponents`,Em=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``),Dm=e=>{let t=e.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();return[t,t.replace(/_/g,``)]},Om=e=>{let t=[e?.contentKey,e?.tabName,e?.pageId,e?.pageName].filter(e=>typeof e==`string`&&e.trim()).map(e=>Em(e)).filter(Boolean);return[...new Set(t)].map(e=>`${e}Content.tsx`)},km=e=>{if(typeof window>`u`)return!1;let t=window.__FBOS_MICROCOMPONENTS__;if(!t)return!1;let n=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`_`).replace(/^_|_$/g,``);return[e?.contentKey,e?.tabName,e?.pageId,e?.pageName].filter(e=>typeof e==`string`&&e.trim()).some(e=>t[n(e)])},Am=new Map,jm=e=>{let t=Am.get(e);return t||(t=import(`${Tm}/${e}`).then(e=>typeof e?.default==`function`||typeof e?.default==`object`?e.default:null).catch(()=>null),Am.set(e,t)),t};async function Mm(e){if(typeof window>`u`||km(e))return null;for(let t of Om(e)){let e=await jm(t);if(!e)continue;let[n,r]=Dm(t.replace(/Content\.tsx$/,``)),i=window.__FBOS_MICROCOMPONENTS__||{};return window.__FBOS_MICROCOMPONENTS__={[n]:e,[r]:e,...i},e}return null}var Nm=(e,n)=>{let r=n?t._a(e.pageType):`public`;return{...e,pageType:r,isPrivate:n,isAdmin:r===`admin`,isInternal:r===`internal`,isShared:r===`internal`}};function Pm(){let e=(0,c.useLocation)(),{user:n,userRole:a,loading:s,roleResolved:l,userInactive:u,signOut:d}=t.na(),f=t.Na(),p=e=>{if(typeof window<`u`){let t=localStorage.getItem(`fbos_route_${e}`);if(t)try{let e=JSON.parse(t);if(e.form&&!e.formConfigOverride){let t=localStorage.getItem(`fbos_form_${e.form}`);t&&(e.formConfigOverride=JSON.parse(t))}return Nm(e,e.isPrivate===!0)}catch{}}let n=(typeof window<`u`?window.__FBOS_PAGES__:null)||{},r=e.replace(/^\//,``);for(let[t,i]of Object.entries(n)){let n=i.config,a=i.isPublic,o=n.route||`/`+t;if(o===e||t===r)return Nm({...n,route:o,contentKey:n.pageId||t,pageId:t},!a)}return e===`/contact`?{route:`/contact`,template:`popup_form`,form:`contact`,pageId:`contact`,contentKey:`contact`,pageName:`Contact`,formConfigOverride:f.defaultConfigs?.contactForm||t.La}:e===`/support`?{route:`/support`,template:`popup_form`,form:`support`,pageId:`support`,contentKey:`support`,pageName:`Support`,formConfigOverride:f.defaultConfigs?.supportForm||t.Fa}:null},[m,h]=(0,r.useState)(()=>p(e.pathname)),[g,_]=(0,r.useState)(()=>!p(e.pathname));(0,r.useEffect)(()=>{let n=!0,r=p(e.pathname);if(r){h(r),_(!1);let e=r.pageName||r.tabName||r.title;e&&(document.title=e)}return(async()=>{try{let r=e.pathname;r.startsWith(`/`)&&(r=r.substring(1));let[i,a,s,c,l,u]=await Promise.allSettled([(0,o.getDoc)((0,o.doc)(t.Da,`sys_pages`,r)),(0,o.getDoc)((0,o.doc)(t.Da,`sys_tabs`,r)),(0,o.getDocs)((0,o.query)((0,o.collection)(t.Da,`sys_pages`),(0,o.where)(`route`,`==`,e.pathname),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(t.Da,`sys_pages`),(0,o.where)(`route`,`==`,r),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(t.Da,`sys_tabs`),(0,o.where)(`route`,`==`,e.pathname),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(t.Da,`sys_tabs`),(0,o.where)(`route`,`==`,r),(0,o.limit)(1)))]),d=null,p=null,m=(e,t)=>{d||e.status===`fulfilled`&&(e.value.exists&&e.value.exists()?(d=Nm(e.value.data(),t),p=e.value.id):e.value.docs&&e.value.docs.length>0&&(d=Nm(e.value.docs[0].data(),t),p=e.value.docs[0].id))};if(m(i,!1),m(s,!1),m(c,!1),m(a,!0),m(l,!0),m(u,!0),!d){let t=(typeof window<`u`?window.__FBOS_PAGES__:null)||{};for(let[n,i]of Object.entries(t)){let t=i.config,a=i.isPublic,o=t.route||`/`+n;if(o===e.pathname||n===r){d=Nm({...t,route:o,contentKey:t.pageId||n,pageId:n},!a),p=n;break}}}if(d||(e.pathname===`/contact`?(d={route:`/contact`,template:`popup_form`,form:`contact`,pageName:`Contact`},p=`contact`):e.pathname===`/support`&&(d={route:`/support`,template:`popup_form`,form:`support`,pageName:`Support`},p=`support`)),!n)return;if(d){if((p===`contact`||p===`support`)&&!d.form&&(d.form=p),d.contentKey||=d.pageId||p,d.pageId=p,localStorage.setItem(`fbos_route_${e.pathname}`,JSON.stringify(d)),d.form){let e=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},r=n=>f.defaultConfigs?.[n]||f.defaultConfigs?.[`${n}Form`]||e[n]||(n===`contact`?t.La:n===`support`?t.Fa:null);if(localStorage.getItem(`fbos_custom_form_${d.form}`)){try{let e=localStorage.getItem(`fbos_form_${d.form}`);e&&(d.formConfigOverride=JSON.parse(e))}catch{}(0,o.getDoc)((0,o.doc)(t.Da,`sys_forms`,d.form)).then(async e=>{if(n)if(e.exists()){let t={...e.data(),id:e.id};h(e=>({...e,formConfigOverride:t})),localStorage.setItem(`fbos_form_${d.form}`,JSON.stringify(t))}else{let e=r(d.form);e&&(h(t=>({...t,formConfigOverride:e})),localStorage.setItem(`fbos_form_${d.form}`,JSON.stringify(e)),localStorage.removeItem(`fbos_custom_form_${d.form}`))}})}else{let e=r(d.form);e&&(d.formConfigOverride=e)}}let r=d.pageName||d.tabName||d.title;r&&(document.title=r),h(d),_(!1)}else h(`not-found`),_(!1),localStorage.removeItem(`fbos_route_${e.pathname}`)}catch{n&&g&&(h(`not-found`),_(!1))}})(),()=>{n=!1}},[e.pathname]);let[v,y]=(0,r.useState)(!1),[b,x]=(0,r.useState)(null),[S,C]=(0,r.useState)(!1),w=m&&m!==`not-found`&&typeof m==`object`?[m.contentKey,m.tabName,m.pageId,m.pageName].filter(Boolean).join(`|`):``;if((0,r.useEffect)(()=>{if(x(null),!w||km(m)){C(!1);return}let e=!1;C(!0),Mm(m).then(t=>{e||(t&&x(()=>t),C(!1))});let t=setTimeout(()=>{e||C(!1)},4e3);return()=>{e=!0,clearTimeout(t)}},[w]),(0,r.useEffect)(()=>{let e;return g||s||!l||S?e=setTimeout(()=>y(!0),150):y(!1),()=>clearTimeout(e)},[g,s,l,S]),g||s||!l||S)return v?n?(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(`div`,{className:`mb-6`,children:[(0,i.jsx)(`div`,{className:`h-10 w-56 rounded-xl bg-foreground/5 animate-pulse mt-1`}),(0,i.jsx)(`div`,{className:`h-3 w-24 rounded bg-foreground/5 animate-pulse mt-3`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsx)(`div`,{className:`flex-1 glass-panel border border-[var(--panel-border)] rounded-3xl flex items-center justify-center min-h-[400px] bg-background shadow-2xl`,children:(0,i.jsx)(t.ti,{className:`w-6 h-6 animate-spin text-accent`})})]})]}):(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center min-h-[40vh] z-10`,children:(0,i.jsxs)(`div`,{className:`p-4 rounded-2xl glass-panel border border-[var(--panel-border)]/40 bg-background/80 shadow-md flex items-center gap-3`,children:[(0,i.jsx)(t.ti,{className:`w-4 h-4 animate-spin text-accent`}),(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/60 tracking-wide`,children:`Loading page...`})]})}):null;if(m===`not-found`)return(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center flex-1 text-center`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 bg-red-500/10 text-red-500 rounded-full flex items-center justify-center mb-6`,children:(0,i.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`w-8 h-8`,children:[(0,i.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,i.jsx)(`line`,{x1:`12`,y1:`8`,x2:`12`,y2:`12`}),(0,i.jsx)(`line`,{x1:`12`,y1:`16`,x2:`12.01`,y2:`16`})]})}),(0,i.jsx)(`h2`,{className:`text-2xl sm:text-3xl font-bold mb-3 text-foreground`,children:`Page Not Found`}),(0,i.jsx)(`p`,{className:`text-foreground/60 max-w-md`,children:`The route you are looking for does not exist or has been removed.`}),t.pa(a)&&(()=>{let t=dm();return(0,i.jsxs)(`div`,{className:`mt-8 w-full max-w-lg text-left flex flex-col gap-4`,children:[(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)] px-5 py-4`,children:[(0,i.jsx)(`p`,{className:`text-[12px] font-extrabold tracking-tight text-gradient mb-1.5`,children:`Pages the app can see`}),(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/70 font-medium leading-relaxed`,children:t.length?t.join(` · `):`None yet. If your assistant says it created a page, the app has not picked its file up.`})]}),(0,i.jsx)(it,{title:`If your assistant just made this page, paste this`,prompt:hm(e.pathname)})]})})()]})});if((m.pageId===`support`||m.isPrivate)&&!n)return(0,i.jsx)(c.Navigate,{to:`/login?from=${encodeURIComponent(e.pathname)}`,replace:!0});if((m.pageId===`support`||m.isPrivate)&&n&&u)return(0,i.jsx)(yi,{tone:`red`,title:`Access Denied`,message:`You don't have access to this app. Please contact the administrator.`,action:(0,i.jsx)(`button`,{onClick:()=>d(),className:bi,children:`Sign Out`})});if((m.pageId===`support`||m.isPrivate)&&n&&!n.emailVerified)return(0,i.jsx)(c.Navigate,{to:`/verify`,replace:!0});if(m.isPrivate&&!t.ua(a,m))return(0,i.jsx)(Ci,{});let T=f.customRoutes?.[e.pathname]||(m&&m.route?f.customRoutes?.[m.route]:null),E=m.pageName?.toLowerCase().replace(/\s+/g,`_`)||m.pageId||`custom_page`,D=`pub_${E}`,O=m.isPrivate?`${t.va(m)}${m.pageId||E}`:D,k=f.microcomponents||(typeof window<`u`?window.__FBOS_MICROCOMPONENTS__:void 0),A=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`_`).replace(/^_|_$/g,``),j=[m.contentKey,m.tabName,m.pageId,m.pageName,m.pageName?.replace(/\s+/g,`_`)].filter(Boolean).map(e=>A(e)).reduce((e,t)=>e||k?.[t],void 0),M=T||j||b||void 0,N=m.route||m.pageId||`custom`;return Cm(m.template,!!M)?m.isAdmin?(0,i.jsx)(vm,{config:m,customContent:M},N):m.isInternal?(0,i.jsx)(ym,{config:m,customContent:M},N):m.isPrivate?(0,i.jsx)(_m,{config:m,customContent:M},N):(0,i.jsx)(gm,{config:m,customContent:M},N):m.template===`board`?(0,i.jsx)(f.components?.TemplateBoard||vn,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Board`,subtitle:m.route,tasksCollection:`${O}_tasks`,categoriesCollection:`${O}_categories`,config:m,customContent:M},N):m.template===`table`?(0,i.jsx)(f.components?.TemplateTable||qr,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Table`,subtitle:m.route,tableCollection:`${O}_table`,config:m,customContent:M},N):m.template===`calendar`?(0,i.jsx)(f.components?.TemplateCalendar||Xr,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Calendar`,subtitle:m.route,eventsCollection:`${O}_events`,defaultTimeFormat:m.defaultTimeFormat||m.defaulttimeformat||`12h`,config:m,customContent:M},N):m.template===`drive`?(0,i.jsx)(f.components?.TemplateDrive||Kt,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Drive`,subtitle:m.route,filesCollection:`${O}_files`,config:m,customContent:M},N):m.template===`inline_form`?(0,i.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-start mt-8 relative z-10 w-full min-h-[60vh]`,children:(0,i.jsx)(t.t,{isInline:!0,formId:m.form,formConfig:m.formConfigOverride})}):(0,i.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-center relative z-10 w-full min-h-[60vh]`,children:(0,i.jsx)(t.t,{formId:m.form,formConfig:m.formConfigOverride,onClose:()=>window.history.back()})})}var Fm=e=>e.error?`error`:e.paid?`paid`:`unpaid`,Im={checking:{icon:t.Oi,tint:`text-accent`,title:`Checking your payment…`},paid:{icon:t.Ni,tint:`text-emerald-400`,title:`Thank you — payment received`},unpaid:{icon:t.Oi,tint:`text-amber-400`,title:`Not confirmed yet`},error:{icon:t.Pi,tint:`text-red-400`,title:`We could not confirm this payment`},cancelled:{icon:t.Ai,tint:`text-foreground/50`,title:`Payment cancelled`}};function Lm({cancelled:e=!1}){let[n]=(0,c.useSearchParams)(),a=n.get(`session_id`)||``,[o,s]=(0,r.useState)(`checking`),[l,u]=(0,r.useState)(null);(0,r.useEffect)(()=>{if(e)return;let t=!1;return ee(a).then(e=>{t||(u(e),s(Fm(e)))}),()=>{t=!0}},[e,a]);let d=async()=>{s(`checking`);let e=await ee(a);u(e),s(Fm(e))},f=Im[e?`cancelled`:o],p=f.icon;return(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mb-16`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.5},className:`w-full max-w-[480px] p-6 md:p-8 lg:p-10 rounded-3xl glass-panel relative glow-hover text-center shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-30 blur-[20px] rounded-3xl -z-10`}),(0,i.jsx)(`div`,{className:`w-14 h-14 md:w-16 md:h-16 rounded-2xl glass-panel border border-[var(--panel-border)] flex items-center justify-center mx-auto mb-5 md:mb-6 shadow-xl`,children:(0,i.jsx)(p,{className:`w-7 h-7 md:w-8 md:h-8 ${f.tint} ${!e&&o===`checking`?`animate-pulse`:``}`})}),(0,i.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold mb-3 text-foreground tracking-tight`,children:f.title}),(0,i.jsxs)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/60 mb-6 md:mb-8 leading-[1.6] tracking-wide`,children:[e&&(0,i.jsx)(`p`,{children:`Nothing was charged. You can try again whenever you like.`}),!e&&o===`checking`&&(0,i.jsx)(`p`,{children:`One moment — confirming with the payment provider.`}),!e&&o===`paid`&&(0,i.jsxs)(`p`,{children:[l?.amountTotal!=null&&l?.currency?`Your payment of ${l.amountTotal} ${l.currency.toUpperCase()} went through.`:`Your payment went through.`,l?.customerEmail?` A receipt is on its way to ${l.customerEmail}.`:``]}),!e&&o===`unpaid`&&(0,i.jsx)(`p`,{children:`The payment provider has not confirmed this payment yet. Some payment methods take a minute — check again shortly, and look for a receipt in your email.`}),!e&&o===`error`&&(0,i.jsxs)(`p`,{children:[l?.error,` If you completed the payment, check your email for a receipt — if one arrived, your payment went through and you can safely close this page.`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 max-w-[360px] mx-auto`,children:[!e&&(o===`unpaid`||o===`error`)&&(0,i.jsx)(t.cr,{variant:`primary`,onClick:d,className:`w-full py-2.5 md:py-3 text-[14px] font-bold tracking-wide rounded-xl`,children:`Check again`}),(0,i.jsx)(c.Link,{to:`/`,className:`w-full block py-2.5 md:py-3 bg-foreground/5 hover:bg-foreground/10 text-foreground text-[14px] font-bold rounded-xl transition-colors`,children:`Back to the site`})]})]})})}function Rm({children:e,className:n,variant:a=`secondary`}){let{loading:o,configured:s}=Y(),[c,l]=(0,r.useState)(!1),[u,d]=(0,r.useState)(null);return o||!s?null:(0,i.jsxs)(`span`,{className:`inline-flex flex-col items-stretch gap-2`,children:[(0,i.jsx)(t.cr,{variant:a,className:n,onClick:async()=>{if(c)return;l(!0),d(null);let e=await G();e&&(d(e),l(!1))},disabled:c,children:c?`Opening…`:e??`Manage plan`}),u&&(0,i.jsx)(`span`,{role:`alert`,className:`text-[13px] font-semibold text-red-400 leading-snug`,children:u})]})}function zm(e){return e.status===`past_due`?{label:`Past due`,tone:`bad`}:e.active?{label:`Active`,tone:`good`}:{label:`Cancelled`,tone:`quiet`}}function Bm(e){if(!e.currentPeriodEnd||!e.active)return``;let t=new Date(e.currentPeriodEnd*1e3).toLocaleDateString(void 0,{day:`numeric`,month:`short`,year:`numeric`});return e.cancelAtPeriodEnd?`Ends on ${t}`:`Renews on ${t}`}function Vm({payment:e}){let n=Gd({kind:`charge`,email:null,name:null,...e});return(0,i.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${t.X}`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.description||`One-off payment`}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/45 font-medium truncate`,children:Jd(e.created)})]}),(0,i.jsx)(`span`,{className:`text-[12.5px] font-semibold text-foreground/70 whitespace-nowrap shrink-0`,children:Kd(e.amount,e.currency)}),(0,i.jsx)(Yd,{label:n.label,tone:n.tone})]})}function Hm({sub:e}){let n=zm(e),r=Bm(e);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 px-3.5 py-3 ${t.X}`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.productName||`Subscription`}),(0,i.jsxs)(`span`,{className:`text-[11px] text-foreground/45 font-medium truncate`,children:[Kd(e.amount,e.currency),e.interval?` / ${e.interval}`:``,r?` — ${r}`:``]})]}),(0,i.jsx)(Yd,{label:n.label,tone:n.tone})]}),(0,i.jsx)(Rm,{className:`self-start`})]})}function Um(){let{user:e}=t.na(),{loading:n,subscriptions:r,payments:a,error:o}=te(),s=!n&&!o&&r.length===0&&a.length===0;return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(Ce,{children:`Billing`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/billing`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col min-h-[400px]`,children:n?(0,i.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,i.jsx)(t.ti,{className:`w-6 h-6 animate-spin text-accent`})}):o?(0,i.jsx)(`p`,{className:`text-[12.5px] font-medium leading-relaxed px-1 text-red-500`,children:o}):s?(0,i.jsx)(t.at,{icon:t.Vr,title:`Nothing here yet`,description:`No payments have been made on this account.`,collapsible:!1,children:(0,i.jsxs)(`p`,{className:`text-[12.5px] font-medium leading-relaxed px-1 text-foreground/50`,children:[`Nothing has been bought on this account’s email`,e?.email?(0,i.jsxs)(i.Fragment,{children:[` (`,(0,i.jsx)(`strong`,{children:e.email}),`)`]}):null,`. A payment made with a different email address at checkout lives with that email — sign in with the address you paid with to see it here.`]})}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[r.length>0&&(0,i.jsx)(t.at,{icon:t.wi,title:r.length===1?`Your subscription`:`Your subscriptions`,description:`Manage plan opens Stripe's own portal — cancel, switch, card, invoices.`,collapsible:!1,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:r.map(e=>(0,i.jsx)(Hm,{sub:e},e.id))})}),a.length>0&&(0,i.jsx)(t.at,{icon:t.Vr,title:`Your payments`,description:`Every payment on this account, straight from Stripe.`,collapsible:!1,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:a.map(e=>(0,i.jsx)(Vm,{payment:e},e.id))})})]})})]})]})}var Wm=`text-accent underline underline-offset-2 font-semibold hover:text-accent-deep transition-colors`,Gm=`space-y-2 list-decimal list-inside text-foreground/75 marker:font-bold marker:text-foreground/40`;function Km({href:e,children:t}){return(0,i.jsx)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,className:Wm,children:t})}function qm({children:e}){return(0,i.jsx)(`h4`,{className:`text-[12px] font-extrabold uppercase tracking-[0.14em] text-foreground/40 pt-1`,children:e})}function Jm({number:e,title:n,done:r,open:a,onToggle:o,children:s}){let c=(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`span`,{className:`w-8 h-8 shrink-0 rounded-full flex items-center justify-center text-[13.5px] font-extrabold border ${r?`bg-emerald-500/10 border-emerald-500/20 text-emerald-500`:`bg-accent/10 border-accent/20 text-accent`}`,children:r?(0,i.jsx)(t.zi,{className:`w-4 h-4`}):e}),(0,i.jsx)(`span`,{className:`flex-1 min-w-0 text-[14.5px] sm:text-[15px] font-bold text-foreground tracking-tight truncate`,children:n}),o&&(0,i.jsx)(t.Ri,{className:`w-4 h-4 shrink-0 text-foreground/40 transition-transform duration-200 ${a?`rotate-180`:``}`})]});return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 bg-foreground/[0.015] overflow-hidden transition-all`,children:[o?(0,i.jsx)(`button`,{type:`button`,onClick:o,"aria-expanded":a,className:`w-full px-4 sm:px-5 py-4 flex items-center gap-3 sm:gap-3.5 text-left cursor-pointer hover:bg-foreground/[0.02] transition-colors`,children:c}):(0,i.jsx)(`div`,{className:`w-full px-4 sm:px-5 py-4 flex items-center gap-3 sm:gap-3.5`,children:c}),(0,i.jsx)(t.pr,{initial:!1,children:a&&(0,i.jsx)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden`,children:(0,i.jsx)(`div`,{className:`border-t border-[var(--panel-border)]/40 p-4 sm:p-5 flex flex-col gap-4 bg-background/30 text-[13.5px] sm:text-[14px] text-foreground/70 leading-relaxed`,children:s})})})]})}function Ym({label:e,onDone:n,waitingFor:r}){return(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 pt-1`,children:[(0,i.jsxs)(t.fr.button,{type:`button`,whileHover:r?void 0:{scale:1.01},whileTap:r?void 0:{scale:.99},onClick:n,disabled:!!r,className:`btn-primary inline-flex items-center justify-center gap-2 h-11 px-5 rounded-[var(--btn-radius,0.75rem)] text-[13px] font-bold text-white self-start max-sm:self-stretch shadow-lg ${r?`opacity-40 cursor-not-allowed`:`cursor-pointer`}`,children:[(0,i.jsx)(t.zi,{className:`w-4 h-4`}),e]}),r&&(0,i.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:r})]})}function Xm({label:e,hint:n,placeholder:a,invalid:o,value:s,clean:c,preview:l,onSave:u}){let[d,f]=(0,r.useState)(s),[p,m]=(0,r.useState)(!1),[h,g]=(0,r.useState)(``),_=c(d),v=d.trim().length>0,y=_!==s;return(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsx)(t.ft,{label:e,hint:n,value:d,onChange:e=>{f(e),g(``)},placeholder:a,error:h,action:(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[s&&!y&&(0,i.jsx)(t.lt,{state:`saved`,label:`Saved`}),(0,i.jsx)(t.Q,{icon:t.zi,onClick:async()=>{if(!_){g(o);return}m(!0);let e=await u(_);m(!1),g(e||``),e||f(_)},busy:p,disabled:!v||!y&&!!s,children:`Save`})]})}),_&&!h&&(0,i.jsx)(`div`,{className:`px-3.5 py-2.5 rounded-xl border border-[var(--panel-border)]/60 bg-background`,children:(0,i.jsx)(`span`,{className:`text-[12.5px] font-mono text-foreground/60 truncate block`,children:l(_)})})]})}function Zm({label:e,url:t}){return(0,i.jsxs)(`div`,{className:`flex max-sm:flex-col sm:items-center justify-between gap-2 sm:gap-3 px-3.5 py-3 rounded-xl border border-[var(--panel-border)]/60 bg-background`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex flex-col gap-0.5`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-[0.14em] text-foreground/40`,children:e}),(0,i.jsx)(`span`,{className:`text-[12.5px] font-mono text-foreground/70 truncate`,children:t})]}),(0,i.jsx)(Ru,{compact:!0,code:t,label:`Copy`})]})}var Qm=[`216.239.32.21`,`216.239.34.21`,`216.239.36.21`,`216.239.38.21`];function $m(){let{loading:e,record:n,save:a}=xd(),[o,s]=(0,r.useState)(null),{status:l}=ad(),u=vd(n.done,o),d=e=>u[ud.indexOf(e)],f=md(n.appName),p=gd(n.domain),m=n.done.length===ud.length,h=m&&bd(l),g=e=>{s(null),a({done:yd(n.done,e)})},_=e=>e.open?e.done?()=>s(null):void 0:()=>s(e.done?e.id:null),v=e=>{let t=d(e);return{done:t.done,open:t.open,onToggle:_(t)}};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(Ce,{children:`Publish App`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/publish`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Fe,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-6 md:p-8 shadow-2xl relative bg-background flex flex-col`,children:[(0,i.jsx)(`div`,{className:`mb-6 pb-4 sm:mb-8 sm:pb-6 border-b border-[var(--panel-border)]/50`,children:(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,i.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-extrabold text-foreground tracking-tight truncate`,children:`Putting your app in front of people`}),(0,i.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1 sm:mt-1.5 leading-snug truncate`,children:[(0,i.jsx)(`span`,{className:`sm:hidden`,children:`One step at a time. Stuck? Message me.`}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:`One step at a time — the next one appears as you tick each off. Stuck anywhere? Message me.`})]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(t.fr.a,{whileHover:{scale:1.05},whileTap:{scale:.95},href:`mailto:antonina@youraiworkflow.co`,title:`Email Support`,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer btn-secondary`,children:(0,i.jsx)(t.Zr,{className:`w-4 h-4`})}),(0,i.jsx)(t.fr.a,{whileHover:{scale:1.05},whileTap:{scale:.95},href:`https://wa.me/34632407883`,target:`_blank`,rel:`noopener noreferrer`,title:`WhatsApp Support`,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer btn-secondary`,children:(0,i.jsx)(bu,{className:`w-4 h-4 text-foreground/80`})})]})]})}),!e&&(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsxs)(Jm,{number:1,title:`Publish in AI Studio`,...v(`published`),children:[(0,i.jsxs)(`ol`,{className:Gm,children:[(0,i.jsxs)(`li`,{children:[`In `,(0,i.jsx)(Km,{href:`https://aistudio.google.com`,children:`Google AI Studio`}),`, click`,` `,(0,i.jsx)(`strong`,{children:`Publish`}),` in the top left corner, then `,(0,i.jsx)(`strong`,{children:`Get started`}),`.`]}),(0,i.jsxs)(`li`,{children:[`It asks for an app URL. Type a name for your app —`,` `,(0,i.jsx)(`span`,{className:`text-accent`,children:`my-ai-project`}),` — and copy it, you need it again at the bottom of this step.`]}),(0,i.jsxs)(`li`,{children:[`Follow the rest of AI Studio's instructions, then click `,(0,i.jsx)(`strong`,{children:`Publish your app`}),`.`]})]}),(0,i.jsxs)(`p`,{children:[`If it says `,(0,i.jsx)(`strong`,{children:`Failed to publish app`}),`, reload the page, unpublish, and publish again. It usually goes through the second time.`]}),(0,i.jsx)(Xm,{label:`Your app name`,hint:`The name you just typed into AI Studio. Saving only keeps it for step 3 — nothing changes in AI Studio, it just says Saved. Pasting the whole address is fine; only the name is kept.`,placeholder:`my-ai-project`,invalid:`That does not look like an app name — letters, numbers and dashes.`,value:n.appName,clean:pd,preview:md,onSave:e=>a({appName:e})}),(0,i.jsx)(Ym,{label:`My app is published`,onDone:()=>g(`published`),waitingFor:n.appName?void 0:`Save your app name first — step 3 asks for this address.`})]}),d(`connected`).visible&&(0,i.jsxs)(Jm,{number:2,title:`Connect your website domain`,...v(`connected`),children:[(0,i.jsxs)(`p`,{children:[`Your app is live at `,(0,i.jsx)(`span`,{className:`font-mono text-foreground/80`,children:f||`your AI Studio address`}),` `,`already. This step puts it on a domain of your own.`]}),(0,i.jsx)(qm,{children:`Start the mapping`}),(0,i.jsxs)(`ol`,{className:Gm,children:[(0,i.jsxs)(`li`,{children:[`Back where you published, click `,(0,i.jsx)(`strong`,{children:`Advanced settings`}),`. It takes you to Google Cloud Run.`]}),(0,i.jsxs)(`li`,{children:[`In the menu on the left, open `,(0,i.jsx)(`strong`,{children:`Domain mappings`}),`, then`,` `,(0,i.jsx)(`strong`,{children:`Add mapping`}),` at the top.`]}),(0,i.jsxs)(`li`,{children:[`Choose your service, then under `,(0,i.jsx)(`strong`,{children:`Select a verified domain`}),` click`,` `,(0,i.jsx)(`strong`,{children:`Verify new domain`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Type your domain — `,(0,i.jsx)(`span`,{className:`text-accent`,children:`myaiproject.com`}),` — and click`,` `,(0,i.jsx)(`strong`,{children:`Continue`}),`, then `,(0,i.jsx)(`strong`,{children:`Verify in Search Console`}),`.`]})]}),(0,i.jsx)(qm,{children:`Prove the domain is yours`}),(0,i.jsxs)(`ol`,{className:Gm,children:[(0,i.jsxs)(`li`,{children:[`Google Search Console opens. Click `,(0,i.jsx)(`strong`,{children:`Add a website`}),`, type the same domain, and click `,(0,i.jsx)(`strong`,{children:`Continue`}),`.`]}),(0,i.jsxs)(`li`,{children:[`On the next screen, under `,(0,i.jsxs)(`em`,{children:[`Copy the TXT record below into the DNS configuration for `,hd(n.domain)||`myaiproject.com`]}),`, copy the`,` `,(0,i.jsx)(`strong`,{children:`TXT record`}),` — a long line starting`,` `,(0,i.jsx)(`span`,{className:`font-mono text-foreground/80`,children:`google-site-verification=`})]}),(0,i.jsxs)(`li`,{children:[`Open your domain registrar in another tab — GoDaddy, Namecheap, whoever you bought the domain from — go to its `,(0,i.jsx)(`strong`,{children:`DNS settings`}),`, and click`,` `,(0,i.jsx)(`strong`,{children:`Add record`}),`. Choose `,(0,i.jsx)(`strong`,{children:`TXT`}),`, paste the line into`,` `,(0,i.jsx)(`strong`,{children:`Value`}),`, and put `,(0,i.jsx)(`span`,{className:`font-mono text-foreground/80`,children:`@`}),` `,`in `,(0,i.jsx)(`strong`,{children:`Host`}),` or `,(0,i.jsx)(`strong`,{children:`Name`}),`. Save it.`]}),(0,i.jsxs)(`li`,{children:[`Back in Search Console, click `,(0,i.jsx)(`strong`,{children:`Verify`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Once it is verified you are done with Search Console — close that tab. Go back to the Google Cloud Run tab (`,(0,i.jsx)(`span`,{className:`font-mono text-foreground/80`,children:`console.cloud.google.com`}),`) where you clicked to verify, and press its `,(0,i.jsx)(`strong`,{children:`refresh`}),` button. It should say `,(0,i.jsxs)(`em`,{children:[`Your ownership of `,hd(n.domain)||`myaiproject.com`,` has been successfully verified. You can now map this domain to your Cloud Run services.`]})]})]}),(0,i.jsx)(qm,{children:`Point the domain at your app`}),(0,i.jsxs)(`ol`,{className:Gm,children:[(0,i.jsxs)(`li`,{children:[`Add a subdomain if you want one, then click `,(0,i.jsx)(`strong`,{children:`Continue`}),`. Cloud Run now shows you the records to add.`]}),(0,i.jsxs)(`li`,{children:[`Back at your registrar, add each one as an `,(0,i.jsx)(`strong`,{children:`A record`}),`, the same way you added the TXT. It is normally these four:`]})]}),(0,i.jsxs)(`div`,{className:`rounded-xl border border-[var(--panel-border)]/60 bg-background overflow-hidden`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-3.5 py-2.5 border-b border-[var(--panel-border)]/40`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-[0.14em] text-foreground/40`,children:`A records`}),(0,i.jsx)(Ru,{compact:!0,code:Qm.join(`
|
|
678
|
-
`),label:`Copy all four`})]}),(0,i.jsx)(`div`,{className:`px-3.5 py-2.5 flex flex-col gap-1`,children:Qm.map(e=>(0,i.jsx)(`span`,{className:`text-[12.5px] font-mono text-foreground/70`,children:e},e))})]}),(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:`Use whatever your own Cloud Run screen shows if it differs from these — that screen is always right.`}),(0,i.jsxs)(`p`,{children:[`Once they are all in, press `,(0,i.jsx)(`strong`,{children:`Done`}),` in Cloud Run and wait — this can take an hour or more. Check every few minutes by typing your domain into any browser, like `,(0,i.jsx)(`span`,{className:`text-accent`,children:`myaiproject.com`}),`: when your published app comes up, it is connected.`]}),(0,i.jsx)(Xm,{label:`Your domain`,hint:`However you have it — with or without https:// and www. Only the domain itself is kept, for step 3.`,placeholder:`myaiproject.com`,invalid:`That does not look like a domain — something like myaiproject.com.`,value:n.domain,clean:hd,preview:gd,onSave:e=>a({domain:e})}),(0,i.jsx)(Ym,{label:`My domain is verified and my app is connected`,onDone:()=>g(`connected`),waitingFor:n.domain?void 0:`Save your domain first — step 3 asks for this address.`})]}),d(`authorised`).visible&&(0,i.jsxs)(Jm,{number:3,title:`Add your domains and email sender`,...v(`authorised`),children:[(0,i.jsxs)(`p`,{children:[`Once your domain answers, head back to the`,` `,(0,i.jsx)(Km,{href:`https://console.firebase.google.com`,children:`Firebase console`}),`. Two jobs, both under `,(0,i.jsx)(`strong`,{children:`Security → Authentication`}),`.`]}),(0,i.jsx)(qm,{children:`Authorise both addresses`}),(0,i.jsxs)(`p`,{children:[`Nobody can sign in from an address Firebase does not know. Open`,` `,(0,i.jsx)(`strong`,{children:`Security → Authentication → Settings → Authorised domains`}),`, click`,` `,(0,i.jsx)(`strong`,{children:`Add domain`}),`, and paste these in one at a time — both need to be there.`]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsx)(Zm,{label:`Your AI Studio address`,url:f?`${pd(n.appName)}.ai.studio`:`—`}),(0,i.jsx)(Zm,{label:`Your own domain`,url:hd(n.domain)||`—`})]}),(0,i.jsx)(qm,{children:`Send email from your own domain`}),(0,i.jsxs)(`ol`,{className:Gm,children:[(0,i.jsxs)(`li`,{children:[`On the same Authentication page, open the `,(0,i.jsx)(`strong`,{children:`Templates`}),` tab. Every email Firebase sends for you lives here — password changes, email verification. You can reword them, but the one thing worth doing is the sender.`]}),(0,i.jsxs)(`li`,{children:[`Click the pencil beside `,(0,i.jsx)(`strong`,{children:`From`}),`. It will be something like`,` `,(0,i.jsx)(`span`,{className:`font-mono text-foreground/80`,children:`noreply@your-project.firebaseapp.com`})]}),(0,i.jsxs)(`li`,{children:[`On the right, click `,(0,i.jsx)(`strong`,{children:`Customise domain`}),`, enter your own domain, and follow the steps it gives you — more records at your registrar, same as before.`]})]}),(0,i.jsx)(`p`,{children:`This is what keeps your emails out of people's spam folders, and it is why they arrive looking like they came from you.`}),(0,i.jsx)(Ym,{label:`I've added my domains and verified my email domain`,onDone:()=>g(`authorised`)})]}),h&&(0,i.jsxs)(Jm,{number:4,title:`Finalise your Stripe live setup`,done:!1,open:!0,children:[(0,i.jsx)(`p`,{children:`Your payments are not live yet — still on practice cards, or live without the webhook that sends receipts. Finish Go live on the Payments screen and your setup is complete.`}),(0,i.jsxs)(`p`,{children:[`Switch `,(0,i.jsx)(`strong`,{children:`Go live`}),` on and follow its steps. Its webhook step was waiting for your published address, and it is open now that step 3 is ticked.`]}),(0,i.jsxs)(c.Link,{to:`/payments`,className:`btn-primary inline-flex items-center justify-center gap-2 h-11 px-5 rounded-[var(--btn-radius,0.75rem)] text-[13px] font-bold text-white self-start max-sm:self-stretch shadow-lg cursor-pointer`,children:[(0,i.jsx)(t.wi,{className:`w-4 h-4`}),`Take me to Go live`]})]}),m&&!h&&(0,i.jsxs)(`div`,{className:`mt-3 flex max-sm:flex-col sm:items-center gap-4 sm:gap-6 p-5 sm:p-6 rounded-2xl border border-emerald-500/20 bg-emerald-500/[0.06]`,children:[(0,i.jsx)(`div`,{className:`w-10 h-10 shrink-0 rounded-2xl flex items-center justify-center border border-emerald-500/20 bg-emerald-500/10 text-emerald-500`,children:(0,i.jsx)(t.zr,{className:`w-5 h-5`})}),(0,i.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-extrabold text-foreground tracking-tight`,children:`Your app is live`}),(0,i.jsxs)(`p`,{className:`text-[13px] text-foreground/60 font-medium leading-relaxed mt-1`,children:[p?(0,i.jsxs)(i.Fragment,{children:[`Anyone can open `,(0,i.jsx)(Km,{href:p,children:hd(n.domain)}),` and sign up.`]}):(0,i.jsx)(i.Fragment,{children:`Anyone can open your app and sign up.`}),` `,`Any step above opens again if you need to check what you typed.`]})]})]})]})]})]})]})}var eh={contentKey:`dashboard`};function th(){let{user:e}=t.na(),n=t.Na(),[a,o]=(0,r.useState)(null),[s,c]=(0,r.useState)(()=>typeof window<`u`&&!km(eh));(0,r.useEffect)(()=>{if(km(eh))return;let e=!1;Mm(eh).then(t=>{e||(t&&o(()=>t),c(!1))});let t=setTimeout(()=>{e||c(!1)},4e3);return()=>{e=!0,clearTimeout(t)}},[]);let l=n.microcomponents?.dashboard||(typeof window<`u`?window.__FBOS_MICROCOMPONENTS__?.dashboard:void 0)||a||void 0,u=(e?.displayName||e?.email?.split(`@`)[0]||`there`).split(` `)[0],d=u.charAt(0).toUpperCase()+u.slice(1);return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-8`,children:[(0,i.jsxs)(Ce,{children:[`Welcome back, `,d,`.`]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/dashboard`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 flex-1 min-h-[500px]`,children:[(0,i.jsx)(`div`,{className:`flex justify-start`,children:(0,i.jsx)(Fe,{})}),(0,i.jsxs)(`div`,{className:`w-full flex-1 glass-panel rounded-3xl relative overflow-hidden border border-[var(--panel-border)] shadow-2xl bg-[var(--panel-bg)] ${l?`p-6 md:p-8`:`p-8 md:p-12 flex items-center justify-center`}`,children:[(0,i.jsx)(`div`,{className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-64 h-64 bg-accent/10 blur-[100px] rounded-full pointer-events-none`}),l?(0,i.jsx)(`div`,{className:`fbos-content-slot relative z-10`,children:(0,i.jsx)(l,{})}):s?(0,i.jsx)(t.ti,{className:`w-6 h-6 text-accent animate-spin relative z-10`}):(0,i.jsx)(t.pr,{mode:`wait`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.95},transition:{duration:.3},className:`text-center z-10`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-3xl bg-accent/10 border border-accent/20 flex items-center justify-center text-accent mx-auto mb-6 shadow-inner`,children:(0,i.jsx)(t.Ci,{className:`w-6 h-6`})}),(0,i.jsx)(`h2`,{className:`text-2xl font-extrabold text-foreground mb-2`,children:`No data added here yet`}),(0,i.jsx)(`p`,{className:`text-foreground/40 font-medium`,children:`Keep moving forward, your data will appear here.`})]})})]})]})]})}var nh=()=>(0,i.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center min-h-[60vh] z-10 animate-in fade-in duration-500`,children:[(0,i.jsx)(`div`,{className:`w-12 h-12 rounded-xl glass-panel border border-[var(--panel-border)] flex items-center justify-center mb-6 shadow-xl`,children:(0,i.jsx)(t.Ci,{className:`w-6 h-6 text-accent animate-pulse`})}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3 glass-panel px-5 py-2.5 rounded-full border border-[var(--panel-border)]`,children:[(0,i.jsx)(`div`,{className:`w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin`}),(0,i.jsx)(`span`,{className:`text-[13px] font-bold tracking-widest uppercase text-foreground/70`,children:`Connecting`})]})]});function rh({level:e,children:n}){let{user:r,userRole:a,loading:o,userInactive:s,signOut:l,roleResolved:u}=t.na(),d=(0,c.useLocation)();return o||!u?(0,i.jsx)(nh,{}):r?s?(0,i.jsx)(yi,{tone:`red`,title:`Access Denied`,message:`You don't have access to this app. Please contact the administrator.`,action:(0,i.jsx)(`button`,{onClick:()=>l(),className:bi,children:`Sign Out`})}):r.emailVerified?e===`admin`&&!t.pa(a)?(0,i.jsx)(Ti,{}):e===`internal`&&!t.fa(a)?(0,i.jsx)(wi,{}):(0,i.jsx)(i.Fragment,{children:n}):(0,i.jsx)(c.Navigate,{to:`/verify`}):(0,i.jsx)(c.Navigate,{to:`/login?from=${encodeURIComponent(d.pathname)}`,replace:!0})}var ih=({children:e})=>(0,i.jsx)(rh,{level:`signed-in`,children:e}),ah=({children:e})=>(0,i.jsx)(rh,{level:`admin`,children:e}),oh=({children:e})=>(0,i.jsx)(rh,{level:`internal`,children:e});function sh({children:e}){let{user:n,loading:r,roleResolved:a}=t.na(),[o]=(0,c.useSearchParams)();return r||!a?(0,i.jsx)(nh,{}):n&&n.emailVerified?(0,i.jsx)(c.Navigate,{to:o.get(`from`)||`/dashboard`,replace:!0}):(0,i.jsx)(i.Fragment,{children:e})}function ch({children:e}){let{user:n,loading:r,roleResolved:a}=t.na();return r||!a?(0,i.jsx)(nh,{}):n?n.emailVerified?(0,i.jsx)(c.Navigate,{to:`/dashboard`}):(0,i.jsx)(i.Fragment,{children:e}):(0,i.jsx)(c.Navigate,{to:`/`})}function lh({to:e}){return(0,i.jsx)(c.Navigate,{to:`${e}${(0,c.useLocation)().search}`,replace:!0})}function uh(){return(0,i.jsxs)(`div`,{className:`fixed top-0 left-0 w-full h-full pointer-events-none -z-0 overflow-hidden`,children:[(0,i.jsx)(t.fr.div,{animate:{scale:[1,1.1,1],opacity:[.6,1,.6]},transition:{duration:12,repeat:1/0,ease:`easeInOut`},className:`absolute -top-[30%] md:-top-[400px] -right-[10%] md:-right-[200px] w-[500px] md:w-[800px] h-[500px] md:h-[800px] rounded-full bg-decorator-1 blur-[80px] md:blur-[120px]`}),(0,i.jsx)(t.fr.div,{animate:{scale:[1,1.2,1],opacity:[.5,.9,.5]},transition:{duration:18,repeat:1/0,ease:`easeInOut`,delay:2},className:`absolute -bottom-[20%] md:-bottom-[300px] -left-[10%] md:-left-[100px] w-[400px] md:w-[600px] h-[400px] md:h-[600px] rounded-full bg-decorator-2 blur-[60px] md:blur-[100px]`})]})}function dh(){let e=t.Na().components?.Home||se,n=(0,c.useNavigate)();return(0,i.jsx)(t.ta,{onSignedOut:()=>n(`/`,{replace:!0}),children:(0,i.jsxs)(`div`,{className:`min-h-screen relative flex flex-col overflow-x-hidden`,children:[(0,i.jsx)(oe,{}),(0,i.jsxs)(c.Routes,{children:[(0,i.jsx)(c.Route,{path:`/`,element:(0,i.jsx)(sh,{children:(0,i.jsx)(`div`,{className:`fbos-home-slot contents`,children:(0,i.jsx)(e,{})})})}),(0,i.jsx)(c.Route,{path:`/register`,element:(0,i.jsx)(sh,{children:(0,i.jsx)(ve,{})})}),(0,i.jsx)(c.Route,{path:`/login`,element:(0,i.jsx)(sh,{children:(0,i.jsx)(ye,{})})}),(0,i.jsx)(c.Route,{path:`/reset-password`,element:(0,i.jsx)(sh,{children:(0,i.jsx)(Le,{})})}),(0,i.jsx)(c.Route,{path:`/verify`,element:(0,i.jsx)(ch,{children:(0,i.jsx)(be,{})})}),(0,i.jsx)(c.Route,{path:`/book/:id`,element:(0,i.jsx)(Bp,{})}),(0,i.jsx)(c.Route,{path:`/meet/:id`,element:(0,i.jsx)(Yp,{})}),(0,i.jsx)(c.Route,{path:`/pay/:id`,element:(0,i.jsx)(Zp,{})}),(0,i.jsx)(c.Route,{path:`/payment-complete`,element:(0,i.jsx)(Lm,{})}),(0,i.jsx)(c.Route,{path:`/payment-cancelled`,element:(0,i.jsx)(Lm,{cancelled:!0})}),(0,i.jsx)(c.Route,{path:`/guide`,element:(0,i.jsx)(fn,{})}),(0,i.jsx)(c.Route,{path:`/templates`,element:(0,i.jsx)(Zt,{})}),(0,i.jsx)(c.Route,{path:`/board`,element:(0,i.jsx)(vn,{})}),(0,i.jsx)(c.Route,{path:`/table`,element:(0,i.jsx)(qr,{})}),(0,i.jsx)(c.Route,{path:`/calendar`,element:(0,i.jsx)(Xr,{})}),(0,i.jsx)(c.Route,{path:`/drive`,element:(0,i.jsx)(Kt,{})}),(0,i.jsx)(c.Route,{path:`/inline_form`,element:(0,i.jsx)(pn,{})}),(0,i.jsx)(c.Route,{path:`/popup_form`,element:(0,i.jsx)(mn,{})}),(0,i.jsx)(c.Route,{path:`/users`,element:(0,i.jsx)(ah,{children:(0,i.jsx)(Dt,{})})}),(0,i.jsx)(c.Route,{path:`/users/:id`,element:(0,i.jsx)(ah,{children:(0,i.jsx)(Dt,{})})}),(0,i.jsx)(c.Route,{path:`/inbox`,element:(0,i.jsx)(ah,{children:(0,i.jsx)(Ht,{})})}),(0,i.jsx)(c.Route,{path:`/payments`,element:(0,i.jsx)(ah,{children:(0,i.jsx)(Xd,{})})}),(0,i.jsx)(c.Route,{path:`/schedule`,element:(0,i.jsx)(oh,{children:(0,i.jsx)(Sp,{})})}),(0,i.jsx)(c.Route,{path:`/my-calendar`,element:(0,i.jsx)(lh,{to:`/schedule`})}),(0,i.jsx)(c.Route,{path:`/my-bookings`,element:(0,i.jsx)(ih,{children:(0,i.jsx)(Cp,{})})}),(0,i.jsx)(c.Route,{path:`/email`,element:(0,i.jsx)(ah,{children:(0,i.jsx)(lm,{})})}),(0,i.jsx)(c.Route,{path:`/submissions`,element:(0,i.jsx)(c.Navigate,{to:`/inbox`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/requests`,element:(0,i.jsx)(c.Navigate,{to:`/inbox`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/assets`,element:(0,i.jsx)(ah,{children:(0,i.jsx)(Xt,{})})}),(0,i.jsx)(c.Route,{path:`/drive/:rest`,element:(0,i.jsx)(c.Navigate,{to:`/assets`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/theme`,element:(0,i.jsx)(ah,{children:(0,i.jsx)(vi,{})})}),(0,i.jsx)(c.Route,{path:`/pages/*`,element:(0,i.jsx)(ah,{children:(0,i.jsx)(Ml,{})})}),(0,i.jsx)(c.Route,{path:`/forms/*`,element:(0,i.jsx)(ah,{children:(0,i.jsx)(ql,{})})}),(0,i.jsx)(c.Route,{path:`/settings`,element:(0,i.jsx)(c.Navigate,{to:`/pages`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/profile`,element:(0,i.jsx)(ih,{children:(0,i.jsx)(Ie,{})})}),(0,i.jsx)(c.Route,{path:`/billing`,element:(0,i.jsx)(ih,{children:(0,i.jsx)(Um,{})})}),(0,i.jsx)(c.Route,{path:`/dashboard`,element:(0,i.jsx)(ih,{children:(0,i.jsx)(th,{})})}),(0,i.jsx)(c.Route,{path:`/publish`,element:(0,i.jsx)(ah,{children:(0,i.jsx)($m,{})})}),(0,i.jsx)(c.Route,{path:`/setup`,element:(0,i.jsx)(Xu,{})}),(0,i.jsx)(c.Route,{path:`/setup/payments`,element:(0,i.jsx)(Wd,{})}),(0,i.jsx)(c.Route,{path:`*`,element:(0,i.jsx)(Pm,{})})]}),(0,i.jsx)(uh,{})]})})}function fh(){return(0,i.jsx)(c.BrowserRouter,{children:(0,i.jsx)(ph,{})})}function ph(){let e=t.Na();return e.firebaseConfig&&e.firebaseConfig.apiKey&&e.firebaseConfig.apiKey.trim()!==``&&e.firebaseConfig.projectId&&e.firebaseConfig.projectId.trim()!==``||Nu()?(0,i.jsx)(dh,{}):(0,i.jsxs)(`div`,{className:`min-h-screen relative flex flex-col overflow-x-hidden`,children:[(0,i.jsx)(oe,{standalone:!0}),(0,i.jsx)(Xu,{standalone:!0}),(0,i.jsx)(uh,{})]})}function mh(e){v();let n=e.firebaseConfig;return n&&n.apiKey&&n.apiKey.trim()!==``&&n.projectId&&n.projectId.trim()!==``&&t.Oa(n),(0,i.jsx)(t.Ma,{config:{firebaseConfig:e.firebaseConfig,basename:e.basename,onAuthChange:e.onAuthChange,themeConfig:e.themeConfig,components:e.components,customRoutes:e.customRoutes,microcomponents:e.microcomponents,defaultConfigs:e.defaultConfigs},children:(0,i.jsx)(t.Aa,{children:(0,i.jsx)(`div`,{className:`firebase-os flex-1 flex flex-col min-h-screen`,style:{background:`var(--bg-gradient)`,color:`var(--fg-color)`},children:(0,i.jsx)(fh,{})})})})}var hh=Object.assign({}),gh={};for(let e in hh){let t=hh[e];if(!t?.default)continue;let n=e.replace(`./`,``).replace(`.tsx`,``);if(n===`registry`)continue;let r=n.replace(/Content$/,``).replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();gh[r]=t.default,gh[r.replace(/_/g,``)]=t.default}if(typeof window<`u`){let e=window.__FBOS_MICROCOMPONENTS__||{};window.__FBOS_MICROCOMPONENTS__={...gh,...e}}var _h=(e,t)=>{let n=e.toLowerCase().replace(/[^a-z0-9]+/g,`_`),r=n.replace(/_/g,``);if(gh[n]=t,gh[r]=t,typeof window<`u`){let e=window.__FBOS_MICROCOMPONENTS__||{};window.__FBOS_MICROCOMPONENTS__={...e,[n]:t,[r]:t}}},vh=({title:e,className:n,children:r,...a})=>(0,i.jsxs)(`div`,{className:t.ur(`border border-[var(--panel-border)] bg-[var(--panel-bg)] px-5 py-4`,n),style:{borderRadius:`var(--card-radius, 1rem)`},...a,children:[e?(0,i.jsx)(`p`,{className:`text-[12px] font-extrabold tracking-tight text-gradient mb-1.5`,children:e}):null,r]});vh.displayName=`Card`;var yh=({sub:e,className:n,children:r,...a})=>(0,i.jsxs)(`div`,{className:t.ur(`mb-4`,n),children:[(0,i.jsx)(`h2`,{className:`text-xl md:text-2xl font-extrabold tracking-tight text-foreground`,...a,children:r}),e?(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/60 font-medium leading-relaxed mt-1`,children:e}):null]});yh.displayName=`SectionHeading`,exports.AdminNotifications=O,exports.Button=t.cr,exports.Card=vh,exports.ConfirmModal=Ve,exports.ContactPopup=t.t,exports.CustomSelect=t.sr,exports.DashboardNav=Fe,exports.EventCard=Of,exports.FirebaseOS=mh,exports.Input=t.lr,exports.ManagePlanButton=Rm,exports.Navbar=oe,exports.PayButton=Xp,exports.PhoneInputField=n.t,exports.SectionHeading=yh,exports.TimeChips=t.q,exports.acceptBooking=t.n,Object.defineProperty(exports,`auth`,{enumerable:!0,get:function(){return t.Ea}}),exports.availableSlots=t.zt,exports.availableSlotsFor=t.Bt,exports.blockedWindows=t.Ut,exports.bookingPath=t.Qt,exports.cancelBooking=t.i,exports.confirmPayment=ee,exports.dayBlocked=t.rn,exports.daysLine=t.in,Object.defineProperty(exports,`db`,{enumerable:!0,get:function(){return t.Da}}),exports.emailAnyone=Za,exports.emailOwner=Ya,exports.emailPerson=Xa,exports.emailStatus=Qa,exports.eventName=t.cn,exports.hoursSummary=t._n,exports.meetPath=ro,exports.notify=S,exports.oneEach=t.En,exports.openBillingPortal=G,exports.partySlots=t.On,exports.payPath=t.kn,exports.registerMicrocomponent=_h,exports.scheduleName=t.Mn,exports.scheduleTitle=t.In,exports.slotsFor=t.Un,exports.startCheckout=U,Object.defineProperty(exports,`storage`,{enumerable:!0,get:function(){return t.ka}}),exports.timeZoneLabel=t.Kn,exports.togetherSlots=t.Xn,exports.useAuth=t.na,exports.useBookings=t.g,exports.useConfig=t.Na,exports.useMemberSchedules=t._,exports.useMyPayments=te,exports.usePaymentsEnabled=Y,exports.useSales=ne,exports.useTakenSlots=t.x,exports.useTeamHours=t.S,exports.useTheme=t.ja;
|
|
668
|
+
flex flex-col items-center justify-center leading-none gap-0.5 transition-colors duration-300 group-hover:bg-accent/[0.13] group-hover:border-accent/30`,children:[(0,i.jsx)(`span`,{className:`text-[17px] font-extrabold tracking-tight tabular-nums`,children:a.value}),(0,i.jsx)(`span`,{className:`text-[9.5px] font-bold uppercase tracking-[0.08em] opacity-70`,children:a.unit})]}),(0,i.jsxs)(`span`,{className:`relative flex-1 min-w-0 flex flex-col gap-1`,children:[(0,i.jsx)(`span`,{className:`text-[14.5px] sm:text-[15px] font-bold text-foreground tracking-tight leading-snug break-words`,children:t.In(e)}),(0,i.jsxs)(`span`,{className:`flex flex-wrap items-center gap-1.5`,children:[(0,i.jsx)(Jd,{icon:t.Ti,children:t.Bn(e.slotMinutes)}),n&&(0,i.jsx)(Jd,{accent:!0,children:Fd(n.amount)})]}),r&&(0,i.jsx)(`span`,{className:`text-[12.5px] font-medium text-foreground/55 leading-relaxed line-clamp-2 mt-0.5`,children:r})]}),(0,i.jsx)(`span`,{"aria-hidden":!0,className:`relative shrink-0 w-8 h-8 rounded-full border border-[var(--panel-border)]/70 flex items-center justify-center
|
|
669
|
+
text-foreground/35 transition-all duration-300 group-hover:border-accent/50 group-hover:bg-accent group-hover:text-[var(--button-fg,#fff)]`,children:(0,i.jsx)(t.Ki,{className:`w-4 h-4 transition-transform duration-300 group-hover:translate-x-[1px]`})})]})}function Xd({page:e}){let n=`w-24 h-24 sm:w-28 sm:h-28`;return(0,i.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,i.jsx)(`span`,{"aria-hidden":!0,className:`absolute -inset-3 rounded-[2rem] bg-accent/15 blur-2xl`}),e.photo?(0,i.jsx)(`img`,{src:e.photo,alt:``,className:`relative ${n} rounded-2xl object-cover border border-[var(--panel-border)] shadow-[0_10px_30px_rgba(0,0,0,0.12)]`}):(0,i.jsx)(`div`,{className:`relative ${n} ${Ud}`,children:(0,i.jsx)(t.Cr,{className:`w-9 h-9`})})]})}function Zd(){let{id:e=``}=(0,c.useParams)(),{activeConfig:n}=t.Da(),{loading:a,pages:o}=pi(),{loading:s,schedules:l}=t._(),u=o.find(t=>t.id===e)||null,d=(0,r.useMemo)(()=>u?li(u,l):[],[u,l]),f=Gd((0,r.useMemo)(()=>[...new Set(d.map(e=>e.paymentId).filter(Boolean))],[d]));if(a||s)return(0,i.jsx)(Kd,{children:(0,i.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-16 text-foreground/50`,children:[(0,i.jsx)(t.ei,{className:`w-4 h-4 animate-spin text-accent`}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium`,children:`Loading…`})]})});if(!u||!u.enabled)return(0,i.jsx)(Kd,{children:(0,i.jsx)(qd,{icon:t.Ri,title:`This page is no longer open`,children:`It may have been taken down. Ask whoever sent it for a new link.`})});if(!d.length){let e=ci(u,l).length;return(0,i.jsx)(Kd,{children:(0,i.jsx)(qd,{icon:t.Ri,title:fi(u),children:e?`Nothing here is taking bookings at the moment. Please check back later.`:`There is nothing to book here at the moment. Please check back later.`})})}let p=u.intro.trim();return(0,i.jsxs)(Kd,{children:[(0,i.jsxs)(`div`,{className:`flex flex-col items-center text-center gap-4`,children:[(0,i.jsx)(Xd,{page:u}),(0,i.jsxs)(`div`,{className:`flex flex-col items-center gap-1.5 w-full min-w-0`,children:[n?.appName&&(0,i.jsx)(`span`,{className:`text-[10.5px] font-bold uppercase tracking-[0.18em] text-foreground/40 truncate max-w-full`,children:n.appName}),(0,i.jsx)(`h1`,{className:`text-[26px] sm:text-4xl font-extrabold tracking-tight text-gradient leading-[1.1] break-words`,children:fi(u)}),p&&(0,i.jsx)(`p`,{className:`mt-1.5 max-w-md text-[13.5px] sm:text-[14.5px] text-foreground/60 font-medium leading-relaxed whitespace-pre-line`,children:p})]})]}),(0,i.jsx)(`div`,{className:`h-px bg-[var(--panel-border)]/60 my-5 sm:my-7`}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-1`,children:[(0,i.jsx)(`p`,{className:`text-[11px] font-bold uppercase tracking-[0.16em] text-foreground/40`,children:d.length===1?`Book a time`:`Pick what to book`}),d.length>1&&(0,i.jsxs)(`span`,{className:`text-[11px] font-semibold text-foreground/35 tabular-nums`,children:[d.length,` meetings`]})]}),d.map(e=>(0,i.jsx)(Yd,{schedule:e,price:Pd(f.get(e.paymentId)||null)},e.id))]})]})}function Qd({children:e,className:n,variant:a=`primary`,pendingLabel:o=`Opening checkout…`,...s}){let{loading:c,configured:l}=X(),{userRole:u}=t.Qi(),[d,f]=(0,r.useState)(!1),[p,m]=(0,r.useState)(null);return c?null:l?(0,i.jsxs)(`span`,{className:`inline-flex flex-col items-stretch gap-2`,children:[(0,i.jsx)(t.cr,{variant:a,className:n,onClick:async()=>{if(d)return;f(!0),m(null);let e=await W(s);e&&(m(e),f(!1))},disabled:d,children:d?o:e??`Pay`}),p&&(0,i.jsx)(`span`,{role:`alert`,className:`text-[13px] font-semibold text-red-400 leading-snug`,children:p})]}):t.la(u)?(0,i.jsx)(`span`,{className:`text-[12.5px] font-medium text-foreground/50 leading-snug`,children:`Only admins see this: payments are not on yet, so this button is hidden. Connect Stripe and switch payments on at /payments and it appears here.`}):null}function $d(){let{id:e=``}=(0,c.useParams)(),{activeConfig:n}=t.Da(),a=X(),[s,l]=(0,r.useState)({loading:!0,product:null});(0,r.useEffect)(()=>{let n=!1;return(0,o.getDoc)((0,o.doc)(t.Ca,Nn,e)).then(e=>{n||l({loading:!1,product:e.exists()?Gn(e.id,e.data()):null})}).catch(()=>{n||l({loading:!1,product:null})}),()=>{n=!0}},[e]);let u=s.product,d=u?.customPath.trim()||``;if(d)return(0,i.jsx)(c.Navigate,{to:d.startsWith(`/`)?d:`/${d}`,replace:!0});let f=u?zn(u).filter(e=>Bn(e.amount)):[],p=u?.name.trim()||f[0]?.name.trim()||`Pay`;return(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-3xl mx-auto px-4 pt-2 pb-16 md:pt-4 z-10 flex flex-col`,children:(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},transition:{duration:.4},className:`w-full rounded-3xl glass-panel border border-[var(--panel-border)] p-5 sm:p-8 md:p-10 shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:s.loading?(0,i.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-16 text-foreground/50`,children:[(0,i.jsx)(t.ei,{className:`w-4 h-4 animate-spin text-accent`}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium`,children:`Loading…`})]}):!u||u.kind!==`once`||!f.length?(0,i.jsxs)(`div`,{className:`flex flex-col items-center text-center py-8 gap-4`,children:[(0,i.jsx)(`div`,{className:`w-14 h-14 rounded-2xl glass-panel border border-[var(--panel-border)] flex items-center justify-center shadow-xl`,children:(0,i.jsx)(t.Nr,{className:`w-7 h-7 text-accent`})}),(0,i.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold text-foreground tracking-tight`,children:`This payment link is no longer open`}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/60 max-w-md`,children:`Ask whoever sent it for a new one.`}),(0,i.jsx)(c.Link,{to:`/`,className:`text-[13px] font-bold text-accent hover:underline mt-2`,children:`Back to the site`})]}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[n?.appName&&(0,i.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-[0.2em] text-foreground/40`,children:n.appName}),(0,i.jsx)(`h1`,{className:`text-2xl sm:text-3xl md:text-4xl font-extrabold text-foreground tracking-tight`,children:p}),u.description.trim()&&(0,i.jsx)(`p`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed mt-1 max-w-2xl whitespace-pre-line`,children:u.description.trim()})]}),!a.loading&&!a.configured&&(0,i.jsx)(`p`,{className:`text-[14px] font-medium text-foreground/60`,children:`Payments are not open right now — please try again later.`}),(0,i.jsx)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60`,children:f.map((e,n)=>(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-4 px-4 py-3.5`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex flex-col`,children:[(0,i.jsx)(`span`,{className:`text-[15px] font-semibold text-foreground truncate`,children:e.name.trim()||p}),(0,i.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/50`,children:Fd(Bn(e.amount)||0)})]}),(0,i.jsxs)(Qd,{amount:Bn(e.amount)||0,productName:e.name.trim()||p,metadata:{productId:u.id,page:t.kn(u.id),emailReceipt:u.emailReceipt?`yes`:`no`,notifyOwner:u.notifyOwner?`yes`:`no`},successPath:`/payment-complete`,cancelPath:t.kn(u.id),className:`px-5 py-2.5 text-[14px] font-bold`,children:[`Pay `,Fd(Bn(e.amount)||0)]})]},n))})]})})})}function ef({trailing:e,onSent:n}){let[a,o]=(0,r.useState)(`idle`),[s,c]=(0,r.useState)(``);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5 flex-wrap`,children:[(0,i.jsx)(t.Q,{compact:!0,icon:t.Ui,busy:a===`sending`,onClick:async()=>{o(`sending`),c(``);try{let e=await fetch(`/api/_selftest/email`),t=await e.json().catch(()=>({}));e.ok&&t?.ok?(o(`sent`),n?.(typeof t.from==`string`&&t.from.trim()?t.from:null)):(o(`failed`),c(String(t?.error||t?.message||`The server answered ${e.status}.`)))}catch{o(`failed`),c(`The server could not be reached.`)}},title:`Sends the test email to your own admin address`,children:`Send yourself a test email`}),e]}),a===`sent`&&(0,i.jsx)(`p`,{className:`text-[12px] font-semibold text-emerald-500 px-1`,children:`Sent. If you do not receive it within a minute, check your spam.`}),a===`failed`&&(0,i.jsxs)(`p`,{className:`text-[12px] font-medium text-red-500 px-1 leading-relaxed`,children:[`It did not send: `,s,` If the sending address uses your own domain, that domain must be verified under `,(0,i.jsx)(`strong`,{children:`Domains`}),` in your Resend account — an unverified domain makes every send fail.`]})]})}var{collection:tf,doc:nf}=el.email,rf=(e,t)=>{let n=String(e||``).trim().toLowerCase(),r=String(t||``).trim().toLowerCase();return!!n&&n===r};function af(){let[e,n]=(0,r.useState)({loading:!0,testedFrom:null});return(0,r.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(t.Ca,tf,nf),e=>{let t=e.exists()?e.data()?.testedFrom:null;n({loading:!1,testedFrom:typeof t==`string`&&t.trim()?t:null})},()=>n({loading:!1,testedFrom:null})),[]),{loading:e.loading,testedFrom:e.testedFrom,mark:async e=>{if(e.trim()){n({loading:!1,testedFrom:e});try{await(0,o.setDoc)((0,o.doc)(t.Ca,tf,nf),{testedFrom:e},{merge:!0})}catch(e){console.error(`Could not remember the test send`,e)}}}}}var of=e=>[{title:`Hear about what happens`,body:`A booking, a form entry, a new member — at your address the moment it happens.`,icon:t.Hi,where:{path:`/pages`,label:`Pages screen`}},{title:`Confirm to the people who write in`,body:`Whoever books or writes gets a note that it arrived, in your words.`,icon:t.Zr,where:{path:`/pages`,label:`Pages screen`}},{title:`Receipts and sale alerts`,body:`Every payment emails the buyer a receipt and tells you something sold.`,icon:t.Br,where:{path:`/payments`,label:`Payments screen`}},{title:`Write to anyone from your app`,body:`A page for your team can write to any address, from ${e}.`,icon:t.Fr,where:{path:`/pages`,label:`Pages screen`}}],sf=e=>String(e||``).toLowerCase().endsWith(`@resend.dev`),cf=e=>String(e||``).split(`@`)[1]||``,lf=e=>e?{description:`Every page you told to send email does. Switch it off to stop all of it at once.`,chip:{state:`saved`,label:`On`}}:{description:`Nothing sends. Your pages keep their settings and wait for this to come back on.`,chip:{state:`off`,label:`Off`}};function uf({from:e}){return(0,i.jsx)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60`,children:of(e).map(e=>{let n=e.icon;return(0,i.jsxs)(`div`,{className:`grid grid-cols-[auto_minmax(0,1fr)] sm:grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-x-3 sm:gap-x-3.5 gap-y-0.5 px-4 py-3`,children:[(0,i.jsx)(`div`,{className:`row-start-1 row-span-2 col-start-1 self-center w-9 h-9 rounded-xl flex items-center justify-center shrink-0 border border-[var(--panel-border)]/50 bg-accent/10 text-accent`,children:(0,i.jsx)(n,{className:`w-4 h-4`})}),(0,i.jsx)(`span`,{className:`row-start-1 col-start-2 min-w-0 text-[13px] font-bold text-foreground leading-tight self-end`,children:e.title}),(0,i.jsx)(`span`,{className:`row-start-2 col-start-2 min-w-0 text-[12px] text-foreground/50 font-normal leading-snug self-start`,children:e.body}),(0,i.jsxs)(c.Link,{to:e.where.path,className:`max-sm:hidden sm:inline-flex row-start-1 row-span-2 col-start-3 self-center justify-self-end items-center gap-1.5 text-[11.5px] font-semibold text-foreground/45 hover:text-accent whitespace-nowrap transition-colors`,children:[e.where.label,(0,i.jsx)(t.Ki,{className:`w-3 h-3`})]})]},e.title)})})}function df({adminCount:e,onSetUp:n}){return(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5 px-1 flex-wrap`,children:[(0,i.jsx)(t.lt,{state:e?`saved`:`off`,label:e?`Your mail reaches ${e} address${e===1?``:`es`}`:`No address for your mail`}),!e&&(0,i.jsxs)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Sale, booking and form alerts have nowhere to go —`,` `,(0,i.jsx)(t.rt,{onClick:n,children:`add ADMIN_EMAILS`}),`.`]})]})}function ff(){let{status:e,error:n,reread:a}=ll(),o=nl(`email`),[s,c]=(0,r.useState)(``),l=af(),[u,d]=(0,r.useState)(!1),[f,p]=(0,r.useState)(!1),m=()=>{d(!1),a().then(()=>p(!0))},h=!!(e&&!e.configured),g=sf(e?.from),_=lf(o.on),v=!l.loading&&rf(l.testedFrom,e?.from);return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(we,{children:`Email`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/email`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col min-h-[600px]`,children:!e&&!n?(0,i.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,i.jsx)(t.ei,{className:`w-6 h-6 animate-spin text-accent`})}):h?(0,i.jsx)(Wl,{icon:t.Xr,title:`Connect email`,description:`This app is not sending email yet.`,stepsDescription:`Three steps — a key, two secrets, and the domain your mail goes out as.`,button:`Set up email`,secret:`RESEND_API_KEY`,open:u,onOpen:()=>d(!0),confirmed:f,steps:(0,i.jsx)(Kl,{onConfirm:m}),children:(0,i.jsx)(t.st,{children:`Email runs through Resend, and connecting it is two pasted rows — a key, and your own address for the mail that is meant for you. Once they are in, this screen fills itself: what your app can do with email, and where it goes.`})}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,i.jsx)(t.ut,{icon:t.Vr,title:`Send email`,description:_.description,chip:_.chip,enabled:o.loading?null:o.on,onChange:async e=>c(await o.set(e)||``),children:s?(0,i.jsx)(t.st,{tone:`error`,children:s}):null}),(0,i.jsx)(t.at,{icon:t.Zr,title:`Connection`,description:v&&!n?`Mail goes out as ${e?.from}.`:`Whether this app can send email right now.`,defaultOpen:!v||!e?.adminCount,actions:n?(0,i.jsx)(t.lt,{state:`error`,label:`Unreachable`}):(0,i.jsx)(t.lt,{state:`saved`,label:`Connected`}),children:n?(0,i.jsx)(t.st,{tone:`error`,children:n}):(0,i.jsxs)(i.Fragment,{children:[!v&&(0,i.jsxs)(t.st,{children:[`Mail goes out as `,(0,i.jsx)(`span`,{className:`font-bold text-foreground/70`,children:e?.from}),`.`,g?` That is Resend’s shared practice address: it delivers only to the address you made your Resend account with, so a test to yourself works and a customer’s email does not arrive. Before anyone else should get one, verify your own domain in Resend and add EMAIL_FROM — `:` That only works if ${cf(e?.from)} is verified under Domains in your Resend account — an unverified domain makes every send fail. Every send also appears in your Resend dashboard, with nothing to sync.`,g&&(0,i.jsx)(t.rt,{onClick:()=>d(!0),children:`show me how`}),g&&`.`]}),(0,i.jsx)(df,{adminCount:e?.adminCount||0,onSetUp:()=>d(!0)}),u&&(0,i.jsx)(`div`,{className:`px-1 pt-1`,children:(0,i.jsx)(Kl,{onConfirm:m})}),!v&&(0,i.jsx)(`div`,{className:`px-1`,children:(0,i.jsx)(ef,{onSent:t=>l.mark(t||e?.from||``),trailing:(0,i.jsxs)(`a`,{href:`https://resend.com/emails`,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1.5 text-[12px] font-bold text-accent hover:underline`,children:[`See everything sent, in Resend`,(0,i.jsx)(t._i,{className:`w-3 h-3`})]})})})]})}),(0,i.jsx)(t.at,{icon:t.Mr,title:`What you can do with email`,description:`Each is switched on where it happens — a page on the Pages screen, a payment on the Payments screen.`,children:(0,i.jsx)(uf,{from:e?.from||``})})]})})]})]})}var pf=`src/your-ai-workflow-firebase-os`;function mf(){let e=new Set;for(let[t,n]of b()){let r=n?.config?.route,i=typeof r==`string`&&r.trim()?r.startsWith(`/`)?r:`/`+r:`/`+t.toLowerCase();e.add(i)}return[...e].sort()}var hf=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``);function gf(e){let t=e?.contentKey||e?.tabName||e?.pageName||e?.pageId||`Page`;return`${pf}/microcomponents/${hf(String(t))||`Page`}Content.tsx`}function _f(e,t){let n=t.replace(/^.*\//,``).replace(/\.tsx$/,``),r=n.replace(/Content$/,``).replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();return[`My app has a page at ${e} and it is still empty after you said it was done. The ONLY thing that fills this page is one file: ${t}, with a default export, registered in ${pf}/microcomponents/registry.ts.`,`Check these in order and fix whatever is wrong, without asking me questions:`,`1. The file exists at exactly that path and name — not another folder, not another spelling. If you put it somewhere else, move it there.`,`2. It has a default export. A named-only export is silently ignored.`,`3. ${pf}/microcomponents/registry.ts contains these two lines: import ${n} from './${n}'; and registerMicrocomponent('${r}', ${n}); — registerMicrocomponent is imported there from 'your-ai-workflow-firebase-os'. Add them if they are missing, and never remove another page's lines.`,`4. You created nothing else for this page — no config file, no route, no page, and no edit to src/App.tsx or src/main.tsx. Undo any of those you made.`,`Then tell me, in one sentence, which of these was wrong.`].join(`
|
|
670
|
+
`)}function vf(e){return[`The page at ${e} shows "Page Not Found". The app only finds a page when its config file is picked up, so check these in order and fix whatever is wrong, without asking me questions.`,`1. The page's config file sits directly in ${pf}/configs/ and its name ends with Tab.config.ts (a page for signed-in users, my team or admins) or Page.config.ts (a page for anyone). Not in a subfolder, not any other name.`,`2. It exports one const whose name ends with Config, and its route is the single string '${e}'. A page has exactly one web address — remove any other addresses you registered for it.`,`3. ${pf}/configs/pagesRegistry.ts exists and src/main.tsx contains the line import './your-ai-workflow-firebase-os/configs/pagesRegistry'. If either is missing, run npm install so the package's postinstall script restores them.`,`4. Put src/App.tsx back to the version the package wrote: it only mounts <FirebaseOS />. Never add routes, a router or the customRoutes prop.`,`5. If the page is for my team, its config says pageType: 'internal'. Any form on it is a *Form.config.ts file shown through <ContactPopup formId="..." />, never a form you wrote by hand.`,`Then rebuild and tell me, in one sentence, which of these was wrong.`].join(`
|
|
671
|
+
`)}function yf({config:e,customContent:n}){let{config:a}=t.Da(),{userRole:o}=t.Qi();return(0,r.useEffect)(()=>{document.title=e.pageName||e.pageTitle||a.appName||`Your AI Firebase`},[e.pageName,e.pageTitle,a.appName]),(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col relative min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[(0,i.jsx)(Gt,{}),(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(we,{children:e.pageTitle||e.pageName||`New Page`}),e.route&&(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})]}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`glass-panel border border-[var(--panel-border)] rounded-3xl shadow-2xl relative flex flex-col flex-1 bg-background/50 h-full min-h-[400px]`,children:n?(0,i.jsx)(`div`,{className:`fbos-content-slot flex-1 p-4 md:p-8`,children:(0,i.jsx)(n,{config:e})}):e.form?(0,i.jsx)(`div`,{className:`fbos-content-slot flex-1 flex flex-col items-center justify-start p-4 md:p-8`,children:(0,i.jsx)(t.t,{isInline:!0,formId:e.form})}):(0,i.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center m-4 md:m-8 gap-6`,children:[(0,i.jsxs)(`div`,{className:`w-full glass-panel border border-[var(--panel-border)]/50 border-dashed rounded-2xl p-8 py-16 text-center opacity-70`,children:[(0,i.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/70`,children:`This page is empty`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 max-w-sm leading-relaxed mx-auto`,children:`Open the Pages screen, say what you would like on it, and copy the sentence there into your assistant's chat.`})]}),t.la(o)&&(0,i.jsx)(`div`,{className:`w-full max-w-lg`,children:(0,i.jsx)(at,{compact:!0,title:`Already asked, and it is still empty? Paste this`,prompt:_f(e.route||`/`,gf(e))})})]})})]})}var bf=e=>`${e}files`;function xf(e){let t=/^https?:\/\/[^?#\s]*\/v0\/b\/[^/]+\/o\/([^?#\s]+)/.exec(e);if(!t)return``;try{return decodeURIComponent(t[1])}catch{return``}}function Sf(e,t){let n=new Set,r=e=>e.startsWith(`${t}/`)&&e.length>t.length+1,i=(e,t)=>{if(typeof e==`string`){let t=r(e)?e:xf(e);r(t)&&n.add(t)}else t<2&&Array.isArray(e)?e.forEach(e=>i(e,t+1)):t<2&&e&&typeof e==`object`&&Object.values(e).forEach(e=>i(e,t+1))};return i(e,0),[...n]}async function Cf(e,n,r){if(!e)return;let i=new Set(n.filter(t=>t.id!==e.id).flatMap(e=>Sf(e,r)));await Promise.all(Sf(e,r).filter(e=>!i.has(e)).map(e=>(0,s.deleteObject)((0,s.ref)(t.Ta,e)).catch(t=>{console.warn(`${e}: the record is gone but its file stayed (${t?.code||t}).`)})))}function wf({config:e,customContent:n}){let{user:a}=t.Qi(),{config:c}=t.Da(),[u,d]=(0,r.useState)([]),[f,p]=(0,r.useState)(!0),[m,h]=(0,r.useState)(!1),[g,_]=(0,r.useState)(``),[v,y]=(0,r.useState)(``),[b,x]=(0,r.useState)(!1),[S,C]=(0,r.useState)(null),w=(0,r.useRef)(null),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(null),[k,A]=(0,r.useState)(null),j=e=>{if(A(e),e){let t=e.fileType||``;P(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},M=k,[N,P]=(0,r.useState)(!0),[F,I]=(0,r.useState)(!1),[L,R]=(0,r.useState)(null),[z,B]=(0,r.useState)(``),[V,H]=(0,r.useState)(``),[U,W]=(0,r.useState)([]),G=(0,r.useRef)(null),ee=(e.tabName||e.pageId||`user_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`),K=t.ma({...e,pageType:`user`}),q=`${K}${ee}_records`,J=K.startsWith(`role_`),Y=bf(K);(0,r.useEffect)(()=>{document.title=e.tabTitle||e.tabName||c.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,c.appName]),(0,r.useEffect)(()=>{if(!a)return;try{let e=Kr(q,a.uid);e?(d(e),p(!1)):p(!0)}catch{}let e=e=>e.map(e=>{let t=e.data();return{id:e.id,...t,createdAt:t.createdAt?.toMillis?t.createdAt.toMillis():t.createdAt}}),n=(0,o.onSnapshot)(J?(0,o.query)((0,o.collection)(t.Ca,q),(0,o.limit)(150)):(0,o.query)((0,o.collection)(t.Ca,q),(0,o.where)(`uid`,`==`,a.uid),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),d(n),p(!1),qr(q,a.uid,n)},e=>{console.warn(`${q}: this account cannot read its records here (${e?.code||`permission-denied`}). Signed-in pages need a verified email address; the records themselves are only ever the signer's own.`),d(e=>e.length?[]:e),p(!1)});return()=>n()},[a,q,J]),(0,r.useEffect)(()=>{!f&&a&&qr(q,a.uid,u)},[u,f,q,a]);let X=async e=>{if(e.preventDefault(),!(!a||!g.trim())){x(!0);try{let e=await(0,o.addDoc)((0,o.collection)(t.Ca,q),{name:g.trim(),note:v.trim(),uid:a.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)()});d(t=>[{id:e.id,name:g.trim(),note:v.trim(),uid:a.uid,recordType:`record`,createdAt:Date.now()},...t]),_(``),y(``),h(!1)}catch(e){console.error(`Error saving record:`,e)}x(!1)}},te=async e=>{let n=e.target.files?.[0];if(!n||!a)return;let r=await t.or(n);E(!0);try{let e=`${Y}/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,n=(0,s.ref)(t.Ta,e);await(0,s.uploadBytes)(n,r,{customMetadata:{ownerId:a.uid}});let i=await(0,s.getDownloadURL)(n);if(w.current)w.current(r,i,{uid:a.uid,storagePath:e});else{let n=await(0,o.addDoc)((0,o.collection)(t.Ca,q),{name:r.name,note:`${r.type||`File`} · ${_e(r.size)}`,uid:a.uid,recordType:`file`,fileName:r.name,fileType:r.type||`unknown`,fileSize:r.size,downloadURL:i,storagePath:e,createdAt:(0,o.serverTimestamp)()});d(t=>[{id:n.id,name:r.name,note:`${r.type||`File`} · ${_e(r.size)}`,uid:a.uid,recordType:`file`,fileName:r.name,fileType:r.type,fileSize:r.size,downloadURL:i,storagePath:e,createdAt:Date.now()},...t])}}catch(e){console.error(`Error uploading file:`,e)}E(!1),G.current&&(G.current.value=``)},ne=async()=>{if(D){I(!0);try{let e=u.find(e=>e.id===D);await(0,o.deleteDoc)((0,o.doc)(t.Ca,q,D)),await Cf(e,u,Y),d(e=>e.filter(e=>e.id!==D)),O(null)}catch(e){console.error(`Error deleting record:`,e)}I(!1)}},[re,Z]=(0,r.useState)(null),[Q,ie]=(0,r.useState)(``),[ae,oe]=(0,r.useState)(!1),[se,ce]=(0,r.useState)(null),le=(0,r.useRef)([]),ue=e=>{if(e.recordType===`file`){Z(e.id),ie(e.name);return}R(e.id),B(e.name),H(e.note||``);let t=[`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`storagePath`,`createdAt`],n=Object.entries(e).filter(([e])=>!t.includes(e)&&e!==`id`).map(([e,t])=>({key:e,value:String(t??``)}));W(n),le.current=n.map(e=>e.key)},de=async()=>{if(!re||!Q.trim()){Z(null);return}let e=u.find(e=>e.id===re);if(e&&e.name===Q.trim()){Z(null);return}oe(!0);try{await(0,o.updateDoc)((0,o.doc)(t.Ca,q,re),{name:Q.trim()}),d(e=>e.map(e=>e.id===re?{...e,name:Q.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}oe(!1),Z(null)},fe=async()=>{await pe(),R(null)},pe=async()=>{if(!L||!z.trim())return;x(!0);let e={};U.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let n=U.map(e=>e.key.trim()).filter(Boolean),r=le.current.filter(e=>!n.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(t.Ca,q,L),{name:z.trim(),note:V.trim(),...e}),d(e=>e.map(e=>{if(e.id!==L)return e;let t={...e,name:z.trim(),note:V.trim()};return r.forEach(e=>{delete t[e]}),U.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),le.current=n}catch(e){console.error(`Error saving record:`,e)}x(!1)},me=(e,n)=>e?e.startsWith(`image/`)?n?(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${n})`}}):(0,i.jsx)(t.li,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,i.jsx)(t.br,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,i.jsx)(t.pi,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,i.jsx)(t.Xi,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,i.jsx)(t.Ci,{className:`w-4 h-4`}):(0,i.jsx)(t.fi,{className:`w-4 h-4`}):(0,i.jsx)(t.pi,{className:`w-4 h-4`}),he=e=>e?e.startsWith(`image/`)?`bg-emerald-500/10 text-emerald-500`:e.startsWith(`video/`)||e.startsWith(`audio/`)?`bg-accent/10 text-accent`:e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?`bg-blue-500/10 text-blue-500`:e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?`bg-yellow-500/10 text-yellow-500`:e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?`bg-emerald-500/10 text-emerald-500`:`bg-foreground/5 text-foreground/40`:`bg-foreground/5 text-foreground/40`,ge=e=>{if(!e)return`FILE`;let t={"application/pdf":`PDF`,"application/zip":`ZIP`,"application/x-zip-compressed":`ZIP`,"application/x-rar-compressed":`RAR`,"application/x-7z-compressed":`7Z`,"application/json":`JSON`,"application/xml":`XML`,"application/javascript":`JS`,"application/typescript":`TS`,"application/msword":`DOC`,"application/vnd.openxmlformats-officedocument.wordprocessingml.document":`DOCX`,"application/vnd.ms-excel":`XLS`,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":`XLSX`,"application/vnd.ms-powerpoint":`PPT`,"application/vnd.openxmlformats-officedocument.presentationml.presentation":`PPTX`,"application/rtf":`RTF`,"application/x-tar":`TAR`,"application/gzip":`GZ`,"text/plain":`TXT`,"text/html":`HTML`,"text/css":`CSS`,"text/csv":`CSV`,"text/markdown":`MD`},n=e.toLowerCase();if(t[n])return t[n];let r=n.split(`/`);return r[r.length-1].replace(/^x-/,``).replace(/^vnd\..*\./,``).toUpperCase().slice(0,10)},_e=e=>{if(!e)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**+r).toFixed(2))+` `+n[r]},ve=e=>{if(!e)return``;let t=e.toMillis?e.toMillis():e;return new Date(t).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})},ye=(()=>{let n=(e.buttonStorageIcon||`upload`).trim(),r=n.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return t.mr[r]?t.mr[r]:t.mr[n]?t.mr[n]:t.wr||t.Hr})(),be=e.buttonStyle!==`secondary`,xe=e.buttonStorageStyle===`primary`;return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(we,{children:e.tabTitle||e.tabName||`User Page`}),e.route&&(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background`,children:[(0,i.jsx)(`input`,{type:`file`,ref:G,onChange:te,className:`hidden`}),!n&&(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4 p-4 sm:p-6 md:px-8 md:py-6 border-b border-[var(--panel-border)]/50 bg-background/50 shrink-0`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:f?`Loading…`:`${u.length} ${u.length===1?`item`:`items`}`})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,i.jsx)(i.Fragment,{children:(0,i.jsxs)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>G.current?.click(),disabled:T,title:e.buttonStorageText||`Upload File`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed ${e.buttonStorageText?`px-4`:`w-10`} ${xe?`btn-primary`:`btn-secondary`}`,children:[T?(0,i.jsx)(t.ei,{className:`w-4 h-4 animate-spin`}):(0,i.jsx)(ye,{className:`w-4 h-4`}),e.buttonStorageText&&(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>h(!0),title:`Add New`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer ${e.buttonText&&e.buttonText!==`+`?`px-5`:`w-10`} ${be?`btn-primary`:`btn-secondary`}`,children:e.buttonText===`+`||!e.buttonText?(0,i.jsx)(t.Hr,{className:`w-4 h-4`}):(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,i.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[f&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,i.jsx)(t.ei,{className:`w-8 h-8 text-accent animate-spin`})}),n?(0,i.jsx)(`div`,{className:`fbos-content-slot`,children:(0,i.jsx)(n,{config:e,actions:{records:u,loading:f,collection:q,user:a,saveRecord:async e=>{let n=(0,o.doc)((0,o.collection)(t.Ca,q)),r={id:n.id,uid:a.uid,recordType:`record`,createdAt:Date.now(),...e};d(e=>[r,...e]),await(0,o.setDoc)(n,{uid:a.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,n)=>{d(t=>t.map(t=>t.id===e?{...t,...n}:t)),await(0,o.updateDoc)((0,o.doc)(t.Ca,q,e),n)},deleteRecord:async e=>{let n=u.find(t=>t.id===e);await(0,o.deleteDoc)((0,o.doc)(t.Ca,q,e)),await Cf(n,u,Y)},startEdit:e=>ue(e),confirmDelete:e=>O(e),uploadFile:()=>G.current?.click(),openAddForm:()=>h(!0),setAddForm:e=>C(()=>e),setFileHandler:e=>{w.current=e}}})}):(0,i.jsxs)(i.Fragment,{children:[!f&&u.length===0&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex-1 flex flex-col items-center justify-center border border-[var(--panel-border)]/50 border-dashed rounded-2xl p-8 py-20 text-center min-h-[350px]`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-2xl bg-accent/5 border border-accent/10 flex items-center justify-center mb-5`,children:(0,i.jsx)(t.Hr,{className:`w-6 h-6 text-accent/40`})}),(0,i.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/35 max-w-xs leading-relaxed`,children:`Use the buttons above to add records or upload files to get started`})]}),!f&&u.length>0&&(0,i.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,i.jsx)(t.pr,{children:u.map((e,n)=>{let r=L===e.id;return(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},transition:{delay:n*.03,duration:.25},onClick:()=>ue(e),className:`group flex flex-col bg-background border rounded-2xl p-5 transition-all relative cursor-pointer ${r?`border-accent/40 shadow-lg ring-1 ring-accent/20`:`border-[var(--panel-border)] hover:border-accent/30 hover:shadow-lg`}`,children:[(0,i.jsxs)(`div`,{className:`absolute top-3 right-3 flex items-center gap-0.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-all z-10`,children:[e.recordType===`file`&&e.downloadURL&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),ce(e.id),setTimeout(()=>ce(null),2e3)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-emerald-500 hover:bg-emerald-500/10 transition-all cursor-pointer`,title:`Copy Link`,children:se===e.id?(0,i.jsx)(t.Fi,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,i.jsx)(t.ni,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`a`,{href:e.downloadURL,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),className:`p-1.5 rounded-lg text-foreground/25 hover:text-blue-500 hover:bg-blue-500/10 transition-all`,title:`Download`,children:(0,i.jsx)(t.yi,{className:`w-3.5 h-3.5`})})]}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),ue(e)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-accent hover:bg-accent/10 transition-all cursor-pointer`,title:`Edit`,children:(0,i.jsx)(t.Gr,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),O(e.id)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-red-500 hover:bg-red-500/10 transition-all cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-3.5 h-3.5`})})]}),(0,i.jsxs)(`div`,{className:`flex items-start gap-3 mb-3`,children:[(0,i.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&j(e)},className:`w-9 h-9 rounded-xl flex items-center justify-center shrink-0 ${e.recordType===`file`?`cursor-pointer hover:scale-105 transition-transform ${he(e.fileType)}`:`bg-accent/10 text-accent`}`,children:e.recordType===`file`?me(e.fileType,e.downloadURL):(0,i.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[re===e.id?(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,value:Q,onChange:e=>ie(e.target.value),onBlur:()=>de(),onKeyDown:e=>{e.key===`Enter`&&de(),e.key===`Escape`&&Z(null)},onClick:e=>e.stopPropagation(),className:`no-glow text-[14px] font-bold text-foreground bg-transparent border-b border-accent/30 outline-none pb-0.5 w-full pr-12`}):(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>j(e)}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:ve(e.createdAt)})]})]}),e.note&&(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/55 font-medium leading-relaxed line-clamp-3 mb-1`,children:e.note}),Object.entries(e).filter(([e])=>![`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`createdAt`,`creatorName`,`creatorEmail`,`creatorAvatar`].includes(e)&&e!==`id`).slice(0,3).map(([e,t])=>(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,i.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e))]},e.id)})})})]})]})]})]}),(0,i.jsx)(t.pr,{children:m&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>!b&&h(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[360px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:S?r.default.createElement(S,{onSave:async e=>{x(!0);try{await(0,o.addDoc)((0,o.collection)(t.Ca,q),{uid:a.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)(),...e}),h(!1)}catch(e){console.error(`Error saving record:`,e)}x(!1)},onClose:()=>!b&&h(!1),saving:b}):(0,i.jsxs)(`form`,{onSubmit:X,className:`p-5 flex flex-col gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>!b&&h(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:g,onChange:e=>_(e.target.value),placeholder:`Name *`,disabled:b,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-semibold text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`textarea`,{value:v,onChange:e=>y(e.target.value),placeholder:`Note (optional)`,disabled:b,rows:2,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-medium text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30 resize-none`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,i.jsx)(t.cr,{type:`submit`,isLoading:b,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:b?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,l.createPortal)((0,i.jsx)(t.pr,{children:M&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>j(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(`button`,{onClick:()=>j(null),className:`absolute top-6 right-6 z-[160] w-12 h-12 bg-foreground/10 hover:bg-foreground/20 text-foreground rounded-full flex items-center justify-center backdrop-blur-md transition-all cursor-pointer outline-none`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`relative z-10 w-full max-w-6xl max-h-[85vh] flex flex-col pointer-events-auto shadow-2xl rounded-3xl overflow-hidden glass-panel border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between p-6 bg-background/80 backdrop-blur-md border-b border-[var(--panel-border)] shrink-0 shadow-sm z-20`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,i.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:M.fileName||M.name}),(0,i.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[ge(M.fileType),` • `,_e(M.fileSize||0)]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(M.downloadURL),ce(`preview`),setTimeout(()=>ce(null),2e3)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 transition-colors rounded-xl shadow-sm hover:text-emerald-500 cursor-pointer`,title:`Copy Link`,children:se===`preview`?(0,i.jsx)(t.Fi,{className:`w-4 h-4 text-emerald-500`}):(0,i.jsx)(t.ni,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),Z(M.id),ie(M.name)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 hover:text-accent transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Rename`,children:(0,i.jsx)(t.Gr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),O(M.id)},className:`p-2.5 bg-red-500/10 hover:bg-red-500/20 text-red-500 transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})}),(0,i.jsx)(`a`,{href:M.downloadURL,download:!0,target:`_blank`,rel:`noreferrer`,className:`p-2.5 btn-primary transition-colors rounded-xl shadow-lg ml-1`,title:`Download`,children:(0,i.jsx)(t.yi,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>j(null),children:(0,i.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[N&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,i.jsx)(`div`,{className:`w-12 h-12 rounded-full bg-background/80 backdrop-blur-md shadow-xl flex items-center justify-center border border-[var(--panel-border)]/50`,children:(0,i.jsx)(t.ei,{className:`w-5 h-5 text-accent animate-spin`})})}),M.fileType?.startsWith(`image/`)?(0,i.jsx)(`img`,{onLoad:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,alt:M.fileName||M.name,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full object-contain drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] rounded-lg pointer-events-auto transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType?.startsWith(`video/`)?(0,i.jsx)(`video`,{onLoadedData:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,controls:!0,autoPlay:!0,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full outline-none bg-black/40 rounded-lg pointer-events-auto drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType===`application/pdf`?(0,i.jsx)(`iframe`,{onLoad:()=>P(!1),src:M.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,i.jsxs)(`div`,{className:`w-full h-full flex flex-col items-center justify-center text-foreground/40 text-center relative z-10`,onClick:e=>{e.stopPropagation(),P(!1)},children:[(0,i.jsx)(t.pi,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,i.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,i.jsx)(`span`,{className:`text-[14px] mt-2 text-foreground/60 font-medium max-w-xs`,children:`This file format cannot be previewed. Please download it instead.`})]})]})})]})]})}),document.body),(0,i.jsx)(t.pr,{children:L&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>fe(),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[440px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:(0,i.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),b&&(0,i.jsx)(t.ei,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>fe(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NAME`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`input`,{autoFocus:!0,required:!0,value:z,onChange:e=>B(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>pe(),placeholder:`Name *`,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NOTE`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:V,onChange:e=>{H(e.target.value),e.target.style.height=`auto`,e.target.style.height=e.target.scrollHeight+`px`},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),e.target.blur())},onBlur:()=>pe(),placeholder:`Add a note...`,rows:1,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50 resize-none overflow-hidden`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),U.map((e,n)=>(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let t=[...U];t[n].key=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>pe(),className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none placeholder:text-foreground/15 pt-3 pb-0.5 caret-foreground/40`}),(0,i.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let t=[...U];t[n].value=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>pe(),className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pt-1.5 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>W(U.filter((e,t)=>t!==n)),className:`absolute top-3 right-0 p-1 text-foreground/0 group-hover/field:text-foreground/20 hover:!text-red-400 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})})]},n)),(0,i.jsxs)(`button`,{type:`button`,onClick:()=>W([...U,{key:``,value:``}]),className:`flex items-center gap-1.5 text-[11px] font-medium text-foreground/25 hover:text-foreground/40 transition-colors cursor-pointer mt-4 mb-4`,children:[(0,i.jsx)(t.Hr,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,i.jsx)(He,{isOpen:!!D,onCancel:()=>O(null),onConfirm:ne,title:`Delete Record`,message:(0,i.jsxs)(i.Fragment,{children:[`Are you sure you want to delete `,(0,i.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:u.find(e=>e.id===D)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:F})]})}function Tf({config:e,customContent:n}){let{user:a}=t.Qi(),{config:c}=t.Da(),[u,d]=(0,r.useState)([]),[f,p]=(0,r.useState)(!0),[m,h]=(0,r.useState)(!1),[g,_]=(0,r.useState)(``),[v,y]=(0,r.useState)(``),[b,x]=(0,r.useState)(!1),[S,C]=(0,r.useState)(null),w=(0,r.useRef)(null),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(null),[k,A]=(0,r.useState)(null),j=e=>{if(A(e),e){let t=e.fileType||``;P(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},M=k,[N,P]=(0,r.useState)(!0),[F,I]=(0,r.useState)(!1),[L,R]=(0,r.useState)(null),[z,B]=(0,r.useState)(``),[V,H]=(0,r.useState)(``),[U,W]=(0,r.useState)([]),G=(0,r.useRef)(null),[ee,K]=(0,r.useState)(null),q=(0,r.useRef)([]),J=`admin_${(e.tabName||e.pageId||`admin_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`)}_records`,Y=bf(`admin_`);(0,r.useEffect)(()=>{document.title=e.tabTitle||e.tabName||c.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,c.appName]);let X=()=>({name:a.displayName||a.email?.split(`@`)[0]||`Admin`,email:a.email||``,avatar:a.photoURL||``});(0,r.useEffect)(()=>{if(!a)return;try{let e=Kr(J,a.uid);e?(d(e),p(!1)):p(!0)}catch{}let e=e=>e.map(e=>{let t=e.data();return{id:e.id,...t,createdAt:t.createdAt?.toMillis?t.createdAt.toMillis():t.createdAt}}),n=(0,o.onSnapshot)((0,o.query)((0,o.collection)(t.Ca,J),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(150)),t=>{let n=e(t.docs);d(n),p(!1),qr(J,a.uid,n)},n=>{console.error(`Error listening to admin records:`,n);let r=(0,o.onSnapshot)((0,o.query)((0,o.collection)(t.Ca,J),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),d(n),p(!1),qr(J,a.uid,n)});return()=>r()});return()=>n()},[a,J]);let te=async e=>{if(e.preventDefault(),!(!a||!g.trim())){x(!0);try{let e=X();await(0,o.addDoc)((0,o.collection)(t.Ca,J),{name:g.trim(),note:v.trim(),uid:a.uid,recordType:`record`,creatorName:e.name,creatorEmail:e.email,creatorAvatar:e.avatar,createdAt:(0,o.serverTimestamp)()}),_(``),y(``),h(!1)}catch(e){console.error(`Error saving admin record:`,e)}x(!1)}},ne=async e=>{let n=e.target.files?.[0];if(!n||!a)return;let r=await t.or(n);E(!0);try{let e=`${Y}/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,n=(0,s.ref)(t.Ta,e);await(0,s.uploadBytes)(n,r,{customMetadata:{ownerId:a.uid}});let i=await(0,s.getDownloadURL)(n);if(w.current)w.current(r,i,{uid:a.uid,storagePath:e});else{let n=X();await(0,o.addDoc)((0,o.collection)(t.Ca,J),{name:r.name,note:`${r.type||`File`} · ${he(r.size)}`,uid:a.uid,recordType:`file`,fileName:r.name,fileType:r.type||`unknown`,fileSize:r.size,downloadURL:i,storagePath:e,creatorName:n.name,creatorEmail:n.email,creatorAvatar:n.avatar,createdAt:(0,o.serverTimestamp)()})}}catch(e){console.error(`Error uploading admin file:`,e)}E(!1),G.current&&(G.current.value=``)},re=async()=>{if(D){I(!0);try{let e=u.find(e=>e.id===D);await(0,o.deleteDoc)((0,o.doc)(t.Ca,J,D)),await Cf(e,u,Y),O(null)}catch(e){console.error(`Error deleting admin record:`,e)}I(!1)}},[Z,Q]=(0,r.useState)(null),[ie,ae]=(0,r.useState)(``),[oe,se]=(0,r.useState)(!1),ce=e=>{if(e.recordType===`file`){Q(e.id),ae(e.name);return}R(e.id),B(e.name),H(e.note||``);let t=[`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`storagePath`,`createdAt`,`creatorName`,`creatorEmail`,`creatorAvatar`],n=Object.entries(e).filter(([e])=>!t.includes(e)&&e!==`id`).map(([e,t])=>({key:e,value:String(t??``)}));W(n),q.current=n.map(e=>e.key)},le=async()=>{if(!Z||!ie.trim()){Q(null);return}let e=u.find(e=>e.id===Z);if(e&&e.name===ie.trim()){Q(null);return}se(!0);try{await(0,o.updateDoc)((0,o.doc)(t.Ca,J,Z),{name:ie.trim()}),d(e=>e.map(e=>e.id===Z?{...e,name:ie.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}se(!1),Q(null)},ue=async()=>{if(!L||!z.trim()){R(null);return}x(!0);let e={};U.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let n=U.map(e=>e.key.trim()).filter(Boolean),r=q.current.filter(e=>!n.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(t.Ca,J,L),{name:z.trim(),note:V.trim(),...e}),d(e=>e.map(e=>{if(e.id!==L)return e;let t={...e,name:z.trim(),note:V.trim()};return r.forEach(e=>{delete t[e]}),U.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),q.current=n}catch(e){console.error(`Error updating record:`,e)}x(!1),R(null)},de=async()=>{if(!L||!z.trim())return;let e={};U.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let n=U.map(e=>e.key.trim()).filter(Boolean),r=q.current.filter(e=>!n.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(t.Ca,J,L),{name:z.trim(),note:V.trim(),...e}),d(e=>e.map(e=>{if(e.id!==L)return e;let t={...e,name:z.trim(),note:V.trim()};return r.forEach(e=>{delete t[e]}),U.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),q.current=n}catch(e){console.error(`Error silently saving record:`,e)}},fe=(e,n)=>e?e.startsWith(`image/`)?n?(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${n})`}}):(0,i.jsx)(t.li,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,i.jsx)(t.br,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,i.jsx)(t.pi,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,i.jsx)(t.Xi,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,i.jsx)(t.Ci,{className:`w-4 h-4`}):(0,i.jsx)(t.fi,{className:`w-4 h-4`}):(0,i.jsx)(t.pi,{className:`w-4 h-4`}),pe=e=>e?e.startsWith(`image/`)?`bg-emerald-500/10 text-emerald-500`:e.startsWith(`video/`)||e.startsWith(`audio/`)?`bg-accent/10 text-accent`:e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?`bg-blue-500/10 text-blue-500`:e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?`bg-yellow-500/10 text-yellow-500`:e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?`bg-emerald-500/10 text-emerald-500`:`bg-foreground/5 text-foreground/40`:`bg-foreground/5 text-foreground/40`,me=e=>{if(!e)return`FILE`;let t={"application/pdf":`PDF`,"application/zip":`ZIP`,"application/x-zip-compressed":`ZIP`,"application/x-rar-compressed":`RAR`,"application/x-7z-compressed":`7Z`,"application/json":`JSON`,"application/xml":`XML`,"application/javascript":`JS`,"application/typescript":`TS`,"application/msword":`DOC`,"application/vnd.openxmlformats-officedocument.wordprocessingml.document":`DOCX`,"application/vnd.ms-excel":`XLS`,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":`XLSX`,"application/vnd.ms-powerpoint":`PPT`,"application/vnd.openxmlformats-officedocument.presentationml.presentation":`PPTX`,"application/rtf":`RTF`,"application/x-tar":`TAR`,"application/gzip":`GZ`,"text/plain":`TXT`,"text/html":`HTML`,"text/css":`CSS`,"text/csv":`CSV`,"text/markdown":`MD`},n=e.toLowerCase();if(t[n])return t[n];let r=n.split(`/`);return r[r.length-1].replace(/^x-/,``).replace(/^vnd\..*\./,``).toUpperCase().slice(0,10)},he=e=>{if(!e)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**+r).toFixed(2))+` `+n[r]},ge=e=>{if(!e)return``;let t=e.toMillis?e.toMillis():e;return new Date(t).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})},_e=(()=>{let n=(e.buttonStorageIcon||`upload`).trim(),r=n.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return t.mr[r]?t.mr[r]:t.mr[n]?t.mr[n]:t.wr||t.Hr})(),ve=e.buttonStyle!==`secondary`,ye=e.buttonStorageStyle===`primary`,be=e=>e.uid===a?.uid,xe=({record:e})=>{let t=e.creatorName||e.creatorEmail?.split(`@`)[0]||`Admin`,n=e.creatorEmail||``,r=e.creatorAvatar||``,a=t.split(` `).map(e=>e[0]).join(``).toUpperCase().slice(0,2);return(0,i.jsxs)(`div`,{className:`flex items-center gap-2 mt-2 pt-2 border-t border-[var(--panel-border)]/30`,children:[r?(0,i.jsx)(`img`,{src:r,alt:``,className:`w-5 h-5 rounded-full object-cover shrink-0`}):(0,i.jsx)(`div`,{className:`w-5 h-5 rounded-full bg-accent/15 text-accent flex items-center justify-center text-[8px] font-extrabold shrink-0`,children:a}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 truncate`,children:t}),n&&(0,i.jsxs)(`span`,{className:`text-[10px] text-foreground/25 truncate`,children:[`· `,n]})]})]})};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(we,{children:e.tabTitle||e.tabName||`Admin Page`}),e.route&&(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background`,children:[(0,i.jsx)(`input`,{type:`file`,ref:G,onChange:ne,className:`hidden`}),!n&&(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4 p-4 sm:p-6 md:px-8 md:py-6 border-b border-[var(--panel-border)]/50 bg-background/50 shrink-0`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:f?`Loading…`:`${u.length} ${u.length===1?`item`:`items`}`})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,i.jsx)(i.Fragment,{children:(0,i.jsxs)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>G.current?.click(),disabled:T,title:e.buttonStorageText||`Upload File`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed ${e.buttonStorageText?`px-4`:`w-10`} ${ye?`btn-primary`:`btn-secondary`}`,children:[T?(0,i.jsx)(t.ei,{className:`w-4 h-4 animate-spin`}):(0,i.jsx)(_e,{className:`w-4 h-4`}),e.buttonStorageText&&(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>h(!0),title:`Add New`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer ${e.buttonText&&e.buttonText!==`+`?`px-5`:`w-10`} ${ve?`btn-primary`:`btn-secondary`}`,children:e.buttonText===`+`||!e.buttonText?(0,i.jsx)(t.Hr,{className:`w-4 h-4`}):(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,i.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[f&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,i.jsx)(t.ei,{className:`w-8 h-8 text-accent animate-spin`})}),n?(0,i.jsx)(`div`,{className:`fbos-content-slot`,children:(0,i.jsx)(n,{config:e,actions:{records:u,loading:f,collection:J,user:a,saveRecord:async e=>{let n=(0,o.doc)((0,o.collection)(t.Ca,J)),r=X(),i={id:n.id,uid:a.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:Date.now(),...e};d(e=>[i,...e]),await(0,o.setDoc)(n,{uid:a.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,n)=>{d(t=>t.map(t=>t.id===e?{...t,...n}:t)),await(0,o.updateDoc)((0,o.doc)(t.Ca,J,e),n)},deleteRecord:async e=>{let n=u.find(t=>t.id===e);await(0,o.deleteDoc)((0,o.doc)(t.Ca,J,e)),await Cf(n,u,Y)},startEdit:e=>ce(e),confirmDelete:e=>O(e),uploadFile:()=>G.current?.click(),openAddForm:()=>h(!0),setAddForm:e=>C(()=>e),setFileHandler:e=>{w.current=e}}})}):(0,i.jsxs)(i.Fragment,{children:[!f&&u.length===0&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex-1 flex flex-col items-center justify-center border border-[var(--panel-border)]/50 border-dashed rounded-2xl p-8 py-20 text-center min-h-[350px]`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-2xl bg-accent/5 border border-accent/10 flex items-center justify-center mb-5`,children:(0,i.jsx)(t.Hr,{className:`w-6 h-6 text-accent/40`})}),(0,i.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/35 max-w-xs leading-relaxed`,children:`Use the buttons above to add records or upload files. All admins can view and contribute.`})]}),!f&&u.length>0&&(0,i.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,i.jsx)(t.pr,{children:u.map((e,n)=>{let r=L===e.id,a=be(e);return(0,i.jsxs)(t.fr.div,{initial:!1,animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},onClick:()=>ce(e),className:`group flex flex-col bg-background border rounded-2xl p-5 transition-all relative cursor-pointer ${r?`border-accent/40 shadow-lg ring-1 ring-accent/20`:`border-[var(--panel-border)] hover:border-accent/30 hover:shadow-lg`}`,children:[(0,i.jsxs)(`div`,{className:`absolute top-3 right-3 flex items-center gap-0.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-all z-10`,children:[e.recordType===`file`&&e.downloadURL&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),K(e.id),setTimeout(()=>K(null),2e3)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-emerald-500 hover:bg-emerald-500/10 transition-all cursor-pointer`,title:`Copy Link`,children:ee===e.id?(0,i.jsx)(t.Fi,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,i.jsx)(t.ni,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`a`,{href:e.downloadURL,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),className:`p-1.5 rounded-lg text-foreground/25 hover:text-blue-500 hover:bg-blue-500/10 transition-all`,title:`Download`,children:(0,i.jsx)(t.yi,{className:`w-3.5 h-3.5`})})]}),a&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),ce(e)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-accent hover:bg-accent/10 transition-all cursor-pointer`,title:`Edit`,children:(0,i.jsx)(t.Gr,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),O(e.id)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-red-500 hover:bg-red-500/10 transition-all cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-3.5 h-3.5`})})]})]}),(0,i.jsxs)(`div`,{className:`flex items-start gap-3 mb-2`,children:[(0,i.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&j(e)},className:`w-9 h-9 rounded-xl flex items-center justify-center shrink-0 ${e.recordType===`file`?`cursor-pointer hover:scale-105 transition-transform ${pe(e.fileType)}`:`bg-accent/10 text-accent`}`,children:e.recordType===`file`?fe(e.fileType,e.downloadURL):(0,i.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[Z===e.id?(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,value:ie,onChange:e=>ae(e.target.value),onBlur:()=>le(),onKeyDown:e=>{e.key===`Enter`&&le(),e.key===`Escape`&&Q(null)},onClick:e=>e.stopPropagation(),className:`no-glow text-[14px] font-bold text-foreground bg-transparent border-b border-accent/30 outline-none pb-0.5 w-full pr-12`}):(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>j(e)}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:ge(e.createdAt)})]})]}),e.note&&(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/55 font-medium leading-relaxed line-clamp-3 mb-1`,children:e.note}),Object.entries(e).filter(([e])=>![`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`createdAt`,`creatorName`,`creatorEmail`,`creatorAvatar`].includes(e)&&e!==`id`).slice(0,3).map(([e,t])=>(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,i.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e)),(0,i.jsx)(xe,{record:e})]},e.id)})})})]})]})]})]}),(0,i.jsx)(t.pr,{children:m&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>!b&&h(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[360px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:S?r.default.createElement(S,{onSave:async e=>{x(!0);try{let n=X();await(0,o.addDoc)((0,o.collection)(t.Ca,J),{uid:a.uid,recordType:`record`,creatorName:n.name,creatorEmail:n.email,creatorAvatar:n.avatar,createdAt:(0,o.serverTimestamp)(),...e}),h(!1)}catch(e){console.error(`Error saving record:`,e)}x(!1)},onClose:()=>!b&&h(!1),saving:b}):(0,i.jsxs)(`form`,{onSubmit:te,className:`p-5 flex flex-col gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>!b&&h(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:g,onChange:e=>_(e.target.value),placeholder:`Name *`,disabled:b,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-semibold text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`textarea`,{value:v,onChange:e=>y(e.target.value),placeholder:`Note (optional)`,disabled:b,rows:2,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-medium text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30 resize-none`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,i.jsx)(t.cr,{type:`submit`,isLoading:b,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:b?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,l.createPortal)((0,i.jsx)(t.pr,{children:M&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>j(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(`button`,{onClick:()=>j(null),className:`absolute top-6 right-6 z-[160] w-12 h-12 bg-foreground/10 hover:bg-foreground/20 text-foreground rounded-full flex items-center justify-center backdrop-blur-md transition-all cursor-pointer outline-none`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`relative z-10 w-full max-w-6xl max-h-[85vh] flex flex-col pointer-events-auto shadow-2xl rounded-3xl overflow-hidden glass-panel border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between p-6 bg-background/80 backdrop-blur-md border-b border-[var(--panel-border)] shrink-0 shadow-sm z-20`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,i.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:M.fileName||M.name}),(0,i.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[me(M.fileType),` • `,he(M.fileSize||0)]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(M.downloadURL),K(`preview`),setTimeout(()=>K(null),2e3)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 transition-colors rounded-xl shadow-sm hover:text-emerald-500 cursor-pointer`,title:`Copy Link`,children:ee===`preview`?(0,i.jsx)(t.Fi,{className:`w-4 h-4 text-emerald-500`}):(0,i.jsx)(t.ni,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),Q(M.id),ae(M.name)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 hover:text-accent transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Rename`,children:(0,i.jsx)(t.Gr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),O(M.id)},className:`p-2.5 bg-red-500/10 hover:bg-red-500/20 text-red-500 transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})}),(0,i.jsx)(`a`,{href:M.downloadURL,download:!0,target:`_blank`,rel:`noreferrer`,className:`p-2.5 btn-primary transition-colors rounded-xl shadow-lg ml-1`,title:`Download`,children:(0,i.jsx)(t.yi,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>j(null),children:(0,i.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[N&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,i.jsx)(`div`,{className:`w-12 h-12 rounded-full bg-background/80 backdrop-blur-md shadow-xl flex items-center justify-center border border-[var(--panel-border)]/50`,children:(0,i.jsx)(t.ei,{className:`w-5 h-5 text-accent animate-spin`})})}),M.fileType?.startsWith(`image/`)?(0,i.jsx)(`img`,{onLoad:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,alt:M.fileName||M.name,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full object-contain drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] rounded-lg pointer-events-auto transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType?.startsWith(`video/`)?(0,i.jsx)(`video`,{onLoadedData:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,controls:!0,autoPlay:!0,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full outline-none bg-black/40 rounded-lg pointer-events-auto drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType===`application/pdf`?(0,i.jsx)(`iframe`,{onLoad:()=>P(!1),src:M.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,i.jsxs)(`div`,{className:`w-full h-full flex flex-col items-center justify-center text-foreground/40 text-center relative z-10`,onClick:e=>{e.stopPropagation(),P(!1)},children:[(0,i.jsx)(t.pi,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,i.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,i.jsx)(`span`,{className:`text-[14px] mt-2 text-foreground/60 font-medium max-w-xs`,children:`This file format cannot be previewed. Please download it instead.`})]})]})})]})]})}),document.body),(0,i.jsx)(t.pr,{children:L&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>ue(),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[440px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:(0,i.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),b&&(0,i.jsx)(t.ei,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>ue(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NAME`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`input`,{autoFocus:!0,required:!0,value:z,onChange:e=>B(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>de(),placeholder:`Name *`,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NOTE`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:V,onChange:e=>{H(e.target.value),e.target.style.height=`auto`,e.target.style.height=e.target.scrollHeight+`px`},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),e.target.blur())},onBlur:()=>de(),placeholder:`Add a note...`,rows:1,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50 resize-none overflow-hidden`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),U.map((e,n)=>(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let t=[...U];t[n].key=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>de(),className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none placeholder:text-foreground/15 pt-3 pb-0.5 caret-foreground/40`}),(0,i.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let t=[...U];t[n].value=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>de(),className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pt-1.5 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>W(U.filter((e,t)=>t!==n)),className:`absolute top-3 right-0 p-1 text-foreground/0 group-hover/field:text-foreground/20 hover:!text-red-400 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})})]},n)),(0,i.jsxs)(`button`,{type:`button`,onClick:()=>W([...U,{key:``,value:``}]),className:`flex items-center gap-1.5 text-[11px] font-medium text-foreground/25 hover:text-foreground/40 transition-colors cursor-pointer mt-4 mb-4`,children:[(0,i.jsx)(t.Hr,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,i.jsx)(He,{isOpen:!!D,onCancel:()=>O(null),onConfirm:re,title:`Delete Record`,message:(0,i.jsxs)(i.Fragment,{children:[`Are you sure you want to delete `,(0,i.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:u.find(e=>e.id===D)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:F})]})}function Ef({config:e,customContent:n}){let{user:a}=t.Qi(),{config:c}=t.Da(),[u,d]=(0,r.useState)([]),[f,p]=(0,r.useState)(!0),[m,h]=(0,r.useState)(!1),[g,_]=(0,r.useState)(``),[v,y]=(0,r.useState)(``),[b,x]=(0,r.useState)(!1),[S,C]=(0,r.useState)(null),w=(0,r.useRef)(null),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(null),[k,A]=(0,r.useState)(null),j=e=>{if(A(e),e){let t=e.fileType||``;P(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},M=k,[N,P]=(0,r.useState)(!0),[F,I]=(0,r.useState)(!1),[L,R]=(0,r.useState)(null),[z,B]=(0,r.useState)(``),[V,H]=(0,r.useState)(``),[U,W]=(0,r.useState)([]),G=(0,r.useRef)(null),[ee,K]=(0,r.useState)(null),q=(0,r.useRef)([]),J=`mem_${(e.tabName||e.pageId||`internal_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`)}_records`,Y=bf(`mem_`);(0,r.useEffect)(()=>{document.title=e.tabTitle||e.tabName||c.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,c.appName]),(0,r.useEffect)(()=>{if(!a)return;try{let e=Kr(J,a.uid);e?(d(e),p(!1)):p(!0)}catch{}let e=e=>e.map(e=>{let t=e.data();return{id:e.id,...t,createdAt:t.createdAt?.toMillis?t.createdAt.toMillis():t.createdAt}}),n=(0,o.onSnapshot)((0,o.query)((0,o.collection)(t.Ca,J),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(150)),t=>{let n=e(t.docs);d(n),p(!1),qr(J,a.uid,n)},n=>{console.error(`Error listening to shared records:`,n);let r=(0,o.onSnapshot)((0,o.query)((0,o.collection)(t.Ca,J),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),d(n),p(!1),qr(J,a.uid,n)});return()=>r()});return()=>n()},[a,J]);let X=()=>({name:a.displayName||a.email?.split(`@`)[0]||`Member`,email:a.email||``,avatar:a.photoURL||``}),te=async e=>{if(e.preventDefault(),!(!a||!g.trim())){x(!0);try{let e=X();await(0,o.addDoc)((0,o.collection)(t.Ca,J),{name:g.trim(),note:v.trim(),uid:a.uid,recordType:`record`,creatorName:e.name,creatorEmail:e.email,creatorAvatar:e.avatar,createdAt:(0,o.serverTimestamp)()}),_(``),y(``),h(!1)}catch(e){console.error(`Error saving shared record:`,e)}x(!1)}},ne=async e=>{let n=e.target.files?.[0];if(!n||!a)return;let r=await t.or(n);E(!0);try{let e=`${Y}/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,n=(0,s.ref)(t.Ta,e);await(0,s.uploadBytes)(n,r,{customMetadata:{ownerId:a.uid}});let i=await(0,s.getDownloadURL)(n);if(w.current)w.current(r,i,{uid:a.uid,storagePath:e});else{let n=X();await(0,o.addDoc)((0,o.collection)(t.Ca,J),{name:r.name,note:`${r.type||`File`} · ${he(r.size)}`,uid:a.uid,recordType:`file`,fileName:r.name,fileType:r.type||`unknown`,fileSize:r.size,downloadURL:i,storagePath:e,creatorName:n.name,creatorEmail:n.email,creatorAvatar:n.avatar,createdAt:(0,o.serverTimestamp)()})}}catch(e){console.error(`Error uploading shared file:`,e)}E(!1),G.current&&(G.current.value=``)},re=async()=>{if(D){I(!0);try{let e=u.find(e=>e.id===D);await(0,o.deleteDoc)((0,o.doc)(t.Ca,J,D)),await Cf(e,u,Y),O(null)}catch(e){console.error(`Error deleting shared record:`,e)}I(!1)}},[Z,Q]=(0,r.useState)(null),[ie,ae]=(0,r.useState)(``),[oe,se]=(0,r.useState)(!1),ce=e=>{if(e.recordType===`file`){Q(e.id),ae(e.name);return}R(e.id),B(e.name),H(e.note||``);let t=[`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`storagePath`,`createdAt`,`creatorName`,`creatorEmail`,`creatorAvatar`],n=Object.entries(e).filter(([e])=>!t.includes(e)&&e!==`id`).map(([e,t])=>({key:e,value:String(t??``)}));W(n),q.current=n.map(e=>e.key)},le=async()=>{if(!Z||!ie.trim()){Q(null);return}let e=u.find(e=>e.id===Z);if(e&&e.name===ie.trim()){Q(null);return}se(!0);try{await(0,o.updateDoc)((0,o.doc)(t.Ca,J,Z),{name:ie.trim()}),d(e=>e.map(e=>e.id===Z?{...e,name:ie.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}se(!1),Q(null)},ue=async()=>{await de(),R(null)},de=async()=>{if(!L||!z.trim())return;x(!0);let e={};U.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let n=U.map(e=>e.key.trim()).filter(Boolean),r=q.current.filter(e=>!n.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(t.Ca,J,L),{name:z.trim(),note:V.trim(),...e}),d(e=>e.map(e=>{if(e.id!==L)return e;let t={...e,name:z.trim(),note:V.trim()};return r.forEach(e=>{delete t[e]}),U.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),q.current=n}catch(e){console.error(`Error saving record:`,e)}x(!1)},fe=(e,n)=>e?e.startsWith(`image/`)?n?(0,i.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${n})`}}):(0,i.jsx)(t.li,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,i.jsx)(t.br,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,i.jsx)(t.pi,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,i.jsx)(t.Xi,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,i.jsx)(t.Ci,{className:`w-4 h-4`}):(0,i.jsx)(t.fi,{className:`w-4 h-4`}):(0,i.jsx)(t.pi,{className:`w-4 h-4`}),pe=e=>e?e.startsWith(`image/`)?`bg-emerald-500/10 text-emerald-500`:e.startsWith(`video/`)||e.startsWith(`audio/`)?`bg-accent/10 text-accent`:e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?`bg-blue-500/10 text-blue-500`:e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?`bg-yellow-500/10 text-yellow-500`:e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?`bg-emerald-500/10 text-emerald-500`:`bg-foreground/5 text-foreground/40`:`bg-foreground/5 text-foreground/40`,me=e=>{if(!e)return`FILE`;let t={"application/pdf":`PDF`,"application/zip":`ZIP`,"application/x-zip-compressed":`ZIP`,"application/x-rar-compressed":`RAR`,"application/x-7z-compressed":`7Z`,"application/json":`JSON`,"application/xml":`XML`,"application/javascript":`JS`,"application/typescript":`TS`,"application/msword":`DOC`,"application/vnd.openxmlformats-officedocument.wordprocessingml.document":`DOCX`,"application/vnd.ms-excel":`XLS`,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":`XLSX`,"application/vnd.ms-powerpoint":`PPT`,"application/vnd.openxmlformats-officedocument.presentationml.presentation":`PPTX`,"application/rtf":`RTF`,"application/x-tar":`TAR`,"application/gzip":`GZ`,"text/plain":`TXT`,"text/html":`HTML`,"text/css":`CSS`,"text/csv":`CSV`,"text/markdown":`MD`},n=e.toLowerCase();if(t[n])return t[n];let r=n.split(`/`);return r[r.length-1].replace(/^x-/,``).replace(/^vnd\..*\./,``).toUpperCase().slice(0,10)},he=e=>{if(!e)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**+r).toFixed(2))+` `+n[r]},ge=e=>{if(!e)return``;let t=e.toMillis?e.toMillis():e;return new Date(t).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})},_e=(()=>{let n=(e.buttonStorageIcon||`upload`).trim(),r=n.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return t.mr[r]?t.mr[r]:t.mr[n]?t.mr[n]:t.wr||t.Hr})(),ve=e.buttonStyle!==`secondary`,ye=e.buttonStorageStyle===`primary`,be=e=>e.uid===a?.uid,xe=({record:e})=>{let t=e.creatorName||e.creatorEmail?.split(`@`)[0]||`Member`,n=e.creatorEmail||``,r=e.creatorAvatar||``,a=t.split(` `).map(e=>e[0]).join(``).toUpperCase().slice(0,2);return(0,i.jsxs)(`div`,{className:`flex items-center gap-2 mt-2 pt-2 border-t border-[var(--panel-border)]/30`,children:[r?(0,i.jsx)(`img`,{src:r,alt:``,className:`w-5 h-5 rounded-full object-cover shrink-0`}):(0,i.jsx)(`div`,{className:`w-5 h-5 rounded-full bg-accent/15 text-accent flex items-center justify-center text-[8px] font-extrabold shrink-0`,children:a}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 truncate`,children:t}),n&&(0,i.jsxs)(`span`,{className:`text-[10px] text-foreground/25 truncate`,children:[`· `,n]})]})]})};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(we,{children:e.tabTitle||e.tabName||`Internal Page`}),e.route&&(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background`,children:[(0,i.jsx)(`input`,{type:`file`,ref:G,onChange:ne,className:`hidden`}),!n&&(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4 p-4 sm:p-6 md:px-8 md:py-6 border-b border-[var(--panel-border)]/50 bg-background/50 shrink-0`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:f?`Loading…`:`${u.length} ${u.length===1?`item`:`items`} · Internal`})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,i.jsx)(i.Fragment,{children:(0,i.jsxs)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>G.current?.click(),disabled:T,title:e.buttonStorageText||`Upload File`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed ${e.buttonStorageText?`px-4`:`w-10`} ${ye?`btn-primary`:`btn-secondary`}`,children:[T?(0,i.jsx)(t.ei,{className:`w-4 h-4 animate-spin`}):(0,i.jsx)(_e,{className:`w-4 h-4`}),e.buttonStorageText&&(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>h(!0),title:`Add New`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer ${e.buttonText&&e.buttonText!==`+`?`px-5`:`w-10`} ${ve?`btn-primary`:`btn-secondary`}`,children:e.buttonText===`+`||!e.buttonText?(0,i.jsx)(t.Hr,{className:`w-4 h-4`}):(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,i.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[f&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,i.jsx)(t.ei,{className:`w-8 h-8 text-accent animate-spin`})}),n?(0,i.jsx)(`div`,{className:`fbos-content-slot`,children:(0,i.jsx)(n,{config:e,actions:{records:u,loading:f,collection:J,user:a,saveRecord:async e=>{let n=(0,o.doc)((0,o.collection)(t.Ca,J)),r=X(),i={id:n.id,uid:a.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:Date.now(),...e};d(e=>[i,...e]),await(0,o.setDoc)(n,{uid:a.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,n)=>{d(t=>t.map(t=>t.id===e?{...t,...n}:t)),await(0,o.updateDoc)((0,o.doc)(t.Ca,J,e),n)},deleteRecord:async e=>{let n=u.find(t=>t.id===e);await(0,o.deleteDoc)((0,o.doc)(t.Ca,J,e)),await Cf(n,u,Y)},startEdit:e=>ce(e),confirmDelete:e=>O(e),uploadFile:()=>G.current?.click(),openAddForm:()=>h(!0),setAddForm:e=>C(()=>e),setFileHandler:e=>{w.current=e}}})}):(0,i.jsxs)(i.Fragment,{children:[!f&&u.length===0&&(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex-1 flex flex-col items-center justify-center border border-[var(--panel-border)]/50 border-dashed rounded-2xl p-8 py-20 text-center min-h-[350px]`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-2xl bg-accent/5 border border-accent/10 flex items-center justify-center mb-5`,children:(0,i.jsx)(t.Hr,{className:`w-6 h-6 text-accent/40`})}),(0,i.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,i.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/35 max-w-xs leading-relaxed`,children:`Use the buttons above to add records or upload files. All team members can view and contribute.`})]}),!f&&u.length>0&&(0,i.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,i.jsx)(t.pr,{children:u.map(e=>{let n=L===e.id,r=be(e);return(0,i.jsxs)(t.fr.div,{initial:!1,animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},onClick:()=>r?ce(e):null,className:`group flex flex-col bg-background border rounded-2xl p-5 transition-all relative ${r?`cursor-pointer`:``} ${n?`border-accent/40 shadow-lg ring-1 ring-accent/20`:`border-[var(--panel-border)] hover:border-accent/30 hover:shadow-lg`}`,children:[(0,i.jsxs)(`div`,{className:`absolute top-3 right-3 flex items-center gap-0.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-all z-10`,children:[e.recordType===`file`&&e.downloadURL&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),K(e.id),setTimeout(()=>K(null),2e3)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-emerald-500 hover:bg-emerald-500/10 transition-all cursor-pointer`,title:`Copy Link`,children:ee===e.id?(0,i.jsx)(t.Fi,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,i.jsx)(t.ni,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`a`,{href:e.downloadURL,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),className:`p-1.5 rounded-lg text-foreground/25 hover:text-blue-500 hover:bg-blue-500/10 transition-all`,title:`Download`,children:(0,i.jsx)(t.yi,{className:`w-3.5 h-3.5`})})]}),r&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),ce(e)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-accent hover:bg-accent/10 transition-all cursor-pointer`,title:`Edit`,children:(0,i.jsx)(t.Gr,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),O(e.id)},className:`p-1.5 rounded-lg text-foreground/25 hover:text-red-500 hover:bg-red-500/10 transition-all cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-3.5 h-3.5`})})]})]}),(0,i.jsxs)(`div`,{className:`flex items-start gap-3 mb-2`,children:[(0,i.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&j(e)},className:`w-9 h-9 rounded-xl flex items-center justify-center shrink-0 ${e.recordType===`file`?`cursor-pointer hover:scale-105 transition-transform ${pe(e.fileType)}`:`bg-accent/10 text-accent`}`,children:e.recordType===`file`?fe(e.fileType,e.downloadURL):(0,i.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[Z===e.id?(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,value:ie,onChange:e=>ae(e.target.value),onBlur:()=>le(),onKeyDown:e=>{e.key===`Enter`&&le(),e.key===`Escape`&&Q(null)},onClick:e=>e.stopPropagation(),className:`no-glow text-[14px] font-bold text-foreground bg-transparent border-b border-accent/30 outline-none pb-0.5 w-full pr-12`}):(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,i.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>j(e)}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:ge(e.createdAt)})]})]}),e.note&&(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/55 font-medium leading-relaxed line-clamp-3 mb-1`,children:e.note}),Object.entries(e).filter(([e])=>![`name`,`note`,`uid`,`recordType`,`fileName`,`fileType`,`fileSize`,`downloadURL`,`createdAt`,`creatorName`,`creatorEmail`,`creatorAvatar`].includes(e)&&e!==`id`).slice(0,3).map(([e,t])=>(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,i.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e)),(0,i.jsx)(xe,{record:e})]},e.id)})})})]})]})]})]}),(0,i.jsx)(t.pr,{children:m&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>!b&&h(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[360px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:S?r.default.createElement(S,{onSave:async e=>{x(!0);try{let n=X();await(0,o.addDoc)((0,o.collection)(t.Ca,J),{uid:a.uid,recordType:`record`,creatorName:n.name,creatorEmail:n.email,creatorAvatar:n.avatar,createdAt:(0,o.serverTimestamp)(),...e}),h(!1)}catch(e){console.error(`Error saving record:`,e)}x(!1)},onClose:()=>!b&&h(!1),saving:b}):(0,i.jsxs)(`form`,{onSubmit:te,className:`p-5 flex flex-col gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>!b&&h(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:g,onChange:e=>_(e.target.value),placeholder:`Name *`,disabled:b,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-semibold text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`textarea`,{value:v,onChange:e=>y(e.target.value),placeholder:`Note (optional)`,disabled:b,rows:2,className:`w-full bg-foreground/[0.03] border border-[var(--panel-border)] px-3.5 py-2.5 text-[13px] font-medium text-foreground outline-none focus:border-accent transition-colors placeholder:text-foreground/30 resize-none`,style:{borderRadius:`var(--input-radius, 0.75rem)`}}),(0,i.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,i.jsx)(t.cr,{type:`submit`,isLoading:b,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:b?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,l.createPortal)((0,i.jsx)(t.pr,{children:M&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>j(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,i.jsx)(`button`,{onClick:()=>j(null),className:`absolute top-6 right-6 z-[160] w-12 h-12 bg-foreground/10 hover:bg-foreground/20 text-foreground rounded-full flex items-center justify-center backdrop-blur-md transition-all cursor-pointer outline-none`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`relative z-10 w-full max-w-6xl max-h-[85vh] flex flex-col pointer-events-auto shadow-2xl rounded-3xl overflow-hidden glass-panel border border-[var(--panel-border)]`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between p-6 bg-background/80 backdrop-blur-md border-b border-[var(--panel-border)] shrink-0 shadow-sm z-20`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,i.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:M.fileName||M.name}),(0,i.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[me(M.fileType),` • `,he(M.fileSize||0)]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(M.downloadURL),K(`preview`),setTimeout(()=>K(null),2e3)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 transition-colors rounded-xl shadow-sm hover:text-emerald-500 cursor-pointer`,title:`Copy Link`,children:ee===`preview`?(0,i.jsx)(t.Fi,{className:`w-4 h-4 text-emerald-500`}):(0,i.jsx)(t.ni,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),Q(M.id),ae(M.name)},className:`p-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground/70 hover:text-accent transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Rename`,children:(0,i.jsx)(t.Gr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{j(null),O(M.id)},className:`p-2.5 bg-red-500/10 hover:bg-red-500/20 text-red-500 transition-colors rounded-xl shadow-sm cursor-pointer`,title:`Delete`,children:(0,i.jsx)(t.Or,{className:`w-4 h-4`})}),(0,i.jsx)(`a`,{href:M.downloadURL,download:!0,target:`_blank`,rel:`noreferrer`,className:`p-2.5 btn-primary transition-colors rounded-xl shadow-lg ml-1`,title:`Download`,children:(0,i.jsx)(t.yi,{className:`w-4 h-4`})})]})]}),(0,i.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>j(null),children:(0,i.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[N&&(0,i.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,i.jsx)(`div`,{className:`w-12 h-12 rounded-full bg-background/80 backdrop-blur-md shadow-xl flex items-center justify-center border border-[var(--panel-border)]/50`,children:(0,i.jsx)(t.ei,{className:`w-5 h-5 text-accent animate-spin`})})}),M.fileType?.startsWith(`image/`)?(0,i.jsx)(`img`,{onLoad:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,alt:M.fileName||M.name,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full object-contain drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] rounded-lg pointer-events-auto transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType?.startsWith(`video/`)?(0,i.jsx)(`video`,{onLoadedData:()=>P(!1),onError:()=>P(!1),src:M.downloadURL,controls:!0,autoPlay:!0,className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-auto h-auto max-w-full max-h-full outline-none bg-black/40 rounded-lg pointer-events-auto drop-shadow-[0_0_40px_rgba(0,0,0,0.5)] transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):M.fileType===`application/pdf`?(0,i.jsx)(`iframe`,{onLoad:()=>P(!1),src:M.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${N?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,i.jsxs)(`div`,{className:`w-full h-full flex flex-col items-center justify-center text-foreground/40 text-center relative z-10`,onClick:e=>{e.stopPropagation(),P(!1)},children:[(0,i.jsx)(t.pi,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,i.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,i.jsx)(`span`,{className:`text-[14px] mt-2 text-foreground/60 font-medium max-w-xs`,children:`This file format cannot be previewed. Please download it instead.`})]})]})})]})]})}),document.body),(0,i.jsx)(t.pr,{children:L&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>ue(),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,i.jsx)(t.fr.div,{initial:{opacity:0,scale:.97,y:6},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.97,y:6},transition:{duration:.2},className:`w-full max-w-[440px] border-[var(--panel-border)] border rounded-2xl relative z-10 glass-panel shadow-2xl bg-background overflow-hidden`,children:(0,i.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,i.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),b&&(0,i.jsx)(t.ei,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>ue(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-4 h-4`})})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NAME`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`input`,{autoFocus:!0,required:!0,value:z,onChange:e=>B(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>de(),placeholder:`Name *`,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{readOnly:!0,value:`NOTE`,className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none pt-3 pb-0.5`}),(0,i.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:V,onChange:e=>{H(e.target.value),e.target.style.height=`auto`,e.target.style.height=e.target.scrollHeight+`px`},onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),e.target.blur())},onBlur:()=>de(),placeholder:`Add a note...`,rows:1,className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pb-1 caret-foreground/50 resize-none overflow-hidden`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),U.map((e,n)=>(0,i.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,i.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let t=[...U];t[n].key=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>de(),className:`no-glow bg-transparent text-[10px] font-bold text-foreground/30 uppercase tracking-[0.15em] outline-none placeholder:text-foreground/15 pt-3 pb-0.5 caret-foreground/40`}),(0,i.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let t=[...U];t[n].value=e.target.value,W(t)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},onBlur:()=>de(),className:`no-glow bg-transparent text-[13px] font-medium text-foreground outline-none placeholder:text-foreground/15 pt-1.5 pb-1 caret-foreground/50`}),(0,i.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>W(U.filter((e,t)=>t!==n)),className:`absolute top-3 right-0 p-1 text-foreground/0 group-hover/field:text-foreground/20 hover:!text-red-400 transition-colors cursor-pointer`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})})]},n)),(0,i.jsxs)(`button`,{type:`button`,onClick:()=>W([...U,{key:``,value:``}]),className:`flex items-center gap-1.5 text-[11px] font-medium text-foreground/25 hover:text-foreground/40 transition-colors cursor-pointer mt-4 mb-4`,children:[(0,i.jsx)(t.Hr,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,i.jsx)(He,{isOpen:!!D,onCancel:()=>O(null),onConfirm:re,title:`Delete Record`,message:(0,i.jsxs)(i.Fragment,{children:[`Are you sure you want to delete `,(0,i.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:u.find(e=>e.id===D)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:F})]})}var Df=e=>({creatorName:e?.displayName||e?.email?.split(`@`)[0]||``,creatorAvatar:e?.photoURL||``}),Of=(e,t)=>{if(e?.creatorName)return{name:e.creatorName,avatar:e.creatorAvatar||``};if(e?.uid&&t?.uid&&e.uid===t.uid){let e=Df(t);return e.creatorName?{name:e.creatorName,avatar:e.creatorAvatar}:null}return null},kf=[{text:`text-red-400`,bgCircle:`bg-red-400`,bgCard:`bg-red-500/[0.08]`,borderCard:`border-red-500/30`,bgLight:`bg-red-500/15`,bgHover:`hover:bg-red-500`,bgAlt:`bg-red-500/[0.04]`,name:`Red`},{text:`text-orange-400`,bgCircle:`bg-orange-400`,bgCard:`bg-orange-500/[0.08]`,borderCard:`border-orange-500/30`,bgLight:`bg-orange-500/15`,bgHover:`hover:bg-orange-500`,bgAlt:`bg-orange-500/[0.04]`,name:`Orange`},{text:`text-yellow-400`,bgCircle:`bg-yellow-400`,bgCard:`bg-yellow-500/[0.08]`,borderCard:`border-yellow-500/30`,bgLight:`bg-yellow-500/15`,bgHover:`hover:bg-yellow-500`,bgAlt:`bg-yellow-500/[0.04]`,name:`Yellow`},{text:`text-green-400`,bgCircle:`bg-green-400`,bgCard:`bg-green-500/[0.08]`,borderCard:`border-green-500/30`,bgLight:`bg-green-500/15`,bgHover:`hover:bg-green-500`,bgAlt:`bg-green-500/[0.04]`,name:`Green`},{text:`text-blue-400`,bgCircle:`bg-blue-400`,bgCard:`bg-blue-500/[0.08]`,borderCard:`border-blue-500/30`,bgLight:`bg-blue-500/15`,bgHover:`hover:bg-blue-500`,bgAlt:`bg-blue-500/[0.04]`,name:`Blue`},{text:`text-accent`,bgCircle:`bg-accent`,bgCard:`bg-accent/[0.08]`,borderCard:`border-accent/30`,bgLight:`bg-accent/15`,bgHover:`hover:bg-accent`,bgAlt:`bg-accent/[0.04]`,name:`Purple`},{text:`text-pink-400`,bgCircle:`bg-pink-400`,bgCard:`bg-pink-500/[0.08]`,borderCard:`border-pink-500/30`,bgLight:`bg-pink-500/15`,bgHover:`hover:bg-pink-500`,bgAlt:`bg-pink-500/[0.04]`,name:`Pink`},{text:`text-foreground/60`,bgCircle:`bg-foreground/30`,bgCard:`bg-foreground/[0.04]`,borderCard:`border-[var(--panel-border)]/50`,bgLight:`bg-foreground/15`,bgHover:`hover:bg-foreground/30`,bgAlt:`bg-foreground/[0.02]`,name:`Default`}];function Af({title:e=`Board View`,subtitle:n=`/board`,backUrl:a,tasksCollection:s=`pub_tasks`,categoriesCollection:c=`pub_categories`,config:l,customContent:u}){let{user:d}=t.Qi(),f=!!l,p=l?.isInternal||l?.isShared;l?.isPrivate&&l?.isAdmin;let m=l?.isAdmin||p,h=f?m||s.startsWith(`role_`):!0,g=(e,t,n,r)=>d?e.startsWith(`user_`)?{...t,uid:d.uid}:n?{uid:d.uid,...r?Df(d):{},...t}:t:t,_=!!u,v=l?.showButton!==!1&&!_,y=l?.buttonText||`+`,b=l?.buttonStyle||`primary`,x=l?.keyName||`key`,S=l?.valueName||`value`,[C,w]=(0,r.useState)([]),[T,E]=(0,r.useState)([]),[D,O]=(0,r.useState)(null),[k,A]=(0,r.useState)(null),[j,M]=(0,r.useState)({name:``}),[N,P]=(0,r.useState)([]),[F,I]=(0,r.useState)(null),[L,R]=(0,r.useState)(null),[z,B]=(0,r.useState)(null),[V,H]=(0,r.useState)(null),[U,W]=(0,r.useState)(!1),[G,ee]=(0,r.useState)(null),[K,q]=(0,r.useState)(``),[J,Y]=(0,r.useState)(null);(0,r.useEffect)(()=>{let e=s.startsWith(`user_`),n=c.startsWith(`user_`);if(e&&!d)return;try{let e=localStorage.getItem(`fbos_board_tasks_${s}`);e&&w(JSON.parse(e));let t=localStorage.getItem(`fbos_board_cats_${c}`);t&&E(JSON.parse(t))}catch{}let r=(0,o.onSnapshot)(e&&d?(0,o.query)((0,o.collection)(t.Ca,s),(0,o.where)(`uid`,`==`,d.uid)):(0,o.collection)(t.Ca,s),e=>{let t=[];e.forEach(e=>{let n=e.data();t.push({id:e.id,categoryId:n.categoryId,name:n.name||n.text||`Unnamed Item`,fields:n.fields||(n.value?[{key:`Label`,value:n.value}]:[]),order:n.order||0,uid:n.uid,creatorName:n.creatorName,creatorAvatar:n.creatorAvatar})});let n=t.sort((e,t)=>(e.order||0)-(t.order||0));w(n),localStorage.setItem(`fbos_board_tasks_${s}`,JSON.stringify(n))}),i=(0,o.onSnapshot)(n&&d?(0,o.query)((0,o.collection)(t.Ca,c),(0,o.where)(`uid`,`==`,d.uid)):(0,o.collection)(t.Ca,c),e=>{let r=[];if(e.forEach(e=>{r.push({id:e.id,...e.data()})}),r.length===0){let e=[{id:`todo`,title:`To Do`,createdAt:Date.now()-2e3},{id:`in_progress`,title:`In Progress`,createdAt:Date.now()-1e3},{id:`review`,title:`Review`,createdAt:Date.now()}],r=d?{uid:d.uid}:{},i=n&&d?`_${d.uid}`:``;e.forEach(e=>(0,o.setDoc)((0,o.doc)(t.Ca,c,`${e.id}${i}`),{...r,title:e.title,createdAt:e.createdAt}))}else E(r),localStorage.setItem(`fbos_board_cats_${c}`,JSON.stringify(r))});return()=>{r(),i()}},[s,c,d]);let X=(e,t)=>{t?(A(t.id),M({id:t.id,name:t.name}),P(t.fields?.length?[...t.fields,{key:``,value:``}]:[{key:``,value:``}])):(O(e),M({name:``}),P([{key:``,value:``}]))},te=(e,t,n)=>{let r=[...N];r[e]={key:t,value:n},e===N.length-1&&(t.trim()!==``||n.trim()!==``)&&r.push({key:``,value:``}),P(r)},ne=(e,t)=>{e.dataTransfer.effectAllowed=`move`,e.dataTransfer.setData(`taskId`,t),I(t)},re=(e,t)=>{e.preventDefault(),e.stopPropagation(),t!==F&&R(t)},Z=(e,t)=>{e.preventDefault(),e.stopPropagation(),B(t)},Q=e=>{e.preventDefault(),R(null),B(null)},ie=async(e,n,r)=>{e.preventDefault(),e.stopPropagation(),R(null),B(null);let i=e.dataTransfer.getData(`taskId`);if(!i||i===r){I(null);return}let a=C.find(e=>e.id===i);if(!a)return;let c=C.filter(e=>e.categoryId===n).sort((e,t)=>(e.order||0)-(t.order||0));if(a.categoryId===n?(c=c.filter(e=>e.id!==i),c.push(a)):c.push({...a,categoryId:n}),r){let e=c.findIndex(e=>e.id===r),t=c.findIndex(e=>e.id===i),[n]=c.splice(t,1);c.splice(e,0,n)}c.forEach((e,r)=>{let i={categoryId:n,order:r};d&&s.startsWith(`user_`)&&(i.uid=d.uid),(0,o.setDoc)((0,o.doc)(t.Ca,s,e.id),i,{merge:!0})}),I(null)},ae=async e=>{let n=j.id||`item_${Date.now()}`,r=j.name.trim(),i=r||`Untitled Item`,a=N.filter(e=>e.key.trim()!==``||e.value.trim()!==``),c=!0,l=j.id?C.find(e=>e.id===j.id):null;if(l){let e=JSON.stringify(l.fields||[]),t=JSON.stringify(a);l.name===i&&e===t&&(c=!1)}else !r&&a.length===0&&(c=!1);if(!c){O(null),A(null);return}H(j.id||`new`);let u={categoryId:e,name:i,fields:a};d&&!j.id&&Object.assign(u,{uid:d.uid},Df(d)),await(0,o.setDoc)((0,o.doc)(t.Ca,s,n),u,{merge:!0}),setTimeout(()=>{O(null),A(null),H(null)},400)},oe=(e,t)=>{Y({type:`item`,id:e,title:t})},se=async()=>{let e=`cat_${Date.now()}`,n={title:``,createdAt:Date.now()};d&&(n.uid=d.uid),await(0,o.setDoc)((0,o.doc)(t.Ca,c,e),n),ee(e),q(``),setTimeout(()=>{let e=document.getElementById(`board-container`);e&&e.scrollTo({left:e.scrollWidth,behavior:`smooth`})},150)},ce=async(e,n)=>{E(t=>t.map(t=>t.id===e?{...t,color:n}:t)),await(0,o.setDoc)((0,o.doc)(t.Ca,c,e),{color:n},{merge:!0})},le=async e=>{K.trim()?await(0,o.setDoc)((0,o.doc)(t.Ca,c,e),{title:K},{merge:!0}):await(0,o.deleteDoc)((0,o.doc)(t.Ca,c,e)),ee(null)},ue=(e,t)=>{Y({type:`category`,id:e,title:t})},de=async()=>{if(J){W(!0);try{if(J.type===`item`)await(0,o.deleteDoc)((0,o.doc)(t.Ca,s,J.id)),A(null);else{let e=C.filter(e=>e.categoryId===J.id);for(let n of e)await(0,o.deleteDoc)((0,o.doc)(t.Ca,s,n.id));await(0,o.deleteDoc)((0,o.doc)(t.Ca,c,J.id))}}catch{}W(!1),Y(null)}},fe=[...T].sort((e,t)=>(e.createdAt||0)-(t.createdAt||0));return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen overflow-x-hidden`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[!f&&a&&(0,i.jsx)(Gt,{to:a}),(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(we,{children:e}),n&&(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),n]})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 min-h-0 pb-16`,children:[f&&(0,i.jsx)(Ie,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 min-h-[400px] shadow-2xl bg-background relative z-10`,children:[(0,i.jsx)(`div`,{className:`absolute top-0 right-0 w-[400px] h-[400px] bg-accent/5 blur-[100px] rounded-full pointer-events-none -z-10`}),(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4 p-4 sm:p-6 md:px-8 md:py-6 border-b border-[var(--panel-border)]/50 bg-background/50 shrink-0 relative z-20`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-lg sm:text-xl font-extrabold text-foreground tracking-tight truncate`,children:l?.tabTitle||l?.tabName||e}),(0,i.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:[C.length,` `,C.length===1?`item`:`items`,` · `,fe.length,` `,fe.length===1?`category`:`categories`]})]}),v&&(0,i.jsx)(t.cr,{variant:b===`secondary`?`secondary`:void 0,onClick:se,className:`px-3 py-2.5 text-[14px] font-bold rounded-xl shadow-lg hover:-translate-y-0.5 transition-all shrink-0`,children:y===`+`?(0,i.jsx)(t.Hr,{className:`w-4 h-4`}):y})]}),(0,i.jsx)(`div`,{className:`flex-1 w-full relative z-40 min-h-0 flex flex-col`,children:u?(0,i.jsx)(`div`,{className:`fbos-content-slot w-full flex-1 overflow-y-auto p-4 md:p-6`,children:(0,i.jsx)(u,{config:l,actions:{tasks:C,categories:T,collection:s,catCollection:c,user:d,saveTask:async(e,n)=>{let r=e||`item_${Date.now()}`,i=g(s,n,!C.some(e=>e.id===r),!0);w(e=>e.find(e=>e.id===r)?e.map(e=>e.id===r?{...e,...i}:e):[...e,{id:r,...i}]),await(0,o.setDoc)((0,o.doc)(t.Ca,s,r),i,{merge:!0})},deleteTask:async e=>{w(t=>t.filter(t=>t.id!==e)),await(0,o.deleteDoc)((0,o.doc)(t.Ca,s,e))},saveCategory:async(e,n)=>{let r=g(c,n,!T.some(t=>t.id===e),!1);E(t=>t.find(t=>t.id===e)?t.map(t=>t.id===e?{...t,...r}:t):[...t,{id:e,...r}]),await(0,o.setDoc)((0,o.doc)(t.Ca,c,e),r,{merge:!0})},deleteCategory:async e=>{E(t=>t.filter(t=>t.id!==e)),await(0,o.deleteDoc)((0,o.doc)(t.Ca,c,e))},openInlineEditor:(e,t)=>X(e,t)}})}):(0,i.jsxs)(`div`,{id:`board-container`,className:`w-full flex-1 min-h-0 flex flex-row gap-4 md:gap-6 overflow-x-auto p-4 md:p-6 snap-x snap-mandatory styled-scrollbars items-start`,children:[fe.map((e,n)=>{let r=C.filter(t=>t.categoryId===e.id);r.sort((e,t)=>(e.order||0)-(t.order||0));let a=kf.find(t=>t.text===e.color)||kf.find(e=>e.text===`text-accent`);return a.text,a.bgLight,a.bgHover,(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:n*.1},className:`w-[calc(100vw-80px)] sm:w-[300px] md:w-[320px] shrink-0 flex flex-col max-h-full rounded-3xl p-4 snap-center relative border transition-colors ${kf.find(t=>t.text===e.color)?.bgCard||`bg-foreground/[0.02]`} ${kf.find(t=>t.text===e.color)?.borderCard||`border-[var(--panel-border)]/50`}`,children:[(0,i.jsx)(`div`,{className:`flex items-center justify-between mb-4 px-2 relative z-[200]`,children:(0,i.jsxs)(`h3`,{className:`font-bold text-[14px] flex items-center w-full text-foreground/80 group relative z-[200]`,children:[G===e.id?(0,i.jsxs)(`div`,{className:`relative flex-1 w-full flex items-center pr-8 z-[200]`,children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-[-1]`,onClick:t=>{t.stopPropagation(),le(e.id)}}),(0,i.jsx)(`input`,{value:K,onChange:e=>q(e.target.value),onBlur:t=>{t.relatedTarget?.closest(`.category-color-picker`)||le(e.id)},onKeyDown:t=>t.key===`Enter`&&le(e.id),className:`bg-transparent border-none outline-none font-bold text-[14px] w-full p-0 ${e.color||`text-foreground/80`}`,placeholder:`Category name`,autoFocus:!0}),(0,i.jsxs)(`div`,{className:`absolute top-8 left-0 flex gap-1.5 bg-background/95 backdrop-blur-xl border border-[var(--panel-border)] p-2 rounded-xl shadow-xl z-[100] category-color-picker items-center`,tabIndex:-1,children:[(0,i.jsx)(`button`,{onClick:async t=>{t.preventDefault(),t.stopPropagation(),await ce(e.id,``),ee(null)},className:`w-4 h-4 rounded-full flex items-center justify-center bg-foreground/10 hover:bg-red-500/20 hover:text-red-500 text-foreground/40 transition-colors border border-[var(--panel-border)]/50 shrink-0`,title:`Reset Category Color`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})}),(0,i.jsx)(`div`,{className:`h-4 w-px bg-[var(--panel-border)]/50 mx-0.5`}),kf.map(t=>(0,i.jsx)(`button`,{onMouseDown:async n=>{n.preventDefault(),await ce(e.id,t.text)},className:`w-4 h-4 rounded-full ${t.bgCircle} hover:scale-125 transition-transform border border-[var(--panel-border)]/50 shrink-0`},t.name))]})]}):(0,i.jsxs)(`div`,{className:`flex items-center gap-2 w-full cursor-pointer hover:text-foreground transition-colors pr-8`,onClick:()=>{ee(e.id),q(e.title)},children:[(0,i.jsx)(`span`,{className:`w-2.5 h-2.5 rounded-full ${kf.find(t=>t.text===e.color)?.bgCircle||`bg-foreground/20`} transition-colors shrink-0`}),(0,i.jsx)(`span`,{className:`truncate flex-1 max-w-[200px] ${e.color||``}`,children:e.title||`Untitled Category`}),(0,i.jsx)(`span`,{className:`text-[11px] bg-foreground/10 text-foreground/60 px-1.5 py-0.5 rounded-md font-medium shrink-0`,children:r.length})]}),T.length>1&&(0,i.jsx)(`button`,{onClick:()=>ue(e.id,e.title),className:`absolute right-0 opacity-100 md:opacity-0 md:group-hover:opacity-100 text-foreground/30 hover:text-red-500 transition-all shrink-0`,children:(0,i.jsx)(t.Dr,{className:`w-3.5 h-3.5`})})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2.5 flex-1 overflow-y-auto styled-scrollbars pr-1 relative min-h-[150px] rounded-xl transition-all ${z===e.id&&!L?`bg-foreground/5 scale-[1.01] border-dashed border border-accent/20`:``}`,onDragOver:t=>Z(t,e.id),onDragLeave:Q,onDrop:t=>ie(t,e.id),children:[(0,i.jsx)(t.pr,{children:r.map(n=>k===n.id?(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:`bg-background/80 rounded-xl p-3 shadow-md border border-accent/40 transition-all flex flex-col gap-2 relative z-[100]`,children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-[-1]`,onClick:t=>{t.stopPropagation(),ae(e.id)}}),(0,i.jsx)(`textarea`,{placeholder:`Write an item name...`,className:`no-glow bg-transparent border-none outline-none text-[13px] text-foreground/90 font-medium leading-snug resize-none w-full min-h-[40px] relative z-10`,value:j.name,onChange:e=>M({...j,name:e.target.value}),onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),ae(e.id))}}),(0,i.jsx)(`div`,{className:`flex flex-col gap-2 mt-1 relative z-10 w-full`,children:N.map((t,n)=>(0,i.jsxs)(`div`,{className:`flex items-start bg-foreground/[0.04] border border-[var(--panel-border)]/50 rounded-[8px] px-2.5 py-1.5 w-full`,children:[(0,i.jsx)(`input`,{placeholder:x,value:t.key,onChange:e=>te(n,e.target.value,t.value),onKeyDown:t=>t.key===`Enter`&&ae(e.id),className:`no-glow bg-transparent outline-none text-[11px] text-foreground/50 font-bold placeholder:text-foreground/30 relative top-[1px] shrink-0`,style:{width:`${Math.max(3,t.key.length||x.length)}ch`}}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/50 font-bold mr-1.5 relative top-[1px]`,children:`:`}),(0,i.jsx)(`textarea`,{rows:1,placeholder:S,value:t.value,onChange:e=>te(n,t.key,e.target.value),onInput:e=>{let t=e.target;t.style.height=`auto`,t.style.height=t.scrollHeight+`px`},onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),ae(e.id))},className:`no-glow bg-transparent outline-none text-[12px] text-foreground/90 font-medium flex-1 min-w-[40px] placeholder:opacity-40 resize-none overflow-hidden leading-tight relative top-[1px]`})]},n))}),V===n.id&&(0,i.jsx)(`div`,{className:`flex items-center justify-end pt-1`,children:(0,i.jsx)(`div`,{className:`w-3 h-3 border-2 border-accent border-t-transparent rounded-full animate-spin`})})]},n.id):(0,i.jsxs)(t.fr.div,{draggable:!0,onDragStart:e=>ne(e,n.id),onDragOver:e=>re(e,n.id),onDragLeave:Q,onDrop:t=>ie(t,e.id,n.id),initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:`bg-background/80 rounded-xl p-3 shadow-sm hover:shadow-md cursor-grab active:cursor-grabbing hover:border-accent/40 transition-all group flex flex-col gap-2 relative z-10 border ${L===n.id?`border-accent border-t-2 translate-y-1`:`border-[var(--panel-border)]`} ${F===n.id?`opacity-30 scale-95 border-dashed border-2`:``}`,children:[(0,i.jsxs)(`div`,{className:`absolute top-2 right-2 flex items-center gap-1.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity bg-background/90 backdrop-blur-md border border-[var(--panel-border)] rounded-lg p-1 z-20 shadow-md`,children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),X(e.id,n)},className:`p-1 hover:bg-foreground/5 rounded-md text-foreground/60 hover:text-accent transition-colors`,children:(0,i.jsx)(t.Gr,{className:`w-3.5 h-3.5`})}),(0,i.jsx)(`button`,{onClick:e=>{e.stopPropagation(),oe(n.id,n.name)},className:`p-1 hover:bg-red-500/10 rounded-md text-foreground/60 hover:text-red-500 transition-colors`,children:(0,i.jsx)(t.Dr,{className:`w-3.5 h-3.5`})})]}),(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/90 font-medium leading-snug break-words pr-12`,children:n.name}),n.fields&&n.fields.length>0&&(0,i.jsx)(`div`,{className:`flex flex-row flex-wrap gap-2 mt-2`,children:n.fields.map((e,t)=>(0,i.jsxs)(`div`,{className:`inline-flex bg-foreground/[0.04] border border-[var(--panel-border)]/50 rounded-[8px] px-2.5 py-1.5 max-w-full`,children:[(0,i.jsxs)(`span`,{className:`text-[11px] text-foreground/50 font-bold mr-1.5 relative -top-[1px] shrink-0 break-all`,children:[e.key,`:`]}),(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/90 font-medium break-words leading-tight min-w-0`,children:e.value})]},t))}),(0,i.jsxs)(`div`,{className:`flex items-end justify-between mt-3 pt-3 border-t border-[var(--panel-border)]/50 w-full gap-2`,children:[(()=>{let e=h&&f?Of(n,d):null;return e?(0,i.jsxs)(`div`,{className:`flex items-center gap-1.5 pr-2 border-r border-[var(--panel-border)] border-dashed mr-auto`,children:[e.avatar?(0,i.jsx)(`img`,{src:e.avatar,className:`w-4 h-4 rounded-full shrink-0 object-cover`}):(0,i.jsx)(`div`,{className:`w-4 h-4 rounded-full bg-accent/20 text-accent flex items-center justify-center text-[9px] font-bold shrink-0`,children:e.name[0].toUpperCase()}),(0,i.jsx)(`span`,{className:`text-[10px] font-bold text-foreground/60 truncate max-w-[80px]`,children:e.name})]}):(0,i.jsx)(`div`,{className:`flex items-center gap-2 pr-2 border-r border-[var(--panel-border)] border-dashed mr-auto`})})(),(0,i.jsx)(`span`,{className:`text-[10px] text-foreground/40 font-bold text-right pt-0.5 shrink-0 max-w-[50%] truncate flex-1`,children:n.id.startsWith(`item_`)?new Date(parseInt(n.id.split(`_`)[1])).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`}):`Recently Added`})]})]},n.id))}),D===e.id?(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},className:`bg-background/80 rounded-xl p-3 shadow-md border border-accent/40 transition-all flex flex-col gap-2 relative z-[100] mt-1`,children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-[-1]`,onClick:t=>{t.stopPropagation(),ae(e.id)}}),(0,i.jsx)(`textarea`,{placeholder:`Write an item name...`,className:`no-glow bg-transparent border-none outline-none text-[13px] text-foreground/90 font-medium leading-snug resize-none w-full min-h-[40px] relative z-10`,value:j.name,onChange:e=>M({...j,name:e.target.value}),onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),ae(e.id))},autoFocus:!0}),(0,i.jsx)(`div`,{className:`flex flex-col gap-2 mt-1 relative z-10 w-full`,children:N.map((t,n)=>(0,i.jsxs)(`div`,{className:`flex items-start bg-foreground/[0.04] border border-[var(--panel-border)]/50 rounded-[8px] px-2.5 py-1.5 w-full`,children:[(0,i.jsx)(`input`,{placeholder:x,style:{width:`${Math.max(3,t.key.length||x.length)}ch`},value:t.key,onChange:e=>te(n,e.target.value,t.value),onKeyDown:t=>t.key===`Enter`&&ae(e.id),className:`no-glow bg-transparent outline-none text-[11px] text-foreground/50 font-bold placeholder:text-foreground/30 relative top-[1px]`}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/50 font-bold mr-1.5 relative top-[1px]`,children:`:`}),(0,i.jsx)(`textarea`,{rows:1,placeholder:S,value:t.value,onChange:e=>te(n,t.key,e.target.value),onInput:e=>{let t=e.target;t.style.height=`auto`,t.style.height=t.scrollHeight+`px`},onKeyDown:t=>{t.key===`Enter`&&!t.shiftKey&&(t.preventDefault(),ae(e.id))},className:`no-glow bg-transparent outline-none text-[12px] text-foreground/90 font-medium flex-1 min-w-[40px] placeholder:opacity-40 resize-none overflow-hidden leading-tight relative top-[1px]`})]},n))}),V===`new`&&(0,i.jsx)(`div`,{className:`flex items-center justify-end pt-1`,children:(0,i.jsx)(`div`,{className:`w-3 h-3 border-2 border-accent border-t-transparent rounded-full animate-spin`})})]}):(0,i.jsxs)(`button`,{onClick:()=>X(e.id),className:`flex items-center gap-2 justify-center w-full py-2.5 mt-1 rounded-xl border border-transparent text-[12px] font-bold text-foreground/40 hover:text-foreground hover:bg-foreground/[0.03] transition-all shrink-0`,children:[(0,i.jsx)(t.Hr,{className:`w-4 h-4`}),` Add Item`]})]})]},e.id)}),(0,i.jsx)(`div`,{className:`w-[10px] shrink-0 pointer-events-none`})]})})]})]}),(0,i.jsx)(`style`,{children:`.styled-scrollbars::-webkit-scrollbar { width: 6px; height: 6px; } .styled-scrollbars::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--accent-color) 20%, transparent); border-radius: 4px; } .styled-scrollbars::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--accent-color) 40%, transparent); }`}),(0,i.jsx)(He,{isOpen:!!J,title:`Confirm Deletion`,message:(0,i.jsxs)(i.Fragment,{children:[`Are you sure you want to delete `,(0,i.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:J?.title}),` This action is permanent.`]}),onConfirm:de,onCancel:()=>Y(null),isProcessing:U,confirmText:`Yes, Delete`})]})}function jf(e){return Array.isArray?Array.isArray(e):Vf(e)===`[object Array]`}function Mf(e){if(typeof e==`string`)return e;if(typeof e==`bigint`)return e.toString();let t=e+``;return t==`0`&&1/e==-1/0?`-0`:t}function Nf(e){return e==null?``:Mf(e)}function Pf(e){return typeof e==`string`}function Ff(e){return typeof e==`number`}function If(e){return e===!0||e===!1||Rf(e)&&Vf(e)==`[object Boolean]`}function Lf(e){return typeof e==`object`}function Rf(e){return Lf(e)&&e!==null}function zf(e){return e!=null}function Bf(e){return!e.trim().length}function Vf(e){return e==null?e===void 0?`[object Undefined]`:`[object Null]`:Object.prototype.toString.call(e)}var Hf=`Incorrect 'index' type`,Uf=e=>`Invalid value for key ${e}`,Wf=e=>`Pattern length exceeds max of ${e}.`,Gf=e=>`Missing ${e} property in key`,Kf=e=>`Property 'weight' in key '${e}' must be a positive integer`,qf=Object.prototype.hasOwnProperty,Jf=class{constructor(e){this._keys=[],this._keyMap={};let t=0;e.forEach(e=>{let n=Yf(e);this._keys.push(n),this._keyMap[n.id]=n,t+=n.weight}),this._keys.forEach(e=>{e.weight/=t})}get(e){return this._keyMap[e]}keys(){return this._keys}toJSON(){return JSON.stringify(this._keys)}};function Yf(e){let t=null,n=null,r=null,i=1,a=null;if(Pf(e)||jf(e))r=e,t=Xf(e),n=Zf(e);else{if(!qf.call(e,`name`))throw Error(Gf(`name`));let o=e.name;if(r=o,qf.call(e,`weight`)&&(i=e.weight,i<=0))throw Error(Kf(o));t=Xf(o),n=Zf(o),a=e.getFn}return{path:t,id:n,weight:i,src:r,getFn:a}}function Xf(e){return jf(e)?e:e.split(`.`)}function Zf(e){return jf(e)?e.join(`.`):e}function Qf(e,t){let n=[],r=!1,i=(e,t,a,o)=>{if(zf(e))if(!t[a])n.push(o===void 0?e:{v:e,i:o});else{let s=e[t[a]];if(!zf(s))return;if(a===t.length-1&&(Pf(s)||Ff(s)||If(s)||typeof s==`bigint`))n.push(o===void 0?Nf(s):{v:Nf(s),i:o});else if(jf(s)){r=!0;for(let e=0,n=s.length;e<n;e+=1)i(s[e],t,a+1,e)}else t.length&&i(s,t,a+1,o)}};return i(e,Pf(t)?t.split(`.`):t,0),r?n:n[0]}var $f={includeMatches:!1,findAllMatches:!1,minMatchCharLength:1},ep={isCaseSensitive:!1,ignoreDiacritics:!1,includeScore:!1,keys:[],shouldSort:!0,sortFn:(e,t)=>e.score===t.score?e.idx<t.idx?-1:1:e.score<t.score?-1:1},tp={location:0,threshold:.6,distance:100},np={useExtendedSearch:!1,useTokenSearch:!1,getFn:Qf,ignoreLocation:!1,ignoreFieldNorm:!1,fieldNormWeight:1},$=Object.freeze({...ep,...$f,...tp,...np}),rp=/[^ ]+/g;function ip(e=1,t=3){let n=new Map,r=10**t;return{get(t){let i=t.match(rp).length;if(n.has(i))return n.get(i);let a=1/i**(.5*e),o=parseFloat(Math.round(a*r)/r);return n.set(i,o),o},clear(){n.clear()}}}var ap=class{constructor({getFn:e=$.getFn,fieldNormWeight:t=$.fieldNormWeight}={}){this.norm=ip(t,3),this.getFn=e,this.isCreated=!1,this.docs=[],this.keys=[],this._keysMap={},this.setIndexRecords()}setSources(e=[]){this.docs=e}setIndexRecords(e=[]){this.records=e}setKeys(e=[]){this.keys=e,this._keysMap={},e.forEach((e,t)=>{this._keysMap[e.id]=t})}create(){this.isCreated||!this.docs.length||(this.isCreated=!0,Pf(this.docs[0])?this.docs.forEach((e,t)=>{this._addString(e,t)}):this.docs.forEach((e,t)=>{this._addObject(e,t)}),this.norm.clear())}add(e){let t=this.size();Pf(e)?this._addString(e,t):this._addObject(e,t)}removeAt(e){this.records.splice(e,1);for(let t=e,n=this.size();t<n;t+=1)--this.records[t].i}removeAll(e){for(let t=e.length-1;t>=0;--t)this.records.splice(e[t],1);for(let e=0,t=this.records.length;e<t;e+=1)this.records[e].i=e}getValueForItemAtKeyId(e,t){return e[this._keysMap[t]]}size(){return this.records.length}_addString(e,t){if(!zf(e)||Bf(e))return;let n={v:e,i:t,n:this.norm.get(e)};this.records.push(n)}_addObject(e,t){let n={i:t,$:{}};this.keys.forEach((t,r)=>{let i=t.getFn?t.getFn(e):this.getFn(e,t.path);if(zf(i)){if(jf(i)){let e=[];for(let t=0,n=i.length;t<n;t+=1){let n=i[t];if(zf(n)){if(Pf(n)){if(!Bf(n)){let r={v:n,i:t,n:this.norm.get(n)};e.push(r)}}else if(zf(n.v)){let t=Pf(n.v)?n.v:Nf(n.v);if(!Bf(t)){let r={v:t,i:n.i,n:this.norm.get(t)};e.push(r)}}}}n.$[r]=e}else if(Pf(i)&&!Bf(i)){let e={v:i,n:this.norm.get(i)};n.$[r]=e}}}),this.records.push(n)}toJSON(){return{keys:this.keys.map(({getFn:e,...t})=>t),records:this.records}}};function op(e,t,{getFn:n=$.getFn,fieldNormWeight:r=$.fieldNormWeight}={}){let i=new ap({getFn:n,fieldNormWeight:r});return i.setKeys(e.map(Yf)),i.setSources(t),i.create(),i}function sp(e,{getFn:t=$.getFn,fieldNormWeight:n=$.fieldNormWeight}={}){let{keys:r,records:i}=e,a=new ap({getFn:t,fieldNormWeight:n});return a.setKeys(r),a.setIndexRecords(i),a}function cp(e=[],t=$.minMatchCharLength){let n=[],r=-1,i=-1,a=0;for(let o=e.length;a<o;a+=1){let o=e[a];o&&r===-1?r=a:!o&&r!==-1&&(i=a-1,i-r+1>=t&&n.push([r,i]),r=-1)}return e[a-1]&&a-r>=t&&n.push([r,a-1]),n}var lp=32;function up(e,t,n,{location:r=$.location,distance:i=$.distance,threshold:a=$.threshold,findAllMatches:o=$.findAllMatches,minMatchCharLength:s=$.minMatchCharLength,includeMatches:c=$.includeMatches,ignoreLocation:l=$.ignoreLocation}={}){if(t.length>lp)throw Error(Wf(lp));let u=t.length,d=e.length,f=Math.max(0,Math.min(r,d)),p=a,m=f,h=(e,t)=>{let n=e/u;if(l)return n;let r=Math.abs(f-t);return i?n+r/i:r?1:n},g=s>1||c,_=g?Array(d):[],v;for(;(v=e.indexOf(t,m))>-1;){let e=h(0,v);if(p=Math.min(e,p),m=v+u,g){let e=0;for(;e<u;)_[v+e]=1,e+=1}}m=-1;let y=[],b=1,x=u+d,S=1<<u-1;for(let t=0;t<u;t+=1){let r=0,i=x;for(;r<i;)h(t,f+i)<=p?r=i:x=i,i=Math.floor((x-r)/2+r);x=i;let a=Math.max(1,f-i+1),s=o?d:Math.min(f+i,d)+u,c=Array(s+2);c[s+1]=(1<<t)-1;for(let r=s;r>=a;--r){let i=r-1,o=n[e[i]];if(g&&(_[i]=+!!o),c[r]=(c[r+1]<<1|1)&o,t&&(c[r]|=(y[r+1]|y[r])<<1|1|y[r+1]),c[r]&S&&(b=h(t,i),b<=p)){if(p=b,m=i,m<=f)break;a=Math.max(1,2*f-m)}}if(h(t+1,f)>p)break;y=c}let C={isMatch:m>=0,score:Math.max(.001,b)};if(g){let e=cp(_,s);e.length?c&&(C.indices=e):C.isMatch=!1}return C}function dp(e){let t={};for(let n=0,r=e.length;n<r;n+=1){let i=e.charAt(n);t[i]=(t[i]||0)|1<<r-n-1}return t}function fp(e){if(e.length<=1)return e;e.sort((e,t)=>e[0]-t[0]||e[1]-t[1]);let t=[e[0]];for(let n=1,r=e.length;n<r;n+=1){let r=t[t.length-1],i=e[n];i[0]<=r[1]+1?r[1]=Math.max(r[1],i[1]):t.push(i)}return t}var pp={ł:`l`,Ł:`L`,đ:`d`,Đ:`D`,ø:`o`,Ø:`O`,ħ:`h`,Ħ:`H`,ŧ:`t`,Ŧ:`T`,ı:`i`,ß:`ss`},mp=RegExp(`[`+Object.keys(pp).join(``)+`]`,`g`),hp=String.prototype.normalize?e=>e.normalize(`NFD`).replace(/[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C04\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]/g,``).replace(mp,e=>pp[e]):e=>e,gp=class{constructor(e,{location:t=$.location,threshold:n=$.threshold,distance:r=$.distance,includeMatches:i=$.includeMatches,findAllMatches:a=$.findAllMatches,minMatchCharLength:o=$.minMatchCharLength,isCaseSensitive:s=$.isCaseSensitive,ignoreDiacritics:c=$.ignoreDiacritics,ignoreLocation:l=$.ignoreLocation}={}){if(this.options={location:t,threshold:n,distance:r,includeMatches:i,findAllMatches:a,minMatchCharLength:o,isCaseSensitive:s,ignoreDiacritics:c,ignoreLocation:l},e=s?e:e.toLowerCase(),e=c?hp(e):e,this.pattern=e,this.chunks=[],!this.pattern.length)return;let u=(e,t)=>{this.chunks.push({pattern:e,alphabet:dp(e),startIndex:t})},d=this.pattern.length;if(d>lp){let e=0,t=d%lp,n=d-t;for(;e<n;)u(this.pattern.substr(e,lp),e),e+=lp;if(t){let e=d-lp;u(this.pattern.substr(e),e)}}else u(this.pattern,0)}searchIn(e){let{isCaseSensitive:t,ignoreDiacritics:n,includeMatches:r}=this.options;if(e=t?e:e.toLowerCase(),e=n?hp(e):e,this.pattern===e){let t={isMatch:!0,score:0};return r&&(t.indices=[[0,e.length-1]]),t}let{location:i,distance:a,threshold:o,findAllMatches:s,minMatchCharLength:c,ignoreLocation:l}=this.options,u=[],d=0,f=!1;this.chunks.forEach(({pattern:t,alphabet:n,startIndex:p})=>{let{isMatch:m,score:h,indices:g}=up(e,t,n,{location:i+p,distance:a,threshold:o,findAllMatches:s,minMatchCharLength:c,includeMatches:r,ignoreLocation:l});m&&(f=!0),d+=h,m&&g&&u.push(...g)});let p={isMatch:f,score:f?d/this.chunks.length:1};return f&&r&&(p.indices=fp(u)),p}},_p=class{constructor(e){this.pattern=e}static isMultiMatch(e){return vp(e,this.multiRegex)}static isSingleMatch(e){return vp(e,this.singleRegex)}search(e){return{isMatch:!1,score:1}}};function vp(e,t){let n=e.match(t);return n?n[1]:null}var yp=class extends _p{constructor(e){super(e)}static get type(){return`exact`}static get multiRegex(){return/^="(.*)"$/}static get singleRegex(){return/^=(.*)$/}search(e){let t=e===this.pattern;return{isMatch:t,score:+!t,indices:[0,this.pattern.length-1]}}},bp=class extends _p{constructor(e){super(e)}static get type(){return`inverse-exact`}static get multiRegex(){return/^!"(.*)"$/}static get singleRegex(){return/^!(.*)$/}search(e){let t=e.indexOf(this.pattern)===-1;return{isMatch:t,score:+!t,indices:[0,e.length-1]}}},xp=class extends _p{constructor(e){super(e)}static get type(){return`prefix-exact`}static get multiRegex(){return/^\^"(.*)"$/}static get singleRegex(){return/^\^(.*)$/}search(e){let t=e.startsWith(this.pattern);return{isMatch:t,score:+!t,indices:[0,this.pattern.length-1]}}},Sp=class extends _p{constructor(e){super(e)}static get type(){return`inverse-prefix-exact`}static get multiRegex(){return/^!\^"(.*)"$/}static get singleRegex(){return/^!\^(.*)$/}search(e){let t=!e.startsWith(this.pattern);return{isMatch:t,score:+!t,indices:[0,e.length-1]}}},Cp=class extends _p{constructor(e){super(e)}static get type(){return`suffix-exact`}static get multiRegex(){return/^"(.*)"\$$/}static get singleRegex(){return/^(.*)\$$/}search(e){let t=e.endsWith(this.pattern);return{isMatch:t,score:+!t,indices:[e.length-this.pattern.length,e.length-1]}}},wp=class extends _p{constructor(e){super(e)}static get type(){return`inverse-suffix-exact`}static get multiRegex(){return/^!"(.*)"\$$/}static get singleRegex(){return/^!(.*)\$$/}search(e){let t=!e.endsWith(this.pattern);return{isMatch:t,score:+!t,indices:[0,e.length-1]}}},Tp=class extends _p{constructor(e,{location:t=$.location,threshold:n=$.threshold,distance:r=$.distance,includeMatches:i=$.includeMatches,findAllMatches:a=$.findAllMatches,minMatchCharLength:o=$.minMatchCharLength,isCaseSensitive:s=$.isCaseSensitive,ignoreDiacritics:c=$.ignoreDiacritics,ignoreLocation:l=$.ignoreLocation}={}){super(e),this._bitapSearch=new gp(e,{location:t,threshold:n,distance:r,includeMatches:i,findAllMatches:a,minMatchCharLength:o,isCaseSensitive:s,ignoreDiacritics:c,ignoreLocation:l})}static get type(){return`fuzzy`}static get multiRegex(){return/^"(.*)"$/}static get singleRegex(){return/^(.*)$/}search(e){return this._bitapSearch.searchIn(e)}},Ep=class extends _p{constructor(e){super(e)}static get type(){return`include`}static get multiRegex(){return/^'"(.*)"$/}static get singleRegex(){return/^'(.*)$/}search(e){let t=0,n,r=[],i=this.pattern.length;for(;(n=e.indexOf(this.pattern,t))>-1;)t=n+i,r.push([n,t-1]);let a=!!r.length;return{isMatch:a,score:+!a,indices:r}}},Dp=[yp,Ep,xp,Sp,wp,Cp,bp,Tp],Op=Dp.length,kp=`\0`,Ap=`|`;function jp(e){let t=[],n=e.length,r=0;for(;r<n;){for(;r<n&&e[r]===` `;)r++;if(r>=n)break;let i=r;for(;i<n&&e[i]!==` `&&e[i]!==`"`;)i++;if(i<n&&e[i]===`"`){for(i++;i<n;){if(e[i]===`"`){let t=i+1;if(t>=n||e[t]===` `){i++;break}if(e[t]===`$`&&(t+1>=n||e[t+1]===` `)){i+=2;break}}i++}t.push(e.substring(r,i)),r=i}else{for(;i<n&&e[i]!==` `;)i++;t.push(e.substring(r,i)),r=i}}return t}function Mp(e,t={}){return e.replace(/\\\|/g,kp).split(Ap).map(e=>{let n=jp(e.replace(/\u0000/g,`|`).trim()).filter(e=>e&&!!e.trim()),r=[];for(let e=0,i=n.length;e<i;e+=1){let i=n[e],a=!1,o=-1;for(;!a&&++o<Op;){let e=Dp[o],n=e.isMultiMatch(i);n&&(r.push(new e(n,t)),a=!0)}if(!a)for(o=-1;++o<Op;){let e=Dp[o],n=e.isSingleMatch(i);if(n){r.push(new e(n,t));break}}}return r})}var Np=new Set([Tp.type,Ep.type]),Pp=class{constructor(e,{isCaseSensitive:t=$.isCaseSensitive,ignoreDiacritics:n=$.ignoreDiacritics,includeMatches:r=$.includeMatches,minMatchCharLength:i=$.minMatchCharLength,ignoreLocation:a=$.ignoreLocation,findAllMatches:o=$.findAllMatches,location:s=$.location,threshold:c=$.threshold,distance:l=$.distance}={}){this.query=null,this.options={isCaseSensitive:t,ignoreDiacritics:n,includeMatches:r,minMatchCharLength:i,findAllMatches:o,ignoreLocation:a,location:s,threshold:c,distance:l},e=t?e:e.toLowerCase(),e=n?hp(e):e,this.pattern=e,this.query=Mp(this.pattern,this.options)}static condition(e,t){return t.useExtendedSearch}searchIn(e){let t=this.query;if(!t)return{isMatch:!1,score:1};let{includeMatches:n,isCaseSensitive:r,ignoreDiacritics:i}=this.options;e=r?e:e.toLowerCase(),e=i?hp(e):e;let a=0,o=[],s=0,c=!1;for(let r=0,i=t.length;r<i;r+=1){let i=t[r];o.length=0,a=0,c=!1;for(let t=0,r=i.length;t<r;t+=1){let r=i[t],{isMatch:l,indices:u,score:d}=r.search(e);if(l){a+=1,s+=d;let e=r.constructor.type;e.startsWith(`inverse`)&&(c=!0),n&&(Np.has(e)?o.push(...u):o.push(u))}else{s=0,a=0,o.length=0,c=!1;break}}if(a){let e={isMatch:!0,score:s/a};return c&&(e.hasInverse=!0),n&&(e.indices=fp(o)),e}}return{isMatch:!1,score:1}}},Fp=[];function Ip(...e){Fp.push(...e)}function Lp(e,t){for(let n=0,r=Fp.length;n<r;n+=1){let r=Fp[n];if(r.condition(e,t))return new r(e,t)}return new gp(e,t)}var Rp={AND:`$and`,OR:`$or`},zp={PATH:`$path`,PATTERN:`$val`},Bp=e=>!!(e[Rp.AND]||e[Rp.OR]),Vp=e=>!!e[zp.PATH],Hp=e=>!jf(e)&&Lf(e)&&!Bp(e),Up=e=>({[Rp.AND]:Object.keys(e).map(t=>({[t]:e[t]}))});function Wp(e,t,{auto:n=!0}={}){let r=e=>{if(Pf(e)){let r={keyId:null,pattern:e};return n&&(r.searcher=Lp(e,t)),r}let i=Object.keys(e),a=Vp(e);if(!a&&i.length>1&&!Bp(e))return r(Up(e));if(Hp(e)){let r=a?e[zp.PATH]:i[0],o=a?e[zp.PATTERN]:e[r];if(!Pf(o))throw Error(Uf(r));let s={keyId:Zf(r),pattern:o};return n&&(s.searcher=Lp(o,t)),s}let o={children:[],operator:i[0]};return i.forEach(t=>{let n=e[t];jf(n)&&n.forEach(e=>{o.children.push(r(e))})}),o};return Bp(e)||(e=Up(e)),r(e)}function Gp(e,{ignoreFieldNorm:t=$.ignoreFieldNorm}){let n=1;return e.forEach(({key:e,norm:r,score:i})=>{let a=e?e.weight:null;n*=(i===0&&a?2**-52:i)**+((a||1)*(t?1:r))}),n}function Kp(e,{ignoreFieldNorm:t=$.ignoreFieldNorm}){e.forEach(e=>{e.score=Gp(e.matches,{ignoreFieldNorm:t})})}var qp=class{constructor(e){this.limit=e,this.heap=[]}get size(){return this.heap.length}shouldInsert(e){return this.size<this.limit||e<this.heap[0].score}insert(e){this.size<this.limit?(this.heap.push(e),this._bubbleUp(this.size-1)):e.score<this.heap[0].score&&(this.heap[0]=e,this._sinkDown(0))}extractSorted(e){return this.heap.sort(e)}_bubbleUp(e){let t=this.heap;for(;e>0;){let n=e-1>>1;if(t[e].score<=t[n].score)break;let r=t[e];t[e]=t[n],t[n]=r,e=n}}_sinkDown(e){let t=this.heap,n=t.length,r=e;do{e=r;let i=2*e+1,a=2*e+2;if(i<n&&t[i].score>t[r].score&&(r=i),a<n&&t[a].score>t[r].score&&(r=a),r!==e){let n=t[e];t[e]=t[r],t[r]=n}}while(r!==e)}};function Jp(e,t){let n=e.matches;t.matches=[],zf(n)&&n.forEach(e=>{if(!zf(e.indices)||!e.indices.length)return;let{indices:n,value:r}=e,i={indices:n,value:r};e.key&&(i.key=e.key.src),e.idx>-1&&(i.refIndex=e.idx),t.matches.push(i)})}function Yp(e,t){t.score=e.score}function Xp(e,t,{includeMatches:n=$.includeMatches,includeScore:r=$.includeScore}={}){let i=[];return n&&i.push(Jp),r&&i.push(Yp),e.map(e=>{let{idx:n}=e,r={item:t[n],refIndex:n};return i.length&&i.forEach(t=>{t(e,r)}),r})}var Zp=/\b\w+\b/g;function Qp({isCaseSensitive:e=!1,ignoreDiacritics:t=!1}={}){return{tokenize(n){return e||(n=n.toLowerCase()),t&&(n=hp(n)),n.match(Zp)||[]}}}function $p(e,t,n){let r=new Map,i=new Map,a=0;function o(e,t,o,s){let c=n.tokenize(e);if(!c.length)return;a++;let l=new Map;for(let e of c)l.set(e,(l.get(e)||0)+1);for(let[e,n]of l){let a={docIdx:t,keyIdx:o,subIdx:s,tf:n},c=r.get(e);c||(c=[],r.set(e,c)),c.push(a),i.set(e,(i.get(e)||0)+1)}}for(let n of e){let{i:e,v:r,$:i}=n;if(r!==void 0){o(r,e,-1,-1);continue}if(i)for(let n=0;n<t;n++){let t=i[n];if(t)if(Array.isArray(t))for(let r of t)o(r.v,e,n,r.i??-1);else o(t.v,e,n,-1)}}return{terms:r,fieldCount:a,df:i}}function em(e,t,n,r){let{i,v:a,$:o}=t;function s(t,n,a){let o=r.tokenize(t);if(!o.length)return;e.fieldCount++;let s=new Map;for(let e of o)s.set(e,(s.get(e)||0)+1);for(let[t,r]of s){let o={docIdx:i,keyIdx:n,subIdx:a,tf:r},s=e.terms.get(t);s||(s=[],e.terms.set(t,s)),s.push(o),e.df.set(t,(e.df.get(t)||0)+1)}}if(a!==void 0){s(a,-1,-1);return}if(o)for(let e=0;e<n;e++){let t=o[e];if(t)if(Array.isArray(t))for(let n of t)s(n.v,e,n.i??-1);else s(t.v,e,-1)}}function tm(e,t){for(let[n,r]of e.terms){let i=r.filter(e=>e.docIdx!==t),a=r.length-i.length;a>0&&(e.fieldCount-=a,e.df.set(n,(e.df.get(n)||0)-a),i.length===0?(e.terms.delete(n),e.df.delete(n)):e.terms.set(n,i))}}var nm=class{constructor(e,t,n){this.options={...$,...t},this.options.useExtendedSearch,this.options.useTokenSearch,this._keyStore=new Jf(this.options.keys),this._docs=e,this._myIndex=null,this._invertedIndex=null,this.setCollection(e,n),this._lastQuery=null,this._lastSearcher=null}_getSearcher(e){if(this._lastQuery===e)return this._lastSearcher;let t=Lp(e,this._invertedIndex?{...this.options,_invertedIndex:this._invertedIndex}:this.options);return this._lastQuery=e,this._lastSearcher=t,t}setCollection(e,t){if(this._docs=e,t&&!(t instanceof ap))throw Error(Hf);if(this._myIndex=t||op(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight}),this.options.useTokenSearch){let e=Qp({isCaseSensitive:this.options.isCaseSensitive,ignoreDiacritics:this.options.ignoreDiacritics});this._invertedIndex=$p(this._myIndex.records,this._myIndex.keys.length,e)}}add(e){if(zf(e)&&(this._docs.push(e),this._myIndex.add(e),this._invertedIndex)){let e=this._myIndex.records[this._myIndex.records.length-1],t=Qp({isCaseSensitive:this.options.isCaseSensitive,ignoreDiacritics:this.options.ignoreDiacritics});em(this._invertedIndex,e,this._myIndex.keys.length,t)}}remove(e=()=>!1){let t=[],n=[];for(let r=0,i=this._docs.length;r<i;r+=1)e(this._docs[r],r)&&(t.push(this._docs[r]),n.push(r));if(n.length){if(this._invertedIndex)for(let e of n)tm(this._invertedIndex,e);for(let e=n.length-1;e>=0;--e)this._docs.splice(n[e],1);this._myIndex.removeAll(n)}return t}removeAt(e){this._invertedIndex&&tm(this._invertedIndex,e);let t=this._docs.splice(e,1)[0];return this._myIndex.removeAt(e),t}getIndex(){return this._myIndex}search(e,t){let{limit:n=-1}=t||{},{includeMatches:r,includeScore:i,shouldSort:a,sortFn:o,ignoreFieldNorm:s}=this.options;if(Pf(e)&&!e.trim()){let e=this._docs.map((e,t)=>({item:e,refIndex:t}));return Ff(n)&&n>-1&&(e=e.slice(0,n)),e}let c=Ff(n)&&n>0&&Pf(e),l;if(c){let t=new qp(n);Pf(this._docs[0])?this._searchStringList(e,{heap:t,ignoreFieldNorm:s}):this._searchObjectList(e,{heap:t,ignoreFieldNorm:s}),l=t.extractSorted(o)}else l=Pf(e)?Pf(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e),Kp(l,{ignoreFieldNorm:s}),a&&l.sort(o),Ff(n)&&n>-1&&(l=l.slice(0,n));return Xp(l,this._docs,{includeMatches:r,includeScore:i})}_searchStringList(e,{heap:t,ignoreFieldNorm:n}={}){let r=this._getSearcher(e),{records:i}=this._myIndex,a=t?null:[];return i.forEach(({v:e,i,n:o})=>{if(!zf(e))return;let{isMatch:s,score:c,indices:l}=r.searchIn(e);if(s){let r={item:e,idx:i,matches:[{score:c,value:e,norm:o,indices:l}]};t?(r.score=Gp(r.matches,{ignoreFieldNorm:n}),t.shouldInsert(r.score)&&t.insert(r)):a.push(r)}}),a}_searchLogical(e){let t=Wp(e,this.options),n=(e,t,r)=>{if(!(`children`in e)){let{keyId:n,searcher:i}=e,a;return n===null?(a=[],this._myIndex.keys.forEach((e,n)=>{a.push(...this._findMatches({key:e,value:t[n],searcher:i}))})):a=this._findMatches({key:this._keyStore.get(n),value:this._myIndex.getValueForItemAtKeyId(t,n),searcher:i}),a&&a.length?[{idx:r,item:t,matches:a}]:[]}let{children:i,operator:a}=e,o=[];for(let e=0,s=i.length;e<s;e+=1){let s=i[e],c=n(s,t,r);if(c.length)o.push(...c);else if(a===Rp.AND)return[]}return o},r=this._myIndex.records,i=new Map,a=[];return r.forEach(({$:e,i:r})=>{if(zf(e)){let o=n(t,e,r);o.length&&(i.has(r)||(i.set(r,{idx:r,item:e,matches:[]}),a.push(i.get(r))),o.forEach(({matches:e})=>{i.get(r).matches.push(...e)}))}}),a}_searchObjectList(e,{heap:t,ignoreFieldNorm:n}={}){let r=this._getSearcher(e),{keys:i,records:a}=this._myIndex,o=t?null:[];return a.forEach(({$:e,i:a})=>{if(!zf(e))return;let s=[],c=!1,l=!1;if(i.forEach((t,n)=>{let i=this._findMatches({key:t,value:e[n],searcher:r});i.length?(s.push(...i),i[0].hasInverse&&(l=!0)):c=!0}),!(l&&c)&&s.length){let r={idx:a,item:e,matches:s};t?(r.score=Gp(r.matches,{ignoreFieldNorm:n}),t.shouldInsert(r.score)&&t.insert(r)):o.push(r)}}),o}_findMatches({key:e,value:t,searcher:n}){if(!zf(t))return[];let r=[];if(jf(t))t.forEach(({v:t,i,n:a})=>{if(!zf(t))return;let{isMatch:o,score:s,indices:c,hasInverse:l}=n.searchIn(t);o&&r.push({score:s,key:e,value:t,idx:i,norm:a,indices:c,hasInverse:l})});else{let{v:i,n:a}=t,{isMatch:o,score:s,indices:c,hasInverse:l}=n.searchIn(i);o&&r.push({score:s,key:e,value:i,norm:a,indices:c,hasInverse:l})}return r}},rm=class{static condition(e,t){return t.useTokenSearch}constructor(e,t){this.options=t,this.analyzer=Qp({isCaseSensitive:t.isCaseSensitive,ignoreDiacritics:t.ignoreDiacritics});let n=this.analyzer.tokenize(e),{df:r,fieldCount:i}=t._invertedIndex;this.termSearchers=[],this.idfWeights=[];for(let e of n){this.termSearchers.push(new gp(e,{location:t.location,threshold:t.threshold,distance:t.distance,includeMatches:t.includeMatches,findAllMatches:t.findAllMatches,minMatchCharLength:t.minMatchCharLength,isCaseSensitive:t.isCaseSensitive,ignoreDiacritics:t.ignoreDiacritics,ignoreLocation:!0}));let n=r.get(e)||0,a=Math.log(1+(i-n+.5)/(n+.5));this.idfWeights.push(a)}}searchIn(e){if(!this.termSearchers.length)return{isMatch:!1,score:1};let t=[],n=0,r=0,i=0;for(let a=0;a<this.termSearchers.length;a++){let o=this.termSearchers[a].searchIn(e),s=this.idfWeights[a];r+=s,o.isMatch&&(i++,n+=s*(1-o.score),o.indices&&t.push(...o.indices))}if(i===0)return{isMatch:!1,score:1};let a=r>0?1-n/r:0,o={isMatch:!0,score:Math.max(.001,a)};return this.options.includeMatches&&t.length&&(o.indices=fp(t)),o}};nm.version=`7.3.0`,nm.createIndex=op,nm.parseIndex=sp,nm.config=$,nm.match=function(e,t,n){return Lp(e,{...$,...n}).searchIn(t)},nm.parseQuery=Wp,Ip(Pp),Ip(rm),nm.use=function(...e){e.forEach(e=>Ip(e))};var im=[{text:`text-red-400`,bgCircle:`bg-red-400`,bgCard:`bg-red-500/[0.08]`,borderCard:`border-red-500/30`,bgLight:`bg-red-500/15`,bgHover:`hover:bg-red-500`,bgAlt:`bg-red-500/[0.04]`,name:`Red`},{text:`text-orange-400`,bgCircle:`bg-orange-400`,bgCard:`bg-orange-500/[0.08]`,borderCard:`border-orange-500/30`,bgLight:`bg-orange-500/15`,bgHover:`hover:bg-orange-500`,bgAlt:`bg-orange-500/[0.04]`,name:`Orange`},{text:`text-yellow-400`,bgCircle:`bg-yellow-400`,bgCard:`bg-yellow-500/[0.08]`,borderCard:`border-yellow-500/30`,bgLight:`bg-yellow-500/15`,bgHover:`hover:bg-yellow-500`,bgAlt:`bg-yellow-500/[0.04]`,name:`Yellow`},{text:`text-green-400`,bgCircle:`bg-green-400`,bgCard:`bg-green-500/[0.08]`,borderCard:`border-green-500/30`,bgLight:`bg-green-500/15`,bgHover:`hover:bg-green-500`,bgAlt:`bg-green-500/[0.04]`,name:`Green`},{text:`text-blue-400`,bgCircle:`bg-blue-400`,bgCard:`bg-blue-500/[0.08]`,borderCard:`border-blue-500/30`,bgLight:`bg-blue-500/15`,bgHover:`hover:bg-blue-500`,bgAlt:`bg-blue-500/[0.04]`,name:`Blue`},{text:`text-accent`,bgCircle:`bg-accent`,bgCard:`bg-accent/[0.08]`,borderCard:`border-accent/30`,bgLight:`bg-accent/15`,bgHover:`hover:bg-accent`,bgAlt:`bg-accent/[0.04]`,name:`Purple`},{text:`text-pink-400`,bgCircle:`bg-pink-400`,bgCard:`bg-pink-500/[0.08]`,borderCard:`border-pink-500/30`,bgLight:`bg-pink-500/15`,bgHover:`hover:bg-pink-500`,bgAlt:`bg-pink-500/[0.04]`,name:`Pink`},{text:`text-foreground/60`,bgCircle:`bg-foreground/30`,bgCard:`bg-foreground/[0.04]`,borderCard:`border-[var(--panel-border)]/50`,bgLight:`bg-foreground/15`,bgHover:`hover:bg-foreground/30`,bgAlt:`bg-foreground/[0.02]`,name:`Default`}];function am({title:e=`Table View`,subtitle:n=`/table`,backUrl:a,tableCollection:s=`pub_table_data`,config:c,customContent:l}){let{user:u}=t.Qi(),d=!!c,f=c?.isInternal||c?.isShared;c?.isPrivate&&c?.isAdmin;let p=c?.isAdmin||f,m=d?p||s.startsWith(`role_`):!0,h=(e,t)=>u?s.startsWith(`user_`)?{...e,uid:u.uid}:t?{uid:u.uid,...e}:e:e,g=!!l,_=c?.showButton!==!1&&!g,v=c?.buttonText||`+`,y=c?.buttonStyle||`secondary`,b=c?.showExportButton!==!1,[x,S]=(0,r.useState)([]),[C,w]=(0,r.useState)(`demo`),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)(!1),[k,A]=(0,r.useState)(``),[j,M]=(0,r.useState)(!1),[N,P]=(0,r.useState)(null),[F,I]=(0,r.useState)(null),[L,R]=(0,r.useState)(``),[z,B]=(0,r.useState)(!1),[V,H]=(0,r.useState)(``),[U,W]=(0,r.useState)(null),[G,ee]=(0,r.useState)(null),[K,q]=(0,r.useState)(!1);(0,r.useEffect)(()=>{let e=s.startsWith(`user_`);if(e&&!u)return;try{let e=localStorage.getItem(`fbos_tables_${s}`);e&&S(JSON.parse(e))}catch{}let n=(0,o.onSnapshot)(e&&u?(0,o.query)((0,o.collection)(t.Ca,s),(0,o.where)(`uid`,`==`,u.uid)):(0,o.collection)(t.Ca,s),n=>{let r=[];if(n.forEach(e=>{r.push({id:e.id,...e.data()})}),r.length===0){let n={name:`Unnamed Table`,columns:[`Column 1`,`Column 2`,`Column 3`,`Column 4`],...u?{uid:u.uid}:{},rows:[{id:`1`,"Column 1":``,"Column 2":``,"Column 3":``,"Column 4":``},{id:`2`,"Column 1":``,"Column 2":``,"Column 3":``,"Column 4":``}]};(0,o.setDoc)((0,o.doc)(t.Ca,s,e&&u?`demo_${u.uid}`:`demo`),n)}else{let e=r.sort((e,t)=>(e.name||``).localeCompare(t.name||``));S(e),localStorage.setItem(`fbos_tables_${s}`,JSON.stringify(e))}});return()=>n()},[s,u]);let J=x.find(e=>e.id===C)||x[0]||{columns:[],rows:[]},Y=async e=>{J.id&&(u&&s.startsWith(`user_`)&&(e.uid=u.uid),await(0,o.setDoc)((0,o.doc)(t.Ca,s,J.id),e,{merge:!0}))},X=()=>{if(!J.rows||J.rows.length===0)return;let e=J.columns.join(`,`),t=J.rows.map(e=>J.columns.map(t=>`"${e[t]||``}"`).join(`,`)).join(`
|
|
672
|
+
`),n=new Blob([`${e}\n${t}`],{type:`text/csv`}),r=window.URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`export_${J.name||`table`}.csv`,i.click(),window.URL.revokeObjectURL(r)},te=(e,t,n)=>{Y({...J,rows:J.rows.map(r=>r.id===e?{...r,[t]:n}:r)})},ne=()=>{let e=Df(u),t={id:Date.now().toString(),...u?{_uid:u.uid,_creatorName:e.creatorName,_creatorAvatar:e.creatorAvatar}:{}};J.columns.forEach(e=>t[e]=``),Y({...J,rows:[...J.rows||[],t]})},re=e=>{Y({...J,rows:J.rows.filter(t=>t.id!==e)})},Z=()=>{let e=`Column ${(J.columns?.length||0)+1}`;J.columns?.includes(e)||(Y({...J,columns:[...J.columns||[],e]}),setTimeout(()=>{let e=document.getElementById(`table-scroll-container`);e&&e.scrollTo({left:e.scrollWidth,behavior:`smooth`})},100))},Q=e=>{let t=(J.columns||[]).filter(t=>t!==e),n=(J.rows||[]).map(t=>{let n={...t};return delete n[e],n}),r={...J.colColors||{}};delete r[e],Y({...J,columns:t,rows:n,colColors:r})},ie=async e=>{e.trim()&&J.id&&e!==J.name&&await(0,o.setDoc)((0,o.doc)(t.Ca,s,J.id),{name:e},{merge:!0})},ae=async()=>{M(!0),E(!1);let e=`tbl_${Date.now()}`;await(0,o.setDoc)((0,o.doc)(t.Ca,s,e),{name:`Unnamed Table`,columns:[`Column 1`,`Column 2`,`Column 3`],...u?{uid:u.uid}:{},rows:[]}),setTimeout(()=>{w(e),M(!1)},600)},oe=e=>{let t=V.trim();if(t&&t!==e&&!J.columns?.includes(t)){let n=J.columns.map(n=>n===e?t:n),r=(J.rows||[]).map(n=>{let r={...n};return r[t]=r[e]||``,delete r[e],r}),i={...J.colColors||{}};i[e]&&(i[t]=i[e],delete i[e]),Y({...J,columns:n,rows:r,colColors:i})}I(null)},se=e=>Of({uid:e._uid,creatorName:e._creatorName,creatorAvatar:e._creatorAvatar},u),ce=J.rows||[];return L.trim()!==``&&(ce=new nm(ce.map(e=>({...e,_creatorMatch:se(e)?.name||``})),{keys:(J.columns||[]).concat([`_creatorMatch`]),threshold:.4,ignoreLocation:!0}).search(L).map(e=>{let{_creatorMatch:t,...n}=e.item;return n})),(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[!d&&a&&(0,i.jsx)(Gt,{to:a}),(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(we,{children:e}),n&&(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),n]})]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 min-h-0 pb-16`,children:[d&&(0,i.jsx)(Ie,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden shadow-2xl relative z-10 flex flex-col flex-1 min-h-[400px]`,children:[(0,i.jsx)(`div`,{className:`absolute top-0 right-0 w-[400px] h-[400px] bg-accent/5 blur-[100px] rounded-full pointer-events-none -z-10`}),(0,i.jsxs)(`div`,{className:`p-4 md:px-6 border-b border-[var(--panel-border)]/50 flex items-center justify-between bg-foreground/[0.01] gap-3 sm:gap-4`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0 relative`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 relative`,children:[(0,i.jsxs)(`div`,{className:`relative flex items-center`,children:[D?(0,i.jsx)(`div`,{contentEditable:!0,suppressContentEditableWarning:!0,onBlur:e=>{O(!1),ie(e.currentTarget.textContent||``)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},className:`bg-transparent border-b-2 border-accent outline-none text-[16px] font-bold text-foreground inline-block min-w-[20px] whitespace-nowrap px-1 py-0.5`,children:J.name||`Unnamed Table`}):(0,i.jsx)(`h3`,{className:`font-bold text-[16px] text-foreground/90 cursor-pointer hover:text-accent transition-colors truncate max-w-[38vw] sm:max-w-[200px]`,onClick:()=>O(!0),title:`Click to rename table`,children:J.name||`Unnamed Table`}),(0,i.jsx)(t.pr,{children:T&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-40`,onClick:()=>E(!1)}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:-10},animate:{opacity:1,y:0},exit:{opacity:0,y:-10},className:`absolute top-[120%] left-0 w-[220px] bg-background/95 backdrop-blur-xl border border-[var(--panel-border)] rounded-2xl shadow-2xl z-50 py-2 flex flex-col`,children:[(0,i.jsx)(`div`,{className:`px-4 py-2 text-[10px] font-bold uppercase tracking-wider text-foreground/40 border-b border-[var(--panel-border)] mb-1`,children:`Your Tables`}),(0,i.jsx)(`div`,{className:`max-h-[250px] overflow-y-auto styled-scrollbars z-50 relative`,children:x.map(e=>(0,i.jsx)(`button`,{onClick:()=>{w(e.id),E(!1)},className:`w-full px-4 py-2 text-[13px] font-bold text-left hover:bg-foreground/[0.03] transition-colors truncate ${C===e.id?`text-accent bg-accent/5`:`text-foreground/70`}`,children:e.name||`Unnamed Table`},e.id))}),(0,i.jsx)(`div`,{className:`w-full h-[1px] bg-[var(--panel-border)]/50 my-1`}),(0,i.jsxs)(`button`,{onClick:ae,className:`w-full px-4 py-2.5 text-[13px] font-bold text-left text-foreground/70 hover:text-foreground hover:bg-foreground/5 transition-colors flex items-center gap-2`,children:[(0,i.jsx)(t.Hr,{className:`w-4 h-4`}),` Create New Table`]})]})]})})]}),(0,i.jsx)(`button`,{onClick:()=>E(!T),className:`p-1 px-1.5 rounded-lg hover:bg-foreground/5 transition-colors text-foreground/40 hover:text-foreground shrink-0 border border-transparent hover:border-[var(--panel-border)]`,children:(0,i.jsx)(t.Pi,{className:`w-4 h-4 transition-transform ${T?`rotate-180 text-accent`:``}`})})]}),(0,i.jsxs)(`span`,{className:`opacity-40 text-[11px] font-bold mt-1 uppercase tracking-wider`,children:[(J.rows||[]).length,` Records`]})]}),(0,i.jsx)(`div`,{className:`relative shrink-0 ${z?`flex-1 min-w-[130px] max-w-[300px]`:``}`,children:z?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.Ir,{className:`absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-foreground/40`}),(0,i.jsx)(`input`,{autoFocus:!0,type:`text`,"aria-label":`Search records`,placeholder:`Search records...`,value:L,onChange:e=>R(e.target.value),onBlur:()=>{L.trim()||B(!1)},onKeyDown:e=>{e.key===`Escape`&&(R(``),B(!1))},className:`w-full bg-background border border-[var(--panel-border)] rounded-xl py-2.5 px-9 text-[13px] font-medium text-foreground focus:outline-none focus:border-accent transition-colors shadow-inner`})]}):(0,i.jsx)(`button`,{type:`button`,onClick:()=>B(!0),"aria-label":`Search records`,title:`Search records`,className:`w-10 h-10 flex items-center justify-center rounded-xl border border-[var(--panel-border)] text-foreground/50 hover:text-accent hover:bg-foreground/5 transition-colors`,children:(0,i.jsx)(t.Ir,{className:`w-4 h-4`})})}),(0,i.jsxs)(`div`,{className:`flex gap-2 shrink-0`,children:[b&&(0,i.jsx)(t.cr,{variant:`secondary`,onClick:X,className:`px-3 py-2.5 font-bold rounded-xl shadow-sm border border-[var(--panel-border)] flex items-center gap-2`,children:(0,i.jsx)(t.yi,{className:`w-4 h-4`})}),_&&(0,i.jsx)(t.cr,{variant:y===`primary`?void 0:`secondary`,onClick:ne,className:`px-3 py-2.5 font-bold rounded-xl border border-[var(--panel-border)] shadow-sm flex items-center gap-2 whitespace-nowrap`,children:v===`+`?(0,i.jsx)(t.Hr,{className:`w-4 h-4`}):v})]})]}),(0,i.jsx)(`div`,{id:`table-scroll-container`,className:`overflow-auto w-full flex-1 min-h-[300px] relative styled-scrollbars`,children:l?(0,i.jsx)(`div`,{className:`fbos-content-slot p-4 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:(0,i.jsx)(l,{config:c,actions:{tables:x,activeTable:J,collection:s,user:u,saveTable:async(e,n)=>{let r=h(n,!x.some(t=>t.id===e));S(t=>t.find(t=>t.id===e)?t.map(t=>t.id===e?{...t,...r}:t):[...t,{id:e,...r}]),await(0,o.setDoc)((0,o.doc)(t.Ca,s,e),r,{merge:!0})},deleteTable:async e=>{S(t=>t.filter(t=>t.id!==e)),await(0,o.deleteDoc)((0,o.doc)(t.Ca,s,e))},updateCell:(e,t,n)=>te(e,t,n),addRow:()=>ne(),addColumn:()=>Z()}})}):(0,i.jsx)(t.pr,{mode:`wait`,children:j?(0,i.jsxs)(t.fr.div,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 flex flex-col items-center justify-center bg-background/40 backdrop-blur-[2px] z-50`,children:[(0,i.jsx)(`div`,{className:`w-8 h-8 rounded-full border-2 border-accent border-r-transparent animate-spin mb-4`}),(0,i.jsx)(`p`,{className:`text-[11px] font-bold text-foreground/50 uppercase tracking-widest`,children:`Generating Table`})]},`loader`):(0,i.jsxs)(t.fr.table,{initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`w-full text-left border-collapse table-auto relative min-w-[800px]`,children:[(0,i.jsx)(`thead`,{children:(0,i.jsxs)(`tr`,{className:`border-b border-[var(--panel-border)] transition-colors ${J.headerColor?im.find(e=>e.text===J.headerColor)?.bgAlt:`bg-foreground/[0.02]`}`,children:[(0,i.jsx)(`th`,{className:`py-4 px-6 text-[12px] font-bold uppercase tracking-wider whitespace-nowrap text-foreground/50 w-32 border-r border-[var(--panel-border)]/20 ${m?``:`hidden`}`,children:`Creator`}),(J.columns||[]).map((e,n)=>{let r=(J.colColors||{})[e],a=(J.colorTimestamps||{})[`col_${e}`]||0;J.headerColor;let o=(J.colorTimestamps||{}).header||0,s=`bg-transparent`,c=`text-foreground/50`;if(r&&r!==`none`&&a>=o){let e=im.find(e=>e.text===r);e&&(s=e.bgCard,c=e.text)}return(0,i.jsx)(`th`,{className:`py-3 px-6 text-[12px] font-bold uppercase tracking-wider relative group h-[53px] min-w-[120px] ${c} ${s} border-r border-[var(--panel-border)]/20 last:border-r-0 select-none align-middle`,children:(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-2 w-full h-full`,children:[F===e?(0,i.jsx)(`div`,{className:`flex-1 min-w-[50px]`,children:(0,i.jsx)(`span`,{contentEditable:!0,suppressContentEditableWarning:!0,onBlur:t=>{I(null),H(t.currentTarget.textContent||``),(t.currentTarget.textContent||``).trim()!==``&&oe(e)},onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),e.currentTarget.blur())},className:`bg-transparent outline-none border-b border-accent/40 font-bold text-[12px] uppercase tracking-wider p-0 m-0 ${c} block w-full whitespace-nowrap overflow-hidden cursor-text`,ref:e=>{e&&requestAnimationFrame(()=>{e.focus()})},children:V})}):(0,i.jsx)(`div`,{className:`flex items-center gap-2 flex-1 overflow-hidden`,onClick:()=>{I(e),H(e)},children:(0,i.jsx)(`span`,{className:`truncate cursor-text`,children:e})}),(0,i.jsxs)(`div`,{className:`relative shrink-0 flex items-center h-full gap-0.5`,children:[(0,i.jsx)(`button`,{onClick:()=>ee(G===e?null:e),className:`p-1.5 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity hover:bg-foreground/10 ${r&&r!==`none`?`!opacity-100`:``} text-current`,children:(0,i.jsx)(t.qr,{className:`w-4 h-4`})}),(J.columns||[]).length>1&&(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),Q(e)},className:`p-1.5 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity hover:bg-red-500/10 text-foreground/30 hover:text-red-500`,title:`Delete column`,children:(0,i.jsx)(t.Dr,{className:`w-3.5 h-3.5`})}),G===e&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-30`,onClick:()=>ee(null)}),(0,i.jsxs)(`div`,{className:`absolute top-8 right-0 flex gap-1.5 bg-background/95 backdrop-blur-xl border border-[var(--panel-border)] p-2 rounded-xl shadow-xl z-50 items-center`,children:[(0,i.jsx)(`button`,{onClick:t=>{t.preventDefault(),t.stopPropagation();let n={...J.colColors||{},[e]:`none`},r={...J.colorTimestamps||{},[`col_${e}`]:Date.now()};Y({...J,colColors:n,colorTimestamps:r}),ee(null)},className:`w-4 h-4 rounded-full flex items-center justify-center bg-foreground/10 hover:bg-red-500/20 hover:text-red-500 text-foreground/40 transition-colors border border-[var(--panel-border)]/50 shrink-0`,title:`Remove Color`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})}),(0,i.jsx)(`div`,{className:`h-4 w-px bg-[var(--panel-border)]/50 mx-0.5`}),im.map(t=>(0,i.jsx)(`button`,{onClick:n=>{n.preventDefault(),n.stopPropagation();let r={...J.colColors||{},[e]:t.text},i={...J.colorTimestamps||{},[`col_${e}`]:Date.now()};Y({...J,colColors:r,colorTimestamps:i}),ee(null)},className:`w-4 h-4 rounded-full ${t.bgCircle} hover:scale-125 transition-transform border border-[var(--panel-border)]/50 shrink-0`},t.name))]})]})]})]})},`col_${n}_${e}`)}),(0,i.jsx)(`th`,{className:`py-4 px-4 w-14 border-l border-[var(--panel-border)]/30 relative`,children:(0,i.jsxs)(`div`,{className:`flex items-center justify-end gap-0.5 relative z-20`,children:[(0,i.jsx)(`button`,{onClick:()=>q(!K),className:`p-1.5 rounded-lg transition-colors hover:bg-foreground/10 ${J.headerColor?im.find(e=>e.text===J.headerColor)?.text:`text-foreground/30`}`,children:(0,i.jsx)(t.qr,{className:`w-4 h-4`})}),K&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-30`,onClick:()=>q(!1)}),(0,i.jsxs)(`div`,{className:`absolute top-6 right-8 flex gap-1.5 bg-background/90 backdrop-blur-xl border border-[var(--panel-border)] p-2 rounded-xl shadow-xl z-50 items-center`,children:[(0,i.jsx)(`button`,{onClick:()=>{Y({...J,headerColor:``}),q(!1)},className:`w-4 h-4 rounded-full flex items-center justify-center bg-foreground/10 hover:bg-red-500/20 hover:text-red-500 text-foreground/40 transition-colors border border-[var(--panel-border)]/50 shrink-0`,title:`Remove Header Color`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})}),(0,i.jsx)(`div`,{className:`h-4 w-px bg-[var(--panel-border)]/50 mx-0.5`}),im.map(e=>(0,i.jsx)(`button`,{onClick:()=>{let t={...J.colorTimestamps||{},header:Date.now()};Y({...J,headerColor:e.text,colorTimestamps:t}),q(!1)},className:`w-4 h-4 rounded-full ${e.bgCircle} hover:scale-125 transition-transform border border-[var(--panel-border)]/50`},e.name))]})]}),(0,i.jsx)(`button`,{onClick:Z,className:`p-1.5 rounded-lg text-foreground/40 hover:text-accent hover:bg-accent/10 transition-colors flex items-center justify-center`,children:(0,i.jsx)(t.Hr,{className:`w-4 h-4`})})]})})]})}),(0,i.jsxs)(`tbody`,{children:[ce.map((e,n)=>{let r=n%2==1,a=(J.rowColors||{})[e.id],o=a?r?im.find(e=>e.text===a)?.bgAlt:im.find(e=>e.text===a)?.bgCard:r?`bg-foreground/[0.02]`:`bg-transparent`;return(0,i.jsxs)(`tr`,{className:`border-b border-[var(--panel-border)]/30 hover:bg-foreground/[0.04] transition-colors group`,children:[(0,i.jsx)(`td`,{className:`py-4 px-6 whitespace-nowrap h-[53px] border-r border-[var(--panel-border)]/20 ${o} ${m?``:`hidden`}`,children:(0,i.jsx)(`div`,{className:`flex items-center gap-2`,children:d?(()=>{let t=se(e);return t?(0,i.jsxs)(i.Fragment,{children:[t.avatar?(0,i.jsx)(`img`,{src:t.avatar,className:`w-5 h-5 rounded-full shrink-0 object-cover`}):(0,i.jsx)(`div`,{className:`w-5 h-5 rounded-full bg-accent/20 text-accent flex items-center justify-center text-[10px] font-bold shrink-0`,children:t.name[0].toUpperCase()}),(0,i.jsx)(`span`,{className:`text-[11px] font-bold text-foreground/80 tracking-tight shrink-0`,children:t.name})]}):(0,i.jsx)(`span`,{className:`text-[11px] font-bold text-foreground/30`,children:`—`})})():(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`w-5 h-5 rounded-full bg-accent/20 text-accent flex items-center justify-center text-[10px] font-bold shrink-0 shadow-inner group-hover:scale-110 transition-transform`,children:`G`}),(0,i.jsx)(`span`,{className:`text-[11px] font-bold text-foreground/80 tracking-tight shrink-0`,children:`Guest`})]})})}),(J.columns||[]).map(t=>{let a=N?.id===e.id&&N?.field===t,o=(J.colColors||{})[t],s=(J.colorTimestamps||{})[`col_${t}`]||0,c=(J.rowColors||{})[e.id],l=(J.colorTimestamps||{})[`row_${e.id}`]||0,u=``;u=l>s?c===`none`?``:c:s>l?o===`none`?``:o:c===`none`?``:c||o||``,u===`none`&&(u=``);let d=u?im.find(e=>e.text===u):null,f=d?r?d.bgAlt:d.bgCard:r?`bg-foreground/[0.02]`:`bg-transparent`,p=d?d.text:`text-foreground/80`;return(0,i.jsxs)(`td`,{className:`py-4 px-6 whitespace-pre-wrap min-w-[120px] text-[14px] font-medium relative ${f} align-top border-r border-[var(--panel-border)]/10 last:border-r-0`,onClick:()=>!a&&P({id:e.id,field:t}),children:[a?(0,i.jsx)(`textarea`,{autoFocus:!0,value:e[t]||``,onChange:n=>te(e.id,t,n.target.value),onBlur:()=>P(null),onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&P(null)},className:`absolute inset-0 bg-transparent !border-0 !outline-none focus:!outline-none focus:!ring-0 !ring-0 !shadow-none focus:!shadow-none p-4 px-6 text-[14px] font-medium w-full h-full caret-accent ${p} z-20 resize-none styled-scrollbars`}):null,(0,i.jsx)(`span`,{className:`block w-full min-h-[20px] break-words transition-all ${a?`opacity-0`:`opacity-100`} ${p} ${t===`Status`&&e[t]===`Active`&&!u?`text-green-500`:``}`,children:e[t]||(0,i.jsx)(`span`,{className:`opacity-30 italic font-normal`,children:`empty`})})]},`cell_${e.id||n}_${t}`)}),(0,i.jsx)(`td`,{className:`py-4 px-4 whitespace-nowrap text-right h-[53px] ${o} relative z-10`,children:(0,i.jsxs)(`div`,{className:`flex items-center justify-end gap-1 opacity-100 md:opacity-20 md:group-hover:opacity-100 transition-opacity relative`,children:[(0,i.jsx)(`button`,{onClick:()=>W(U===e.id?null:e.id),className:`p-1.5 rounded-lg transition-colors hover:bg-foreground/10 ${a?im.find(e=>e.text===a)?.text:`text-foreground/40`}`,children:(0,i.jsx)(t.qr,{className:`w-4 h-4`})}),U===e.id&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`div`,{className:`fixed inset-0 z-30`,onClick:()=>W(null)}),(0,i.jsxs)(`div`,{className:`absolute top-6 right-8 flex gap-1.5 bg-background/90 backdrop-blur-xl border border-[var(--panel-border)] p-2 rounded-xl shadow-xl z-50 items-center`,children:[(0,i.jsx)(`button`,{onClick:t=>{t.preventDefault(),t.stopPropagation();let n={...J.rowColors||{},[e.id]:`none`},r={...J.colorTimestamps||{},[`row_${e.id}`]:Date.now()};Y({...J,rowColors:n,colorTimestamps:r}),W(null)},className:`w-4 h-4 rounded-full flex items-center justify-center bg-foreground/10 hover:bg-red-500/20 hover:text-red-500 text-foreground/40 transition-colors border border-[var(--panel-border)]/50 shrink-0`,title:`Remove Row Color`,children:(0,i.jsx)(t._r,{className:`w-3 h-3`})}),(0,i.jsx)(`div`,{className:`h-4 w-px bg-[var(--panel-border)]/50 mx-0.5`}),im.map(t=>(0,i.jsx)(`button`,{onClick:()=>{let n={...J.colorTimestamps||{},[`row_${e.id}`]:Date.now()};Y({...J,rowColors:{...J.rowColors||{},[e.id]:t.text},colorTimestamps:n}),W(null)},className:`w-4 h-4 rounded-full ${t.bgCircle} hover:scale-125 transition-transform border border-[var(--panel-border)]/50`},t.name))]})]}),(0,i.jsx)(`button`,{onClick:()=>re(e.id),className:`p-2 ml-auto rounded-lg text-foreground/20 hover:text-red-500 hover:bg-red-500/10 transition-colors flex items-center justify-center`,children:(0,i.jsx)(t.Dr,{className:`w-4 h-4`})})]})})]},e.id||`row_${n}`)}),ce.length===0&&(0,i.jsx)(`tr`,{children:(0,i.jsxs)(`td`,{colSpan:(J.columns||[]).length+2,className:`py-12 text-center text-foreground/40 text-[14px] font-medium border border-[var(--panel-border)] m-4 rounded-xl border-dashed`,children:[`No records found in `,J.name||`this table`,`.`]})}),(0,i.jsx)(`tr`,{children:(0,i.jsx)(`td`,{colSpan:(J.columns||[]).length+2,className:`py-2 px-4 border-none bg-foreground/[0.01]`,children:(0,i.jsx)(`div`,{className:`flex items-center gap-4`,children:(0,i.jsx)(`button`,{onClick:ne,className:`p-1.5 rounded-lg text-foreground/40 hover:text-accent hover:bg-accent/10 transition-colors flex items-center justify-center ml-2 border border-transparent hover:border-accent/20`,children:(0,i.jsx)(t.Hr,{className:`w-4 h-4`})})})})})]})]},`table`)})})]})]})]})}var om=[{text:`text-red-400`,bgCircle:`bg-red-400`,bgCard:`bg-red-500/[0.08]`,borderCard:`border-red-500/30`,bgLight:`bg-red-500/15`,bgHover:`hover:bg-red-500`,bgAlt:`bg-red-500/[0.04]`,name:`Red`},{text:`text-orange-400`,bgCircle:`bg-orange-400`,bgCard:`bg-orange-500/[0.08]`,borderCard:`border-orange-500/30`,bgLight:`bg-orange-500/15`,bgHover:`hover:bg-orange-500`,bgAlt:`bg-orange-500/[0.04]`,name:`Orange`},{text:`text-yellow-400`,bgCircle:`bg-yellow-400`,bgCard:`bg-yellow-500/[0.08]`,borderCard:`border-yellow-500/30`,bgLight:`bg-yellow-500/15`,bgHover:`hover:bg-yellow-500`,bgAlt:`bg-yellow-500/[0.04]`,name:`Yellow`},{text:`text-green-400`,bgCircle:`bg-green-400`,bgCard:`bg-green-500/[0.08]`,borderCard:`border-green-500/30`,bgLight:`bg-green-500/15`,bgHover:`hover:bg-green-500`,bgAlt:`bg-green-500/[0.04]`,name:`Green`},{text:`text-blue-400`,bgCircle:`bg-blue-400`,bgCard:`bg-blue-500/[0.08]`,borderCard:`border-blue-500/30`,bgLight:`bg-blue-500/15`,bgHover:`hover:bg-blue-500`,bgAlt:`bg-blue-500/[0.04]`,name:`Blue`},{text:`text-accent`,bgCircle:`bg-accent`,bgCard:`bg-accent/[0.08]`,borderCard:`border-accent/30`,bgLight:`bg-accent/15`,bgHover:`hover:bg-accent`,bgAlt:`bg-accent/[0.04]`,name:`Purple`},{text:`text-pink-400`,bgCircle:`bg-pink-400`,bgCard:`bg-pink-500/[0.08]`,borderCard:`border-pink-500/30`,bgLight:`bg-pink-500/15`,bgHover:`hover:bg-pink-500`,bgAlt:`bg-pink-500/[0.04]`,name:`Pink`},{text:`text-foreground/60`,bgCircle:`bg-foreground/30`,bgCard:`bg-foreground/[0.04]`,borderCard:`border-[var(--panel-border)]/50`,bgLight:`bg-foreground/15`,bgHover:`hover:bg-foreground/30`,bgAlt:`bg-foreground/[0.02]`,name:`Default`}],sm={dateStr:``,title:``,description:``,time:`12:00`,duration:`60`,color:``,guestEmail:``,customFields:{}};function cm({title:e=`Calendar View`,subtitle:n=`/calendar`,backUrl:s,eventsCollection:l=`pub_events`,defaultTimeFormat:u=`12h`,config:d,customContent:f}){let p=!!(d?.isPrivate||d?.isAdmin||d?.isInternal||d?.isShared);d?.isAdmin,d?.isInternal||d?.isShared,d?.isPrivate;let m=d?.showButton!==!1,h=d?.buttonText||`+`,g=d?.buttonStyle||`primary`,_=d?.showViewsButton!==!1,v=d?.viewsButtonStyle||`secondary`,y=d?.defaultView||`calendar`,b=d?.customFields||[],x=l.startsWith(`user_`)?`user`:l.startsWith(`mem_`)||l.startsWith(`role_`)?`internal`:l.startsWith(`admin_`)?`admin_only`:`public`,[S,C]=(0,r.useState)(()=>{try{let e=localStorage.getItem(`cal_view_${l}`);if(e===`list`||e===`month`)return e}catch{}return y===`board`?`list`:`month`}),[w,T]=(0,r.useState)([]),[E,D]=(0,r.useState)(!1),[O,k]=(0,r.useState)(null),[A,j]=(0,r.useState)(!1),[M,N]=(0,r.useState)(!1),[P,F]=(0,r.useState)(null),[I,L]=(0,r.useState)(sm),[R,z]=(0,r.useState)(new Date),[B,V]=(0,r.useState)(null),[H,U]=(0,r.useState)(null),[W,G]=(0,r.useState)(!1),ee=`cal_24h_${l}`,[K,q]=(0,r.useState)(()=>{try{let e=localStorage.getItem(ee);if(e!==null)return e===`true`}catch{}return u===`24h`}),J=()=>{let e=!K;q(e);try{localStorage.setItem(ee,String(e))}catch{}};(0,r.useEffect)(()=>{try{localStorage.setItem(`cal_view_${l}`,S)}catch{}},[S,l,x]);let Y=()=>{let e=S===`month`?`list`:`month`;C(e);try{localStorage.setItem(`cal_view_${l}`,e)}catch{}},X=()=>{try{return sessionStorage.getItem(`cal_guest_email`)||``}catch{return``}},te=e=>{try{sessionStorage.setItem(`cal_guest_email`,e)}catch{}};(0,r.useEffect)(()=>(0,a.onAuthStateChanged)(t.Sa,async e=>{if(V(e),e&&x===`admin_only`)try{let n=await(0,o.getDoc)((0,o.doc)(t.Ca,`user_profiles`,e.uid));n.exists()&&U(n.data())}catch{}G(!0)}),[x]),(0,r.useEffect)(()=>{if(!W)return;if(x!==`public`&&!B){T([]);return}try{let e=localStorage.getItem(`fbos_cal_${l}`);e&&T(JSON.parse(e))}catch{}let e=(0,o.onSnapshot)(x===`user`&&B?(0,o.query)((0,o.collection)(t.Ca,l),(0,o.where)(`uid`,`==`,B.uid)):(0,o.collection)(t.Ca,l),e=>{let t=[];e.forEach(e=>t.push({id:e.id,...e.data()})),T(t),localStorage.setItem(`fbos_cal_${l}`,JSON.stringify(t))},e=>console.error(`Calendar events:`,e));return()=>e()},[l,x,B?.uid,W]);let ne=e=>!!B&&B.uid===e.uid,re=e=>x===`public`?!1:x===`user`?!!B:ne(e),Z=(e,t)=>!B||x===`public`?e:x===`user`?{...e,uid:B.uid}:t?{uid:B.uid,creatorEmail:B.email||``,creatorName:B.displayName||``,creatorAvatar:B.photoURL||``,...e}:e,Q=e=>{if(!e)return``;if(K)return e;let[t,n]=e.split(`:`),r=parseInt(t,10),i=r>=12?`PM`:`AM`;return r=r%12||12,`${r}:${n} ${i}`},ie=e=>{if(!e)return`60m`;let t=parseInt(e,10);return isNaN(t)?e:t>=60?t%60==0?`${t/60}h`:`${Math.floor(t/60)}h ${t%60}m`:`${t}m`},ae=e=>{let[t,n]=(e||`12:00`).split(`:`),r=parseInt(t,10)||0,i=parseInt(n,10)||0,a=r>=12?`PM`:`AM`;return r=r%12||12,{h:r,m:i,ampm:a}},oe=(e,t,n)=>{let r=e%12;return n===`PM`&&(r+=12),`${r.toString().padStart(2,`0`)}:${t.toString().padStart(2,`0`)}`},se=e=>{let t=e.getTimezoneOffset()*6e4;return new Date(e.getTime()-t).toISOString().split(`T`)[0]},ce=()=>se(new Date),le=new Date(R.getFullYear(),R.getMonth(),1),ue=new Date(R.getFullYear(),R.getMonth()+1,0),de=le.getDay(),fe=ue.getDate(),pe=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],me=Array.from({length:42},(e,t)=>{let n=t-de+1,r=new Date(R.getFullYear(),R.getMonth(),n);return{day:r.getDate(),dateStr:se(r),isCurrentMonth:n>0&&n<=fe}}),he=()=>z(S===`month`?new Date(R.getFullYear(),R.getMonth()-1,1):new Date(R.getFullYear(),R.getMonth(),R.getDate()-1)),ge=()=>z(S===`month`?new Date(R.getFullYear(),R.getMonth()+1,1):new Date(R.getFullYear(),R.getMonth(),R.getDate()+1)),_e=e=>{if(x!==`public`&&!B)return;let t=new Date;t.setDate(t.getDate()+1);let n=new Date().getHours().toString().padStart(2,`0`);L({...sm,dateStr:e||se(t),time:`${n}:00`,guestEmail:x===`public`?X():``,customFields:{}}),D(!0)},ve=e=>{let t=e.time;if(t){let[e,n]=t.split(`:`);e&&n&&(t=`${e.padStart(2,`0`)}:${n}`)}L({id:e.id,uid:e.uid,dateStr:e.dateStr,title:e.title,description:e.description||``,time:t||`12:00`,duration:e.duration||`60`,color:e.color||``,guestEmail:e.creatorEmail||``,customFields:e.customFields||{}}),D(!0)},ye=async e=>{if(e.preventDefault(),I.title.trim()){j(!0);try{let e={dateStr:I.dateStr,title:I.title.trim(),description:I.description.trim(),time:I.time,duration:I.duration||`60`};if(I.color&&(e.color=I.color),b.length>0&&(e.customFields=I.customFields),!I.id)if(x===`public`){let t=I.guestEmail.trim();e.creatorEmail=t,te(t)}else x===`user`||x===`internal`?(e.uid=B?.uid,e.creatorEmail=B?.email||``,e.creatorName=B?.displayName||``,e.creatorAvatar=B?.photoURL||``):x===`admin_only`&&(e.uid=B?.uid,e.creatorEmail=H?.email||B?.email||``,e.creatorName=H?.displayName||H?.name||``,e.creatorAvatar=H?.avatar||H?.avatarUrl||B?.photoURL||``);I.id?(await(0,o.setDoc)((0,o.doc)(t.Ca,l,I.id),e,{merge:!0}),O?.id===I.id&&k({...O,...e})):await(0,o.setDoc)((0,o.doc)(t.Ca,l,`ev_${Date.now()}`),e,{merge:!0}),D(!1)}catch(e){console.error(e)}j(!1)}},be=async()=>{if(P){N(!0);try{await(0,o.deleteDoc)((0,o.doc)(t.Ca,l,P.id)),O?.id===P.id&&k(null),F(null),D(!1)}catch{}N(!1)}},xe=e=>{if(x===`user`||!e.creatorEmail&&!e.creatorName)return null;let t=(e.creatorName||e.creatorEmail||`?`).charAt(0).toUpperCase(),n=om.find(t=>t.text===e.color);return(0,i.jsxs)(`div`,{className:`flex items-center gap-3 mt-4 p-3 rounded-xl bg-foreground/[0.03] border border-[var(--panel-border)]/50`,children:[e.creatorAvatar?(0,i.jsx)(`img`,{src:e.creatorAvatar,alt:``,className:`w-8 h-8 rounded-full object-cover shrink-0`}):(0,i.jsx)(`div`,{className:`w-8 h-8 rounded-full ${n?.bgCircle||`bg-accent`} flex items-center justify-center text-[13px] font-extrabold text-white shrink-0`,children:t}),(0,i.jsxs)(`div`,{className:`flex flex-col min-w-0`,children:[e.creatorName&&(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground/90 truncate`,children:e.creatorName}),e.creatorEmail&&(0,i.jsx)(`span`,{className:`text-[12px] text-foreground/50 truncate`,children:e.creatorEmail})]})]})},Se=e=>{if(x===`user`||x===`public`||!e.creatorName&&!e.creatorEmail)return null;let t=e.creatorName||e.creatorEmail?.split(`@`)[0]||``,n=t.split(` `).map(e=>e[0]).join(``).toUpperCase().slice(0,2);return(0,i.jsxs)(`div`,{className:`flex items-center gap-2 mt-2 pt-2 border-t border-[var(--panel-border)]/30`,children:[e.creatorAvatar?(0,i.jsx)(`img`,{src:e.creatorAvatar,alt:``,className:`w-5 h-5 rounded-full object-cover shrink-0`}):(0,i.jsx)(`div`,{className:`w-5 h-5 rounded-full bg-accent/15 text-accent flex items-center justify-center text-[8px] font-extrabold shrink-0`,children:n}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 truncate`,children:t}),e.creatorEmail&&(0,i.jsxs)(`span`,{className:`text-[10px] text-foreground/25 truncate`,children:[`· `,e.creatorEmail]})]})]})};if(W&&x!==`public`&&!B)return(0,i.jsx)(`main`,{className:`flex-1 w-full flex items-center justify-center min-h-screen p-8`,children:(0,i.jsxs)(`div`,{className:`text-center glass-panel border border-[var(--panel-border)] rounded-3xl p-12 max-w-sm w-full`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-full bg-accent/10 border border-accent/20 flex items-center justify-center mx-auto mb-4`,children:(0,i.jsx)(t.Xr,{className:`w-7 h-7 text-accent`})}),(0,i.jsx)(`h2`,{className:`text-2xl font-extrabold mb-2`,children:`Sign in required`}),(0,i.jsx)(`p`,{className:`text-foreground/50 text-[14px] mb-6`,children:`You need to be signed in to access this calendar.`}),(0,i.jsx)(c.Link,{to:`/login`,className:`inline-flex items-center justify-center gap-2 px-6 py-2.5 rounded-xl btn-primary font-bold text-[14px] w-full`,children:`Sign In`})]})});if(!W&&x!==`public`)return(0,i.jsx)(`main`,{className:`flex-1 w-full flex items-center justify-center min-h-screen`,children:(0,i.jsx)(t.ei,{className:`w-8 h-8 animate-spin text-accent`})});let Ce=!!f,Te=(x===`public`||!!B)&&m&&!Ce,Ee=()=>(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4 p-4 sm:p-6 md:px-8 md:py-6 border-b border-[var(--panel-border)]/50 bg-background/50 shrink-0`,children:[(0,i.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,i.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:d?.tabTitle||d?.tabName||e}),(0,i.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:[w.length,` `,w.length===1?`event`:`events`,` · `,S===`month`?`Month`:`Board`,` View`]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:J,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer btn-secondary text-[12px] font-extrabold`,children:K?`24h`:`12h`}),_&&!Ce&&(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:Y,title:S===`month`?`Switch to Board`:`Switch to Calendar`,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer ${v===`primary`?`btn-primary`:`btn-secondary`}`,children:S===`month`?(0,i.jsx)(t.ii,{className:`w-4 h-4`}):(0,i.jsx)(t.Li,{className:`w-4 h-4`})}),Te&&(0,i.jsx)(t.fr.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>_e(),title:`Add event`,"aria-label":`Add event`,className:`h-10 flex items-center justify-center gap-2 rounded-xl transition-all duration-300 cursor-pointer ${h===`+`?`w-10`:`px-5`} ${g===`primary`?`btn-primary`:`btn-secondary`}`,children:h===`+`?(0,i.jsx)(t.Hr,{className:`w-4 h-4`}):(0,i.jsx)(`span`,{className:`text-[13px] font-bold`,children:h})})]})]}),De=()=>(0,i.jsxs)(`div`,{className:`p-4 md:p-6 border-b border-[var(--panel-border)]/50 flex flex-wrap items-center justify-between gap-x-3 gap-y-2 bg-foreground/[0.01]`,children:[(0,i.jsx)(`h3`,{className:`text-lg md:text-xl font-extrabold tracking-tight ml-2 min-w-0`,children:S===`month`?R.toLocaleString(`default`,{month:`long`,year:`numeric`}):R.toLocaleString(`default`,{month:`long`,day:`numeric`,year:`numeric`})}),(0,i.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,i.jsx)(`button`,{onClick:()=>z(new Date),className:`px-3 md:px-4 py-2 text-[13px] font-bold border border-[var(--panel-border)] rounded-xl mr-1 md:mr-2 hover:bg-foreground/5 transition-colors`,children:`Today`}),(0,i.jsx)(`button`,{onClick:he,className:`p-2 rounded-xl text-foreground/50 hover:text-foreground hover:bg-foreground/5 transition-colors border border-transparent hover:border-[var(--panel-border)]`,children:(0,i.jsx)(t.Ni,{className:`w-5 h-5`})}),(0,i.jsx)(`button`,{onClick:ge,className:`p-2 rounded-xl text-foreground/50 hover:text-foreground hover:bg-foreground/5 transition-colors border border-transparent hover:border-[var(--panel-border)]`,children:(0,i.jsx)(t.Mi,{className:`w-5 h-5`})})]})]}),Oe=()=>(0,i.jsxs)(i.Fragment,{children:[De(),f?(0,i.jsx)(`div`,{className:`fbos-content-slot p-4 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:(0,i.jsx)(f,{config:d,actions:{events:w,loading:!W,collection:l,currentUser:B,user:B,saveEvent:async e=>{let n=e.id||`ev_${Date.now()}`,r=Z(e,!w.some(e=>e.id===n));T(e=>e.find(e=>e.id===n)?e.map(e=>e.id===n?{...e,...r}:e):[...e,{id:n,...r}]),await(0,o.setDoc)((0,o.doc)(t.Ca,l,n),r,{merge:!0})},deleteEvent:async e=>{T(t=>t.filter(t=>t.id!==e)),await(0,o.deleteDoc)((0,o.doc)(t.Ca,l,e))},openAddModal:e=>_e(e),openEditModal:e=>ve(e),setViewingEvent:e=>k(e),currentDate:R,setCurrentDate:z,goToPrev:he,goToNext:ge,goToToday:()=>z(new Date)}})}):S===`month`?(0,i.jsx)(`div`,{className:`overflow-x-auto w-full flex-1`,children:(0,i.jsxs)(`div`,{className:`min-w-[800px] h-full flex flex-col`,children:[(0,i.jsx)(`div`,{className:`grid grid-cols-7 border-b border-[var(--panel-border)]/50 bg-foreground/[0.02]`,children:pe.map(e=>(0,i.jsx)(`div`,{className:`py-3 text-center text-[12px] font-bold uppercase tracking-wider text-foreground/40`,children:e},e))}),(0,i.jsx)(`div`,{className:`grid grid-cols-7 auto-rows-auto bg-[var(--panel-border)] gap-[1px] relative flex-1`,children:me.map((e,n)=>{let r=e.dateStr===ce(),a=w.filter(t=>t.dateStr===e.dateStr);return(0,i.jsxs)(`div`,{onClick:()=>e.isCurrentMonth&&Te&&_e(e.dateStr),className:`min-h-[140px] p-2 bg-[var(--panel-bg)] flex flex-col relative group
|
|
673
|
+
${e.isCurrentMonth?Te?`hover:bg-foreground/[0.03] transition-colors cursor-cell`:``:`opacity-30 bg-background/50 pointer-events-none`}`,children:[(0,i.jsx)(`div`,{className:`flex justify-between items-start mb-2 shrink-0`,children:(0,i.jsx)(`span`,{className:`w-8 h-8 rounded-full flex items-center justify-center text-[14px] font-bold ${r?`bg-accent text-white shadow-lg shadow-accent/20`:`text-foreground/70 group-hover:text-foreground`}`,children:e.day})}),(0,i.jsx)(`div`,{className:`flex flex-col gap-1.5 flex-1 w-full relative z-10 pb-1`,children:a.map(e=>{let n=om.find(t=>t.text===e.color),r=re(e);return(0,i.jsxs)(`div`,{className:`px-2 py-1.5 rounded-lg border transition-colors shadow-sm cursor-pointer group/ev relative ${n?n.bgCard+` `+n.borderCard:`bg-accent/20 border-accent/30 hover:bg-accent/40`}`,onClick:t=>{t.stopPropagation(),k(e)},children:[(0,i.jsx)(`p`,{className:`text-[12px] font-bold truncate leading-tight ${r?`pr-5`:``} ${n?n.text:`text-foreground`}`,children:e.title}),(0,i.jsx)(`p`,{className:`text-[10px] text-foreground/70 mt-0.5`,children:Q(e.time)}),r&&(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),ve(e)},className:`absolute top-1 right-1 opacity-0 group-hover/ev:opacity-100 p-1 text-foreground/60 hover:bg-foreground/10 hover:text-foreground transition-all rounded`,children:(0,i.jsx)(t.Gr,{className:`w-3 h-3`})})]},e.id)})})]},n)})}),(0,i.jsx)(`style`,{children:`
|
|
674
|
+
.styled-scrollbars::-webkit-scrollbar{width:4px}
|
|
675
|
+
.styled-scrollbars::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--accent-color) 30%,transparent);border-radius:4px}
|
|
676
|
+
input[type="time"]::-webkit-calendar-picker-indicator{display:none!important}
|
|
677
|
+
input[type="date"]{color-scheme:dark}
|
|
678
|
+
input[type="date"]::-webkit-calendar-picker-indicator{cursor:pointer;opacity:.5;transition:opacity .2s}
|
|
679
|
+
input[type="date"]::-webkit-calendar-picker-indicator:hover{opacity:1}
|
|
680
|
+
`})]})}):(0,i.jsxs)(`div`,{className:`flex flex-col p-4 md:p-8 overflow-y-auto w-full flex-1 gap-4`,children:[w.filter(e=>e.dateStr===se(R)).sort((e,t)=>e.time.localeCompare(t.time)).map(e=>{let n=new Date(e.dateStr+`T12:00:00`),r=om.find(t=>t.text===e.color),a=re(e);return(0,i.jsxs)(`div`,{onClick:()=>k(e),className:`p-4 rounded-2xl border flex flex-col cursor-pointer transition-colors group ${r?r.bgCard+` `+r.borderCard+` hover:brightness-110`:`bg-foreground/[0.01] border-[var(--panel-border)]/70 hover:border-accent/40 hover:bg-foreground/[0.02]`}`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3 shrink-0`,children:[(0,i.jsxs)(`div`,{className:`w-11 h-11 md:w-12 md:h-12 rounded-xl flex flex-col items-center justify-center border transition-colors shadow-sm ${r?r.bgCard+` `+r.borderCard:`bg-foreground/5 border-[var(--panel-border)] group-hover:bg-accent/10 group-hover:border-accent/30`}`,children:[(0,i.jsx)(`span`,{className:`text-[10px] font-bold uppercase leading-none mb-0.5 ${r?r.text:`text-foreground/40 group-hover:text-accent/60`}`,children:n.toLocaleString(`default`,{month:`short`})}),(0,i.jsx)(`span`,{className:`text-[18px] font-black leading-none ${r?r.text:`group-hover:text-accent`}`,children:n.getDate()})]}),(0,i.jsx)(`div`,{className:`h-6 w-px bg-[var(--panel-border)] max-sm:hidden group-hover:bg-accent/30 transition-colors`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-1 min-w-0 flex-1`,children:[(0,i.jsx)(`h4`,{className:`text-[15px] md:text-[16px] font-extrabold tracking-tight truncate ${r?r.text:`text-foreground group-hover:text-accent`}`,children:e.title}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3 text-[12px] text-foreground/50 font-medium`,children:[(0,i.jsx)(`span`,{children:Q(e.time)}),(0,i.jsxs)(`span`,{className:`flex items-center gap-1`,children:[(0,i.jsx)(t.Ti,{className:`w-3 h-3`}),ie(e.duration)]})]})]}),a&&(0,i.jsxs)(`div`,{className:`ml-auto pl-2 flex items-center gap-1 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity`,children:[(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),ve(e)},className:`p-2.5 rounded-xl text-foreground/50 hover:bg-foreground/10 hover:text-foreground transition-colors`,children:(0,i.jsx)(t.Gr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:t=>{t.stopPropagation(),F(e)},className:`p-2.5 rounded-xl text-foreground/30 hover:bg-red-500/10 hover:text-red-500 transition-colors`,children:(0,i.jsx)(t.Dr,{className:`w-4 h-4`})})]})]}),p&&Se(e)]},e.id)}),w.filter(e=>e.dateStr===se(R)).length===0&&(0,i.jsx)(`div`,{className:`p-12 text-center text-foreground/40 font-medium`,children:`No events scheduled for this day.`})]})]}),ke=()=>(0,i.jsxs)(t.pr,{children:[O&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[100] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>k(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/80 backdrop-blur-xl cursor-pointer`}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`w-full max-w-[500px] p-6 sm:p-8 rounded-3xl glass-popover border shadow-2xl relative z-10 ${om.find(e=>e.text===O.color)?.borderCard||`border-[var(--panel-border)]`}`,children:[(0,i.jsxs)(`div`,{className:`absolute top-4 right-4 flex items-center gap-1 bg-background/50 backdrop-blur-3xl p-1 rounded-2xl border border-[var(--panel-border)]/50 shadow-sm z-50`,children:[re(O)&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`button`,{onClick:()=>{k(null),ve(O)},className:`p-2 rounded-xl text-foreground/50 hover:bg-foreground/10 hover:text-foreground transition-all`,title:`Edit`,children:(0,i.jsx)(t.Gr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>{F(O),k(null)},className:`p-2 rounded-xl text-foreground/50 hover:bg-red-500/10 hover:text-red-500 transition-all`,title:`Delete`,children:(0,i.jsx)(t.Dr,{className:`w-4 h-4`})}),(0,i.jsx)(`div`,{className:`w-px h-6 bg-[var(--panel-border)]/50 mx-1`})]}),(0,i.jsx)(`button`,{onClick:()=>k(null),className:`p-2 rounded-xl text-foreground/40 hover:bg-foreground/10 hover:text-foreground transition-all`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})})]}),(0,i.jsxs)(`div`,{className:`mb-6 mt-12 sm:mt-0 sm:pr-32`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2 mb-3`,children:[(0,i.jsx)(`span`,{className:`w-2.5 h-2.5 rounded-full ${om.find(e=>e.text===O.color)?.bgCircle||`bg-accent`}`}),(0,i.jsx)(`span`,{className:`text-[11px] font-bold tracking-[0.2em] uppercase ${om.find(e=>e.text===O.color)?.text||`text-accent`}`,children:`Event Details`})]}),(0,i.jsx)(`h3`,{className:`text-xl sm:text-3xl font-black mb-3 tracking-tight leading-tight break-words ${om.find(e=>e.text===O.color)?.text||`text-foreground`}`,children:O.title}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 mt-4`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5 text-[14px] text-foreground/70 font-medium`,children:[(0,i.jsx)(`div`,{className:`w-8 h-8 rounded-full bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.Li,{className:`w-4 h-4 text-foreground/50`})}),new Date(O.dateStr+`T12:00:00`).toLocaleDateString(`default`,{weekday:`long`,month:`long`,day:`numeric`,year:`numeric`})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2.5 text-[14px] text-foreground/70 font-medium`,children:[(0,i.jsx)(`div`,{className:`w-8 h-8 rounded-full bg-foreground/5 border border-[var(--panel-border)] flex items-center justify-center shrink-0`,children:(0,i.jsx)(t.Ti,{className:`w-4 h-4 text-foreground/50`})}),Q(O.time),` `,(0,i.jsxs)(`span`,{className:`text-foreground/40 text-[12px] ml-1`,children:[`(`,ie(O.duration),`)`]})]})]}),xe(O)]}),(0,i.jsx)(`div`,{className:`w-full h-px bg-gradient-to-r from-[var(--panel-border)]/0 via-[var(--panel-border)] to-[var(--panel-border)]/0 mb-6`}),O.description?(0,i.jsx)(`div`,{className:`bg-foreground/[0.02] border border-[var(--panel-border)]/50 rounded-2xl py-3 px-4 mb-4 w-full overflow-hidden`,children:(0,i.jsx)(`div`,{className:`text-[14px] text-foreground/80 font-medium whitespace-pre-wrap leading-tight break-words`,children:O.description})}):(0,i.jsx)(`div`,{className:`p-4 mb-4 rounded-2xl border border-dashed border-[var(--panel-border)] bg-foreground/[0.01] text-center`,children:(0,i.jsx)(`p`,{className:`text-[12px] font-medium text-foreground/40`,children:`No description provided for this event.`})}),O.customFields&&Object.entries(O.customFields).filter(([,e])=>e).length>0&&(0,i.jsx)(`div`,{className:`flex flex-col gap-2 mb-2`,children:Object.entries(O.customFields).filter(([,e])=>e).map(([e,t])=>(0,i.jsxs)(`div`,{className:`flex items-start gap-2 text-[13px]`,children:[(0,i.jsxs)(`span`,{className:`font-bold text-foreground/50 capitalize shrink-0`,children:[e,`:`]}),(0,i.jsx)(`span`,{className:`text-foreground/80 font-medium break-words min-w-0`,children:t})]},e))})]})]},`view-modal`),E&&(0,i.jsxs)(`div`,{className:`fixed inset-0 z-[100] flex items-center justify-center p-4`,children:[(0,i.jsx)(t.fr.div,{onClick:()=>D(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/80 backdrop-blur-xl cursor-pointer`}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95,y:10},animate:{opacity:1,scale:1,y:0},exit:{opacity:0,scale:.95,y:10},className:`w-full max-w-[500px] p-6 sm:p-8 rounded-3xl glass-popover border border-[var(--panel-border)] shadow-2xl relative z-10 max-h-[90vh] overflow-y-auto styled-scrollbars`,children:[(0,i.jsxs)(`div`,{className:`absolute top-4 right-4 flex items-center gap-1`,children:[I.id&&re({uid:I.uid})&&(0,i.jsx)(`button`,{onClick:()=>{D(!1),F({id:I.id,...I})},className:`p-2 rounded-xl text-foreground/30 hover:bg-red-500/10 hover:text-red-500 transition-all`,children:(0,i.jsx)(t.Dr,{className:`w-4 h-4`})}),(0,i.jsx)(`button`,{onClick:()=>D(!1),className:`p-2 rounded-xl text-foreground/40 hover:bg-foreground/10 hover:text-foreground transition-all`,children:(0,i.jsx)(t._r,{className:`w-5 h-5`})})]}),(0,i.jsxs)(`div`,{className:`mb-6 pr-12`,children:[(0,i.jsx)(`h3`,{className:`text-2xl font-extrabold mb-1 tracking-tight`,children:I.id?`Edit Event`:`Add Event`}),(0,i.jsx)(`p`,{className:`text-[14px] text-foreground/50`,children:I.id?`Modify your scheduled calendar block.`:`Schedule a new calendar block.`})]}),(0,i.jsxs)(`form`,{onSubmit:ye,className:`space-y-4`,children:[x===`public`&&!I.id&&(0,i.jsx)(t.lr,{label:`Your Email`,type:`email`,value:I.guestEmail,onChange:e=>L({...I,guestEmail:e.target.value}),placeholder:`you@example.com`,required:!0}),(0,i.jsx)(t.lr,{label:`Event Title`,value:I.title,onChange:e=>L({...I,title:e.target.value}),placeholder:`e.g. Design Sync`,required:!0}),(0,i.jsxs)(`div`,{className:`flex flex-col w-full relative`,children:[(0,i.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,children:`Description`}),(0,i.jsx)(`textarea`,{value:I.description,onChange:e=>L({...I,description:e.target.value}),placeholder:`e.g. Discussing the new features...`,className:`block min-h-[80px] w-full rounded-xl text-[15px] text-foreground px-4 py-3 transition-all duration-300 placeholder:text-foreground/40 focus:outline-none focus:border-accent glow-focus glass-panel styled-scrollbars resize-none`})]}),b.map(e=>(0,i.jsx)(t.lr,{label:e,value:I.customFields[e]||``,onChange:t=>L({...I,customFields:{...I.customFields,[e]:t.target.value}}),placeholder:`Enter ${e.toLowerCase()}...`},e)),(0,i.jsx)(`style`,{children:`
|
|
681
|
+
input[type="date"]::-webkit-calendar-picker-indicator{background:transparent;bottom:0;color:transparent;cursor:pointer;height:auto;left:0;position:absolute;right:0;top:0;width:auto;z-index:10}
|
|
682
|
+
input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
|
|
683
|
+
input[type="number"]{-moz-appearance:textfield}
|
|
684
|
+
`}),(0,i.jsxs)(`div`,{className:`relative group/date flex flex-col w-full`,children:[(0,i.jsx)(t.lr,{type:`date`,label:`Date`,required:!0,value:I.dateStr,onChange:e=>L({...I,dateStr:e.target.value}),className:`pr-10`}),(0,i.jsx)(`div`,{className:`absolute right-4 bottom-4 pointer-events-none group-focus-within/date:text-accent text-foreground/40 transition-colors`,children:(0,i.jsx)(t.Li,{className:`w-4 h-4`})})]}),(0,i.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-4`,children:[K?(0,i.jsx)(t.lr,{type:`time`,label:`Time`,value:I.time,onChange:e=>L({...I,time:e.target.value}),required:!0}):(()=>{let{h:e,m:t,ampm:n}=ae(I.time);return(0,i.jsxs)(`div`,{className:`flex flex-col w-full`,children:[(0,i.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,children:`Time`}),(0,i.jsxs)(`div`,{className:`flex items-center h-12 glass-panel border border-[var(--panel-border)] rounded-xl px-3 gap-1 focus-within:border-accent transition-colors`,children:[(0,i.jsx)(`input`,{type:`number`,min:1,max:12,value:e,onChange:e=>L({...I,time:oe(Math.min(12,Math.max(1,parseInt(e.target.value)||12)),t,n)}),className:`w-8 text-center bg-transparent focus:outline-none text-foreground font-bold text-[15px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none`}),(0,i.jsx)(`span`,{className:`text-foreground/40 font-bold text-[15px] select-none`,children:`:`}),(0,i.jsx)(`input`,{type:`number`,min:0,max:59,value:t.toString().padStart(2,`0`),onChange:t=>L({...I,time:oe(e,Math.min(59,Math.max(0,parseInt(t.target.value)||0)),n)}),className:`w-8 text-center bg-transparent focus:outline-none text-foreground font-bold text-[15px] [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none`}),(0,i.jsx)(`button`,{type:`button`,onClick:()=>L({...I,time:oe(e,t,n===`AM`?`PM`:`AM`)}),className:`ml-auto px-2 py-0.5 rounded-md bg-accent/10 text-accent text-[11px] font-extrabold uppercase tracking-wider hover:bg-accent/20 transition-colors shrink-0`,children:n})]})]})})(),(0,i.jsx)(t.lr,{type:`number`,min:`1`,max:`1440`,label:`Duration (min)`,value:I.duration,onChange:e=>L({...I,duration:e.target.value}),placeholder:`60`,required:!0})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsx)(`label`,{className:`text-[11px] font-bold text-foreground/50 uppercase tracking-widest mt-1`,children:`Event Color`}),(0,i.jsx)(`div`,{className:`flex gap-2 items-center relative z-10 w-full h-[46px]`,children:om.map(e=>(0,i.jsx)(`button`,{type:`button`,onClick:()=>L({...I,color:I.color===e.text?``:e.text}),className:`w-6 h-6 rounded-full shrink-0 ${e.bgCircle} hover:scale-110 transition-transform flex items-center justify-center border border-[var(--panel-border)]`,children:I.color===e.text&&(0,i.jsx)(`div`,{className:`w-2.5 h-2.5 rounded-full bg-background`})},e.name))})]}),(0,i.jsx)(`div`,{className:`pt-2`,children:(0,i.jsx)(t.cr,{type:`submit`,isLoading:A,className:`w-full py-3`,children:I.id?`Save Changes`:`Create Event`})})]})]})]},`edit-modal`),(0,i.jsx)(He,{isOpen:!!P,title:`Confirm Deletion`,message:(0,i.jsxs)(i.Fragment,{children:[`Are you sure you want to delete `,(0,i.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:P?.title}),` This action is permanent.`]}),onConfirm:be,onCancel:()=>{F(null)},isProcessing:M,confirmText:`Yes, Delete`})]});return p?(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col`,children:[(0,i.jsx)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,i.jsxs)(`div`,{children:[(0,i.jsx)(we,{children:d?.tabTitle||d?.tabName||e}),n&&(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),n]})]})}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 shadow-2xl bg-background`,children:[Ee(),Oe()]})]}),ke()]}):(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[s&&(0,i.jsx)(Gt,{to:s}),(0,i.jsxs)(`div`,{className:`min-w-0`,children:[(0,i.jsx)(we,{children:e}),n&&(0,i.jsxs)(`div`,{className:`max-sm:hidden sm:flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),n]})]})]}),(0,i.jsx)(`div`,{className:`flex flex-col gap-6 flex-1 min-h-0 pb-16`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`flex flex-col glass-panel border border-[var(--panel-border)] rounded-3xl overflow-hidden flex-1 min-h-[400px] shadow-2xl bg-background relative`,children:[(0,i.jsx)(`div`,{className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[800px] h-[800px] bg-accent/5 blur-[120px] rounded-full pointer-events-none -z-10`}),Ee(),Oe()]})}),ke()]})}var lm=[`board`,`table`,`calendar`,`drive`],um=[`inline_form`,`popup_form`],dm=e=>typeof e!=`string`||e===``||e===`none`||e===`custom`||![...lm,...um].includes(e),fm=(e,t)=>dm(e)||t&&!pm(e),pm=e=>typeof e==`string`&&lm.includes(e),mm=`/src/your-ai-workflow-firebase-os/microcomponents`,hm=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``),gm=e=>{let t=e.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();return[t,t.replace(/_/g,``)]},_m=e=>{let t=[e?.contentKey,e?.tabName,e?.pageId,e?.pageName].filter(e=>typeof e==`string`&&e.trim()).map(e=>hm(e)).filter(Boolean);return[...new Set(t)].map(e=>`${e}Content.tsx`)},vm=e=>{if(typeof window>`u`)return!1;let t=window.__FBOS_MICROCOMPONENTS__;if(!t)return!1;let n=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`_`).replace(/^_|_$/g,``);return[e?.contentKey,e?.tabName,e?.pageId,e?.pageName].filter(e=>typeof e==`string`&&e.trim()).some(e=>t[n(e)])},ym=new Map,bm=e=>{let t=ym.get(e);return t||(t=import(`${mm}/${e}`).then(e=>typeof e?.default==`function`||typeof e?.default==`object`?e.default:null).catch(()=>null),ym.set(e,t)),t};async function xm(e){if(typeof window>`u`||vm(e))return null;for(let t of _m(e)){let e=await bm(t);if(!e)continue;let[n,r]=gm(t.replace(/Content\.tsx$/,``)),i=window.__FBOS_MICROCOMPONENTS__||{};return window.__FBOS_MICROCOMPONENTS__={[n]:e,[r]:e,...i},e}return null}var Sm=(e,n)=>{let r=n?t.pa(e.pageType):`public`;return{...e,pageType:r,isPrivate:n,isAdmin:r===`admin`,isInternal:r===`internal`,isShared:r===`internal`}};function Cm(){let e=(0,c.useLocation)(),{user:n,userRole:a,loading:s,roleResolved:l,userInactive:u,signOut:d}=t.Qi(),f=t.ka(),p=e=>{if(typeof window<`u`){let t=localStorage.getItem(`fbos_route_${e}`);if(t)try{let e=JSON.parse(t);if(e.form&&!e.formConfigOverride){let t=localStorage.getItem(`fbos_form_${e.form}`);t&&(e.formConfigOverride=JSON.parse(t))}return Sm(e,e.isPrivate===!0)}catch{}}let n=(typeof window<`u`?window.__FBOS_PAGES__:null)||{},r=e.replace(/^\//,``);for(let[t,i]of Object.entries(n)){let n=i.config,a=i.isPublic,o=n.route||`/`+t;if(o===e||t===r)return Sm({...n,route:o,contentKey:n.pageId||t,pageId:t},!a)}return e===`/contact`?{route:`/contact`,template:`popup_form`,form:`contact`,pageId:`contact`,contentKey:`contact`,pageName:`Contact`,formConfigOverride:f.defaultConfigs?.contactForm||t.Na}:e===`/support`?{route:`/support`,template:`popup_form`,form:`support`,pageId:`support`,contentKey:`support`,pageName:`Support`,formConfigOverride:f.defaultConfigs?.supportForm||t.ja}:null},[m,h]=(0,r.useState)(()=>p(e.pathname)),[g,_]=(0,r.useState)(()=>!p(e.pathname));(0,r.useEffect)(()=>{let n=!0,r=p(e.pathname);if(r){h(r),_(!1);let e=r.pageName||r.tabName||r.title;e&&(document.title=e)}return(async()=>{try{let r=e.pathname;r.startsWith(`/`)&&(r=r.substring(1));let[i,a,s,c,l,u]=await Promise.allSettled([(0,o.getDoc)((0,o.doc)(t.Ca,`sys_pages`,r)),(0,o.getDoc)((0,o.doc)(t.Ca,`sys_tabs`,r)),(0,o.getDocs)((0,o.query)((0,o.collection)(t.Ca,`sys_pages`),(0,o.where)(`route`,`==`,e.pathname),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(t.Ca,`sys_pages`),(0,o.where)(`route`,`==`,r),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(t.Ca,`sys_tabs`),(0,o.where)(`route`,`==`,e.pathname),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(t.Ca,`sys_tabs`),(0,o.where)(`route`,`==`,r),(0,o.limit)(1)))]),d=null,p=null,m=(e,t)=>{d||e.status===`fulfilled`&&(e.value.exists&&e.value.exists()?(d=Sm(e.value.data(),t),p=e.value.id):e.value.docs&&e.value.docs.length>0&&(d=Sm(e.value.docs[0].data(),t),p=e.value.docs[0].id))};if(m(i,!1),m(s,!1),m(c,!1),m(a,!0),m(l,!0),m(u,!0),!d){let t=(typeof window<`u`?window.__FBOS_PAGES__:null)||{};for(let[n,i]of Object.entries(t)){let t=i.config,a=i.isPublic,o=t.route||`/`+n;if(o===e.pathname||n===r){d=Sm({...t,route:o,contentKey:t.pageId||n,pageId:n},!a),p=n;break}}}if(d||(e.pathname===`/contact`?(d={route:`/contact`,template:`popup_form`,form:`contact`,pageName:`Contact`},p=`contact`):e.pathname===`/support`&&(d={route:`/support`,template:`popup_form`,form:`support`,pageName:`Support`},p=`support`)),!n)return;if(d){if((p===`contact`||p===`support`)&&!d.form&&(d.form=p),d.contentKey||=d.pageId||p,d.pageId=p,localStorage.setItem(`fbos_route_${e.pathname}`,JSON.stringify(d)),d.form){let e=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},r=n=>f.defaultConfigs?.[n]||f.defaultConfigs?.[`${n}Form`]||e[n]||(n===`contact`?t.Na:n===`support`?t.ja:null);if(localStorage.getItem(`fbos_custom_form_${d.form}`)){try{let e=localStorage.getItem(`fbos_form_${d.form}`);e&&(d.formConfigOverride=JSON.parse(e))}catch{}(0,o.getDoc)((0,o.doc)(t.Ca,`sys_forms`,d.form)).then(async e=>{if(n)if(e.exists()){let t={...e.data(),id:e.id};h(e=>({...e,formConfigOverride:t})),localStorage.setItem(`fbos_form_${d.form}`,JSON.stringify(t))}else{let e=r(d.form);e&&(h(t=>({...t,formConfigOverride:e})),localStorage.setItem(`fbos_form_${d.form}`,JSON.stringify(e)),localStorage.removeItem(`fbos_custom_form_${d.form}`))}})}else{let e=r(d.form);e&&(d.formConfigOverride=e)}}let r=d.pageName||d.tabName||d.title;r&&(document.title=r),h(d),_(!1)}else h(`not-found`),_(!1),localStorage.removeItem(`fbos_route_${e.pathname}`)}catch{n&&g&&(h(`not-found`),_(!1))}})(),()=>{n=!1}},[e.pathname]);let[v,y]=(0,r.useState)(!1),[b,x]=(0,r.useState)(null),[S,C]=(0,r.useState)(!1),w=m&&m!==`not-found`&&typeof m==`object`?[m.contentKey,m.tabName,m.pageId,m.pageName].filter(Boolean).join(`|`):``;if((0,r.useEffect)(()=>{if(x(null),!w||vm(m)){C(!1);return}let e=!1;C(!0),xm(m).then(t=>{e||(t&&x(()=>t),C(!1))});let t=setTimeout(()=>{e||C(!1)},4e3);return()=>{e=!0,clearTimeout(t)}},[w]),(0,r.useEffect)(()=>{let e;return g||s||!l||S?e=setTimeout(()=>y(!0),150):y(!1),()=>clearTimeout(e)},[g,s,l,S]),g||s||!l||S)return v?n?(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(`div`,{className:`mb-6`,children:[(0,i.jsx)(`div`,{className:`h-10 w-56 rounded-xl bg-foreground/5 animate-pulse mt-1`}),(0,i.jsx)(`div`,{className:`h-3 w-24 rounded bg-foreground/5 animate-pulse mt-3`})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsx)(`div`,{className:`flex-1 glass-panel border border-[var(--panel-border)] rounded-3xl flex items-center justify-center min-h-[400px] bg-background shadow-2xl`,children:(0,i.jsx)(t.ei,{className:`w-6 h-6 animate-spin text-accent`})})]})]}):(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center min-h-[40vh] z-10`,children:(0,i.jsxs)(`div`,{className:`p-4 rounded-2xl glass-panel border border-[var(--panel-border)]/40 bg-background/80 shadow-md flex items-center gap-3`,children:[(0,i.jsx)(t.ei,{className:`w-4 h-4 animate-spin text-accent`}),(0,i.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/60 tracking-wide`,children:`Loading page...`})]})}):null;if(m===`not-found`)return(0,i.jsx)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center flex-1 text-center`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 bg-red-500/10 text-red-500 rounded-full flex items-center justify-center mb-6`,children:(0,i.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.5`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`w-8 h-8`,children:[(0,i.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,i.jsx)(`line`,{x1:`12`,y1:`8`,x2:`12`,y2:`12`}),(0,i.jsx)(`line`,{x1:`12`,y1:`16`,x2:`12.01`,y2:`16`})]})}),(0,i.jsx)(`h2`,{className:`text-2xl sm:text-3xl font-bold mb-3 text-foreground`,children:`Page Not Found`}),(0,i.jsx)(`p`,{className:`text-foreground/60 max-w-md`,children:`The route you are looking for does not exist or has been removed.`}),t.la(a)&&(()=>{let t=mf();return(0,i.jsxs)(`div`,{className:`mt-8 w-full max-w-lg text-left flex flex-col gap-4`,children:[(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)] px-5 py-4`,children:[(0,i.jsx)(`p`,{className:`text-[12px] font-extrabold tracking-tight text-gradient mb-1.5`,children:`Pages the app can see`}),(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/70 font-medium leading-relaxed`,children:t.length?t.join(` · `):`None yet. If your assistant says it created a page, the app has not picked its file up.`})]}),(0,i.jsx)(at,{title:`If your assistant just made this page, paste this`,prompt:vf(e.pathname)})]})})()]})});if((m.pageId===`support`||m.isPrivate)&&!n)return(0,i.jsx)(c.Navigate,{to:`/login?from=${encodeURIComponent(e.pathname)}`,replace:!0});if((m.pageId===`support`||m.isPrivate)&&n&&u)return(0,i.jsx)(xn,{tone:`red`,title:`Access Denied`,message:`You don't have access to this app. Please contact the administrator.`,action:(0,i.jsx)(`button`,{onClick:()=>d(),className:Sn,children:`Sign Out`})});if((m.pageId===`support`||m.isPrivate)&&n&&!n.emailVerified)return(0,i.jsx)(c.Navigate,{to:`/verify`,replace:!0});if(m.isPrivate&&!t.oa(a,m))return(0,i.jsx)(Tn,{});let T=f.customRoutes?.[e.pathname]||(m&&m.route?f.customRoutes?.[m.route]:null),E=m.pageName?.toLowerCase().replace(/\s+/g,`_`)||m.pageId||`custom_page`,D=`pub_${E}`,O=m.isPrivate?`${t.ma(m)}${m.pageId||E}`:D,k=f.microcomponents||(typeof window<`u`?window.__FBOS_MICROCOMPONENTS__:void 0),A=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`_`).replace(/^_|_$/g,``),j=[m.contentKey,m.tabName,m.pageId,m.pageName,m.pageName?.replace(/\s+/g,`_`)].filter(Boolean).map(e=>A(e)).reduce((e,t)=>e||k?.[t],void 0),M=T||j||b||void 0,N=m.route||m.pageId||`custom`;return fm(m.template,!!M)?m.isAdmin?(0,i.jsx)(Tf,{config:m,customContent:M},N):m.isInternal?(0,i.jsx)(Ef,{config:m,customContent:M},N):m.isPrivate?(0,i.jsx)(wf,{config:m,customContent:M},N):(0,i.jsx)(yf,{config:m,customContent:M},N):m.template===`board`?(0,i.jsx)(f.components?.TemplateBoard||Af,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Board`,subtitle:m.route,tasksCollection:`${O}_tasks`,categoriesCollection:`${O}_categories`,config:m,customContent:M},N):m.template===`table`?(0,i.jsx)(f.components?.TemplateTable||am,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Table`,subtitle:m.route,tableCollection:`${O}_table`,config:m,customContent:M},N):m.template===`calendar`?(0,i.jsx)(f.components?.TemplateCalendar||cm,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Calendar`,subtitle:m.route,eventsCollection:`${O}_events`,defaultTimeFormat:m.defaultTimeFormat||m.defaulttimeformat||`12h`,config:m,customContent:M},N):m.template===`drive`?(0,i.jsx)(f.components?.TemplateDrive||qt,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Drive`,subtitle:m.route,filesCollection:`${O}_files`,config:m,customContent:M},N):m.template===`inline_form`?(0,i.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-start mt-8 relative z-10 w-full min-h-[60vh]`,children:(0,i.jsx)(t.t,{isInline:!0,formId:m.form,formConfig:m.formConfigOverride})}):(0,i.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-center relative z-10 w-full min-h-[60vh]`,children:(0,i.jsx)(t.t,{formId:m.form,formConfig:m.formConfigOverride,onClose:()=>window.history.back()})})}var wm=e=>e.error?`error`:e.paid?`paid`:`unpaid`,Tm={checking:{icon:t.Ti,tint:`text-accent`,title:`Checking your payment…`},paid:{icon:t.ki,tint:`text-emerald-400`,title:`Thank you — payment received`},unpaid:{icon:t.Ti,tint:`text-amber-400`,title:`Not confirmed yet`},error:{icon:t.Ai,tint:`text-red-400`,title:`We could not confirm this payment`},cancelled:{icon:t.Di,tint:`text-foreground/50`,title:`Payment cancelled`}};function Em({cancelled:e=!1}){let[n]=(0,c.useSearchParams)(),a=n.get(`session_id`)||``,[o,s]=(0,r.useState)(`checking`),[l,u]=(0,r.useState)(null);(0,r.useEffect)(()=>{if(e)return;let t=!1;return K(a).then(e=>{t||(u(e),s(wm(e)))}),()=>{t=!0}},[e,a]);let d=async()=>{s(`checking`);let e=await K(a);u(e),s(wm(e))},f=Tm[e?`cancelled`:o],p=f.icon;return(0,i.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mb-16`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.5},className:`w-full max-w-[480px] p-6 md:p-8 lg:p-10 rounded-3xl glass-panel relative glow-hover text-center shadow-[0_8px_32px_rgba(0,0,0,0.08)]`,children:[(0,i.jsx)(`div`,{className:`absolute -inset-[1px] bg-gradient-to-br from-[var(--primary-glow)] to-transparent opacity-30 blur-[20px] rounded-3xl -z-10`}),(0,i.jsx)(`div`,{className:`w-14 h-14 md:w-16 md:h-16 rounded-2xl glass-panel border border-[var(--panel-border)] flex items-center justify-center mx-auto mb-5 md:mb-6 shadow-xl`,children:(0,i.jsx)(p,{className:`w-7 h-7 md:w-8 md:h-8 ${f.tint} ${!e&&o===`checking`?`animate-pulse`:``}`})}),(0,i.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold mb-3 text-foreground tracking-tight`,children:f.title}),(0,i.jsxs)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/60 mb-6 md:mb-8 leading-[1.6] tracking-wide`,children:[e&&(0,i.jsx)(`p`,{children:`Nothing was charged. You can try again whenever you like.`}),!e&&o===`checking`&&(0,i.jsx)(`p`,{children:`One moment — confirming with the payment provider.`}),!e&&o===`paid`&&(0,i.jsxs)(`p`,{children:[l?.amountTotal!=null&&l?.currency?`Your payment of ${l.amountTotal} ${l.currency.toUpperCase()} went through.`:`Your payment went through.`,l?.customerEmail?` A receipt is on its way to ${l.customerEmail}.`:``]}),!e&&o===`unpaid`&&(0,i.jsx)(`p`,{children:`The payment provider has not confirmed this payment yet. Some payment methods take a minute — check again shortly, and look for a receipt in your email.`}),!e&&o===`error`&&(0,i.jsxs)(`p`,{children:[l?.error,` If you completed the payment, check your email for a receipt — if one arrived, your payment went through and you can safely close this page.`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 max-w-[360px] mx-auto`,children:[!e&&(o===`unpaid`||o===`error`)&&(0,i.jsx)(t.cr,{variant:`primary`,onClick:d,className:`w-full py-2.5 md:py-3 text-[14px] font-bold tracking-wide rounded-xl`,children:`Check again`}),(0,i.jsx)(c.Link,{to:`/`,className:`w-full block py-2.5 md:py-3 bg-foreground/5 hover:bg-foreground/10 text-foreground text-[14px] font-bold rounded-xl transition-colors`,children:`Back to the site`})]})]})})}function Dm({children:e,className:n,variant:a=`secondary`}){let{loading:o,configured:s}=X(),[c,l]=(0,r.useState)(!1),[u,d]=(0,r.useState)(null);return o||!s?null:(0,i.jsxs)(`span`,{className:`inline-flex flex-col items-stretch gap-2`,children:[(0,i.jsx)(t.cr,{variant:a,className:n,onClick:async()=>{if(c)return;l(!0),d(null);let e=await ee();e&&(d(e),l(!1))},disabled:c,children:c?`Opening…`:e??`Manage plan`}),u&&(0,i.jsx)(`span`,{role:`alert`,className:`text-[13px] font-semibold text-red-400 leading-snug`,children:u})]})}function Om(e){return e.status===`past_due`?{label:`Past due`,tone:`bad`}:e.active?{label:`Active`,tone:`good`}:{label:`Cancelled`,tone:`quiet`}}function km(e){if(!e.currentPeriodEnd||!e.active)return``;let t=new Date(e.currentPeriodEnd*1e3).toLocaleDateString(void 0,{day:`numeric`,month:`short`,year:`numeric`});return e.cancelAtPeriodEnd?`Ends on ${t}`:`Renews on ${t}`}function Am({payment:e}){let n=Jl({kind:`charge`,email:null,name:null,...e});return(0,i.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${t.X}`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.description||`One-off payment`}),(0,i.jsx)(`span`,{className:`text-[11px] text-foreground/45 font-medium truncate`,children:Zl(e.created)})]}),(0,i.jsx)(`span`,{className:`text-[12.5px] font-semibold text-foreground/70 whitespace-nowrap shrink-0`,children:Yl(e.amount,e.currency)}),(0,i.jsx)(Ql,{label:n.label,tone:n.tone})]})}function jm({sub:e}){let n=Om(e),r=km(e);return(0,i.jsxs)(`div`,{className:`flex flex-col gap-3 px-3.5 py-3 ${t.X}`,children:[(0,i.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,i.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,i.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.productName||`Subscription`}),(0,i.jsxs)(`span`,{className:`text-[11px] text-foreground/45 font-medium truncate`,children:[Yl(e.amount,e.currency),e.interval?` / ${e.interval}`:``,r?` — ${r}`:``]})]}),(0,i.jsx)(Ql,{label:n.label,tone:n.tone})]}),(0,i.jsx)(Dm,{className:`self-start`})]})}function Mm(){let{user:e}=t.Qi(),{loading:n,subscriptions:r,payments:a,error:o}=te(),s=!n&&!o&&r.length===0&&a.length===0;return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(we,{children:`Billing`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/billing`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsx)(`div`,{className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-5 md:p-8 shadow-2xl relative bg-background flex flex-col min-h-[400px]`,children:n?(0,i.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,i.jsx)(t.ei,{className:`w-6 h-6 animate-spin text-accent`})}):o?(0,i.jsx)(`p`,{className:`text-[12.5px] font-medium leading-relaxed px-1 text-red-500`,children:o}):s?(0,i.jsx)(t.at,{icon:t.Br,title:`Nothing here yet`,description:`No payments have been made on this account.`,collapsible:!1,children:(0,i.jsxs)(`p`,{className:`text-[12.5px] font-medium leading-relaxed px-1 text-foreground/50`,children:[`Nothing has been bought on this account’s email`,e?.email?(0,i.jsxs)(i.Fragment,{children:[` (`,(0,i.jsx)(`strong`,{children:e.email}),`)`]}):null,`. A payment made with a different email address at checkout lives with that email — sign in with the address you paid with to see it here.`]})}):(0,i.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[r.length>0&&(0,i.jsx)(t.at,{icon:t.xi,title:r.length===1?`Your subscription`:`Your subscriptions`,description:`Manage plan opens Stripe's own portal — cancel, switch, card, invoices.`,collapsible:!1,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:r.map(e=>(0,i.jsx)(jm,{sub:e},e.id))})}),a.length>0&&(0,i.jsx)(t.at,{icon:t.Br,title:`Your payments`,description:`Every payment on this account, straight from Stripe.`,collapsible:!1,children:(0,i.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:a.map(e=>(0,i.jsx)(Am,{payment:e},e.id))})})]})})]})]})}var Nm=`text-accent underline underline-offset-2 font-semibold hover:text-accent-deep transition-colors`,Pm=`space-y-2 list-decimal list-inside text-foreground/75 marker:font-bold marker:text-foreground/40`;function Fm({href:e,children:t}){return(0,i.jsx)(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,className:Nm,children:t})}function Im({children:e}){return(0,i.jsx)(`h4`,{className:`text-[12px] font-extrabold uppercase tracking-[0.14em] text-foreground/40 pt-1`,children:e})}function Lm({number:e,title:n,done:r,open:a,onToggle:o,children:s}){let c=(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(`span`,{className:`w-8 h-8 shrink-0 rounded-full flex items-center justify-center text-[13.5px] font-extrabold border ${r?`bg-emerald-500/10 border-emerald-500/20 text-emerald-500`:`bg-accent/10 border-accent/20 text-accent`}`,children:r?(0,i.jsx)(t.Fi,{className:`w-4 h-4`}):e}),(0,i.jsx)(`span`,{className:`flex-1 min-w-0 text-[14.5px] sm:text-[15px] font-bold text-foreground tracking-tight truncate`,children:n}),o&&(0,i.jsx)(t.Pi,{className:`w-4 h-4 shrink-0 text-foreground/40 transition-transform duration-200 ${a?`rotate-180`:``}`})]});return(0,i.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 bg-foreground/[0.015] overflow-hidden transition-all`,children:[o?(0,i.jsx)(`button`,{type:`button`,onClick:o,"aria-expanded":a,className:`w-full px-4 sm:px-5 py-4 flex items-center gap-3 sm:gap-3.5 text-left cursor-pointer hover:bg-foreground/[0.02] transition-colors`,children:c}):(0,i.jsx)(`div`,{className:`w-full px-4 sm:px-5 py-4 flex items-center gap-3 sm:gap-3.5`,children:c}),(0,i.jsx)(t.pr,{initial:!1,children:a&&(0,i.jsx)(t.fr.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},className:`overflow-hidden`,children:(0,i.jsx)(`div`,{className:`border-t border-[var(--panel-border)]/40 p-4 sm:p-5 flex flex-col gap-4 bg-background/30 text-[13.5px] sm:text-[14px] text-foreground/70 leading-relaxed`,children:s})})})]})}function Rm({label:e,onDone:n,waitingFor:r}){return(0,i.jsxs)(`div`,{className:`flex flex-col gap-2 pt-1`,children:[(0,i.jsxs)(t.fr.button,{type:`button`,whileHover:r?void 0:{scale:1.01},whileTap:r?void 0:{scale:.99},onClick:n,disabled:!!r,className:`btn-primary inline-flex items-center justify-center gap-2 h-11 px-5 rounded-[var(--btn-radius,0.75rem)] text-[13px] font-bold text-white self-start max-sm:self-stretch shadow-lg ${r?`opacity-40 cursor-not-allowed`:`cursor-pointer`}`,children:[(0,i.jsx)(t.Fi,{className:`w-4 h-4`}),e]}),r&&(0,i.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:r})]})}function zm({label:e,hint:n,placeholder:a,invalid:o,value:s,clean:c,preview:l,onSave:u}){let[d,f]=(0,r.useState)(s),[p,m]=(0,r.useState)(!1),[h,g]=(0,r.useState)(``),_=c(d),v=d.trim().length>0,y=_!==s;return(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsx)(t.ft,{label:e,hint:n,value:d,onChange:e=>{f(e),g(``)},placeholder:a,error:h,action:(0,i.jsxs)(`div`,{className:`flex items-center gap-2`,children:[s&&!y&&(0,i.jsx)(t.lt,{state:`saved`,label:`Saved`}),(0,i.jsx)(t.Q,{icon:t.Fi,onClick:async()=>{if(!_){g(o);return}m(!0);let e=await u(_);m(!1),g(e||``),e||f(_)},busy:p,disabled:!v||!y&&!!s,children:`Save`})]})}),_&&!h&&(0,i.jsx)(`div`,{className:`px-3.5 py-2.5 rounded-xl border border-[var(--panel-border)]/60 bg-background`,children:(0,i.jsx)(`span`,{className:`text-[12.5px] font-mono text-foreground/60 truncate block`,children:l(_)})})]})}function Bm({label:e,url:t}){return(0,i.jsxs)(`div`,{className:`flex max-sm:flex-col sm:items-center justify-between gap-2 sm:gap-3 px-3.5 py-3 rounded-xl border border-[var(--panel-border)]/60 bg-background`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex flex-col gap-0.5`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-[0.14em] text-foreground/40`,children:e}),(0,i.jsx)(`span`,{className:`text-[12.5px] font-mono text-foreground/70 truncate`,children:t})]}),(0,i.jsx)(Bc,{compact:!0,code:t,label:`Copy`})]})}var Vm=[`216.239.32.21`,`216.239.34.21`,`216.239.36.21`,`216.239.38.21`];function Hm(){let{loading:e,record:n,save:a}=wl(),[o,s]=(0,r.useState)(null),{status:l}=cl(),u=xl(n.done,o),d=e=>u[pl.indexOf(e)],f=_l(n.appName),p=yl(n.domain),m=n.done.length===pl.length,h=m&&Cl(l),g=e=>{s(null),a({done:Sl(n.done,e)})},_=e=>e.open?e.done?()=>s(null):void 0:()=>s(e.done?e.id:null),v=e=>{let t=d(e);return{done:t.done,open:t.open,onToggle:_(t)}};return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,i.jsx)(we,{children:`Publish App`}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/publish`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,i.jsx)(Ie,{}),(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{delay:.1},className:`glass-panel border border-[var(--panel-border)] rounded-3xl p-4 sm:p-6 md:p-8 shadow-2xl relative bg-background flex flex-col`,children:[(0,i.jsx)(`div`,{className:`mb-6 pb-4 sm:mb-8 sm:pb-6 border-b border-[var(--panel-border)]/50`,children:(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 sm:gap-4`,children:[(0,i.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,i.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-extrabold text-foreground tracking-tight truncate`,children:`Putting your app in front of people`}),(0,i.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1 sm:mt-1.5 leading-snug truncate`,children:[(0,i.jsx)(`span`,{className:`sm:hidden`,children:`One step at a time. Stuck? Message me.`}),(0,i.jsx)(`span`,{className:`max-sm:hidden`,children:`One step at a time — the next one appears as you tick each off. Stuck anywhere? Message me.`})]})]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,i.jsx)(t.fr.a,{whileHover:{scale:1.05},whileTap:{scale:.95},href:`mailto:antonina@youraiworkflow.co`,title:`Email Support`,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer btn-secondary`,children:(0,i.jsx)(t.Xr,{className:`w-4 h-4`})}),(0,i.jsx)(t.fr.a,{whileHover:{scale:1.05},whileTap:{scale:.95},href:`https://wa.me/34632407883`,target:`_blank`,rel:`noopener noreferrer`,title:`WhatsApp Support`,className:`w-10 h-10 flex items-center justify-center rounded-xl transition-all duration-300 cursor-pointer btn-secondary`,children:(0,i.jsx)(Sc,{className:`w-4 h-4 text-foreground/80`})})]})]})}),!e&&(0,i.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,i.jsxs)(Lm,{number:1,title:`Publish in AI Studio`,...v(`published`),children:[(0,i.jsxs)(`ol`,{className:Pm,children:[(0,i.jsxs)(`li`,{children:[`In `,(0,i.jsx)(Fm,{href:`https://aistudio.google.com`,children:`Google AI Studio`}),`, click`,` `,(0,i.jsx)(`strong`,{children:`Publish`}),` in the top left corner, then `,(0,i.jsx)(`strong`,{children:`Get started`}),`.`]}),(0,i.jsxs)(`li`,{children:[`It asks for an app URL. Type a name for your app —`,` `,(0,i.jsx)(`span`,{className:`text-accent`,children:`my-ai-project`}),` — and copy it, you need it again at the bottom of this step.`]}),(0,i.jsxs)(`li`,{children:[`Follow the rest of AI Studio's instructions, then click `,(0,i.jsx)(`strong`,{children:`Publish your app`}),`.`]})]}),(0,i.jsxs)(`p`,{children:[`If it says `,(0,i.jsx)(`strong`,{children:`Failed to publish app`}),`, reload the page, unpublish, and publish again. It usually goes through the second time.`]}),(0,i.jsx)(zm,{label:`Your app name`,hint:`The name you just typed into AI Studio. Saving only keeps it for step 3 — nothing changes in AI Studio, it just says Saved. Pasting the whole address is fine; only the name is kept.`,placeholder:`my-ai-project`,invalid:`That does not look like an app name — letters, numbers and dashes.`,value:n.appName,clean:gl,preview:_l,onSave:e=>a({appName:e})}),(0,i.jsx)(Rm,{label:`My app is published`,onDone:()=>g(`published`),waitingFor:n.appName?void 0:`Save your app name first — step 3 asks for this address.`})]}),d(`connected`).visible&&(0,i.jsxs)(Lm,{number:2,title:`Connect your website domain`,...v(`connected`),children:[(0,i.jsxs)(`p`,{children:[`Your app is live at `,(0,i.jsx)(`span`,{className:`font-mono text-foreground/80`,children:f||`your AI Studio address`}),` `,`already. This step puts it on a domain of your own.`]}),(0,i.jsx)(Im,{children:`Start the mapping`}),(0,i.jsxs)(`ol`,{className:Pm,children:[(0,i.jsxs)(`li`,{children:[`Back where you published, click `,(0,i.jsx)(`strong`,{children:`Advanced settings`}),`. It takes you to Google Cloud Run.`]}),(0,i.jsxs)(`li`,{children:[`In the menu on the left, open `,(0,i.jsx)(`strong`,{children:`Domain mappings`}),`, then`,` `,(0,i.jsx)(`strong`,{children:`Add mapping`}),` at the top.`]}),(0,i.jsxs)(`li`,{children:[`Choose your service, then under `,(0,i.jsx)(`strong`,{children:`Select a verified domain`}),` click`,` `,(0,i.jsx)(`strong`,{children:`Verify new domain`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Type your domain — `,(0,i.jsx)(`span`,{className:`text-accent`,children:`myaiproject.com`}),` — and click`,` `,(0,i.jsx)(`strong`,{children:`Continue`}),`, then `,(0,i.jsx)(`strong`,{children:`Verify in Search Console`}),`.`]})]}),(0,i.jsx)(Im,{children:`Prove the domain is yours`}),(0,i.jsxs)(`ol`,{className:Pm,children:[(0,i.jsxs)(`li`,{children:[`Google Search Console opens. Click `,(0,i.jsx)(`strong`,{children:`Add a website`}),`, type the same domain, and click `,(0,i.jsx)(`strong`,{children:`Continue`}),`.`]}),(0,i.jsxs)(`li`,{children:[`On the next screen, under `,(0,i.jsxs)(`em`,{children:[`Copy the TXT record below into the DNS configuration for `,vl(n.domain)||`myaiproject.com`]}),`, copy the`,` `,(0,i.jsx)(`strong`,{children:`TXT record`}),` — a long line starting`,` `,(0,i.jsx)(`span`,{className:`font-mono text-foreground/80`,children:`google-site-verification=`})]}),(0,i.jsxs)(`li`,{children:[`Open your domain registrar in another tab — GoDaddy, Namecheap, whoever you bought the domain from — go to its `,(0,i.jsx)(`strong`,{children:`DNS settings`}),`, and click`,` `,(0,i.jsx)(`strong`,{children:`Add record`}),`. Choose `,(0,i.jsx)(`strong`,{children:`TXT`}),`, paste the line into`,` `,(0,i.jsx)(`strong`,{children:`Value`}),`, and put `,(0,i.jsx)(`span`,{className:`font-mono text-foreground/80`,children:`@`}),` `,`in `,(0,i.jsx)(`strong`,{children:`Host`}),` or `,(0,i.jsx)(`strong`,{children:`Name`}),`. Save it.`]}),(0,i.jsxs)(`li`,{children:[`Back in Search Console, click `,(0,i.jsx)(`strong`,{children:`Verify`}),`.`]}),(0,i.jsxs)(`li`,{children:[`Once it is verified you are done with Search Console — close that tab. Go back to the Google Cloud Run tab (`,(0,i.jsx)(`span`,{className:`font-mono text-foreground/80`,children:`console.cloud.google.com`}),`) where you clicked to verify, and press its `,(0,i.jsx)(`strong`,{children:`refresh`}),` button. It should say `,(0,i.jsxs)(`em`,{children:[`Your ownership of `,vl(n.domain)||`myaiproject.com`,` has been successfully verified. You can now map this domain to your Cloud Run services.`]})]})]}),(0,i.jsx)(Im,{children:`Point the domain at your app`}),(0,i.jsxs)(`ol`,{className:Pm,children:[(0,i.jsxs)(`li`,{children:[`Add a subdomain if you want one, then click `,(0,i.jsx)(`strong`,{children:`Continue`}),`. Cloud Run now shows you the records to add.`]}),(0,i.jsxs)(`li`,{children:[`Back at your registrar, add each one as an `,(0,i.jsx)(`strong`,{children:`A record`}),`, the same way you added the TXT. It is normally these four:`]})]}),(0,i.jsxs)(`div`,{className:`rounded-xl border border-[var(--panel-border)]/60 bg-background overflow-hidden`,children:[(0,i.jsxs)(`div`,{className:`flex items-center justify-between gap-3 px-3.5 py-2.5 border-b border-[var(--panel-border)]/40`,children:[(0,i.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-[0.14em] text-foreground/40`,children:`A records`}),(0,i.jsx)(Bc,{compact:!0,code:Vm.join(`
|
|
685
|
+
`),label:`Copy all four`})]}),(0,i.jsx)(`div`,{className:`px-3.5 py-2.5 flex flex-col gap-1`,children:Vm.map(e=>(0,i.jsx)(`span`,{className:`text-[12.5px] font-mono text-foreground/70`,children:e},e))})]}),(0,i.jsx)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:`Use whatever your own Cloud Run screen shows if it differs from these — that screen is always right.`}),(0,i.jsxs)(`p`,{children:[`Once they are all in, press `,(0,i.jsx)(`strong`,{children:`Done`}),` in Cloud Run and wait — this can take an hour or more. Check every few minutes by typing your domain into any browser, like `,(0,i.jsx)(`span`,{className:`text-accent`,children:`myaiproject.com`}),`: when your published app comes up, it is connected.`]}),(0,i.jsx)(zm,{label:`Your domain`,hint:`However you have it — with or without https:// and www. Only the domain itself is kept, for step 3.`,placeholder:`myaiproject.com`,invalid:`That does not look like a domain — something like myaiproject.com.`,value:n.domain,clean:vl,preview:yl,onSave:e=>a({domain:e})}),(0,i.jsx)(Rm,{label:`My domain is verified and my app is connected`,onDone:()=>g(`connected`),waitingFor:n.domain?void 0:`Save your domain first — step 3 asks for this address.`})]}),d(`authorised`).visible&&(0,i.jsxs)(Lm,{number:3,title:`Add your domains and email sender`,...v(`authorised`),children:[(0,i.jsxs)(`p`,{children:[`Once your domain answers, head back to the`,` `,(0,i.jsx)(Fm,{href:`https://console.firebase.google.com`,children:`Firebase console`}),`. Two jobs, both under `,(0,i.jsx)(`strong`,{children:`Security → Authentication`}),`.`]}),(0,i.jsx)(Im,{children:`Authorise both addresses`}),(0,i.jsxs)(`p`,{children:[`Nobody can sign in from an address Firebase does not know. Open`,` `,(0,i.jsx)(`strong`,{children:`Security → Authentication → Settings → Authorised domains`}),`, click`,` `,(0,i.jsx)(`strong`,{children:`Add domain`}),`, and paste these in one at a time — both need to be there.`]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,i.jsx)(Bm,{label:`Your AI Studio address`,url:f?`${gl(n.appName)}.ai.studio`:`—`}),(0,i.jsx)(Bm,{label:`Your own domain`,url:vl(n.domain)||`—`})]}),(0,i.jsx)(Im,{children:`Send email from your own domain`}),(0,i.jsxs)(`ol`,{className:Pm,children:[(0,i.jsxs)(`li`,{children:[`On the same Authentication page, open the `,(0,i.jsx)(`strong`,{children:`Templates`}),` tab. Every email Firebase sends for you lives here — password changes, email verification. You can reword them, but the one thing worth doing is the sender.`]}),(0,i.jsxs)(`li`,{children:[`Click the pencil beside `,(0,i.jsx)(`strong`,{children:`From`}),`. It will be something like`,` `,(0,i.jsx)(`span`,{className:`font-mono text-foreground/80`,children:`noreply@your-project.firebaseapp.com`})]}),(0,i.jsxs)(`li`,{children:[`On the right, click `,(0,i.jsx)(`strong`,{children:`Customise domain`}),`, enter your own domain, and follow the steps it gives you — more records at your registrar, same as before.`]})]}),(0,i.jsx)(`p`,{children:`This is what keeps your emails out of people's spam folders, and it is why they arrive looking like they came from you.`}),(0,i.jsx)(Rm,{label:`I've added my domains and verified my email domain`,onDone:()=>g(`authorised`)})]}),h&&(0,i.jsxs)(Lm,{number:4,title:`Finalise your Stripe live setup`,done:!1,open:!0,children:[(0,i.jsx)(`p`,{children:`Your payments are not live yet — still on practice cards, or live without the webhook that sends receipts. Finish Go live on the Payments screen and your setup is complete.`}),(0,i.jsxs)(`p`,{children:[`Switch `,(0,i.jsx)(`strong`,{children:`Go live`}),` on and follow its steps. Its webhook step was waiting for your published address, and it is open now that step 3 is ticked.`]}),(0,i.jsxs)(c.Link,{to:`/payments`,className:`btn-primary inline-flex items-center justify-center gap-2 h-11 px-5 rounded-[var(--btn-radius,0.75rem)] text-[13px] font-bold text-white self-start max-sm:self-stretch shadow-lg cursor-pointer`,children:[(0,i.jsx)(t.xi,{className:`w-4 h-4`}),`Take me to Go live`]})]}),m&&!h&&(0,i.jsxs)(`div`,{className:`mt-3 flex max-sm:flex-col sm:items-center gap-4 sm:gap-6 p-5 sm:p-6 rounded-2xl border border-emerald-500/20 bg-emerald-500/[0.06]`,children:[(0,i.jsx)(`div`,{className:`w-10 h-10 shrink-0 rounded-2xl flex items-center justify-center border border-emerald-500/20 bg-emerald-500/10 text-emerald-500`,children:(0,i.jsx)(t.Rr,{className:`w-5 h-5`})}),(0,i.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,i.jsx)(`h3`,{className:`text-[15px] font-extrabold text-foreground tracking-tight`,children:`Your app is live`}),(0,i.jsxs)(`p`,{className:`text-[13px] text-foreground/60 font-medium leading-relaxed mt-1`,children:[p?(0,i.jsxs)(i.Fragment,{children:[`Anyone can open `,(0,i.jsx)(Fm,{href:p,children:vl(n.domain)}),` and sign up.`]}):(0,i.jsx)(i.Fragment,{children:`Anyone can open your app and sign up.`}),` `,`Any step above opens again if you need to check what you typed.`]})]})]})]})]})]})]})}var Um={contentKey:`dashboard`};function Wm(){let{user:e}=t.Qi(),n=t.ka(),[a,o]=(0,r.useState)(null),[s,c]=(0,r.useState)(()=>typeof window<`u`&&!vm(Um));(0,r.useEffect)(()=>{if(vm(Um))return;let e=!1;xm(Um).then(t=>{e||(t&&o(()=>t),c(!1))});let t=setTimeout(()=>{e||c(!1)},4e3);return()=>{e=!0,clearTimeout(t)}},[]);let l=n.microcomponents?.dashboard||(typeof window<`u`?window.__FBOS_MICROCOMPONENTS__?.dashboard:void 0)||a||void 0,u=(e?.displayName||e?.email?.split(`@`)[0]||`there`).split(` `)[0],d=u.charAt(0).toUpperCase()+u.slice(1);return(0,i.jsxs)(`main`,{className:`flex-1 w-full max-w-7xl mx-auto p-4 pt-2 md:p-8 md:pt-4 z-10 flex flex-col min-h-screen`,children:[(0,i.jsxs)(t.fr.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-8`,children:[(0,i.jsxs)(we,{children:[`Welcome back, `,d,`.`]}),(0,i.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,i.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/dashboard`]})]}),(0,i.jsxs)(`div`,{className:`flex flex-col gap-4 flex-1 min-h-[500px]`,children:[(0,i.jsx)(`div`,{className:`flex justify-start`,children:(0,i.jsx)(Ie,{})}),(0,i.jsxs)(`div`,{className:`w-full flex-1 glass-panel rounded-3xl relative overflow-hidden border border-[var(--panel-border)] shadow-2xl bg-[var(--panel-bg)] ${l?`p-6 md:p-8`:`p-8 md:p-12 flex items-center justify-center`}`,children:[(0,i.jsx)(`div`,{className:`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-64 h-64 bg-accent/10 blur-[100px] rounded-full pointer-events-none`}),l?(0,i.jsx)(`div`,{className:`fbos-content-slot relative z-10`,children:(0,i.jsx)(l,{})}):s?(0,i.jsx)(t.ei,{className:`w-6 h-6 text-accent animate-spin relative z-10`}):(0,i.jsx)(t.pr,{mode:`wait`,children:(0,i.jsxs)(t.fr.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.95},transition:{duration:.3},className:`text-center z-10`,children:[(0,i.jsx)(`div`,{className:`w-16 h-16 rounded-3xl bg-accent/10 border border-accent/20 flex items-center justify-center text-accent mx-auto mb-6 shadow-inner`,children:(0,i.jsx)(t.bi,{className:`w-6 h-6`})}),(0,i.jsx)(`h2`,{className:`text-2xl font-extrabold text-foreground mb-2`,children:`No data added here yet`}),(0,i.jsx)(`p`,{className:`text-foreground/40 font-medium`,children:`Keep moving forward, your data will appear here.`})]})})]})]})]})}var Gm=()=>(0,i.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center min-h-[60vh] z-10 animate-in fade-in duration-500`,children:[(0,i.jsx)(`div`,{className:`w-12 h-12 rounded-xl glass-panel border border-[var(--panel-border)] flex items-center justify-center mb-6 shadow-xl`,children:(0,i.jsx)(t.bi,{className:`w-6 h-6 text-accent animate-pulse`})}),(0,i.jsxs)(`div`,{className:`flex items-center gap-3 glass-panel px-5 py-2.5 rounded-full border border-[var(--panel-border)]`,children:[(0,i.jsx)(`div`,{className:`w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin`}),(0,i.jsx)(`span`,{className:`text-[13px] font-bold tracking-widest uppercase text-foreground/70`,children:`Connecting`})]})]});function Km({level:e,children:n}){let{user:r,userRole:a,loading:o,userInactive:s,signOut:l,roleResolved:u}=t.Qi(),d=(0,c.useLocation)();return o||!u?(0,i.jsx)(Gm,{}):r?s?(0,i.jsx)(xn,{tone:`red`,title:`Access Denied`,message:`You don't have access to this app. Please contact the administrator.`,action:(0,i.jsx)(`button`,{onClick:()=>l(),className:Sn,children:`Sign Out`})}):r.emailVerified?e===`admin`&&!t.la(a)?(0,i.jsx)(Dn,{}):e===`internal`&&!t.ca(a)?(0,i.jsx)(En,{}):(0,i.jsx)(i.Fragment,{children:n}):(0,i.jsx)(c.Navigate,{to:`/verify`}):(0,i.jsx)(c.Navigate,{to:`/login?from=${encodeURIComponent(d.pathname)}`,replace:!0})}var qm=({children:e})=>(0,i.jsx)(Km,{level:`signed-in`,children:e}),Jm=({children:e})=>(0,i.jsx)(Km,{level:`admin`,children:e}),Ym=({children:e})=>(0,i.jsx)(Km,{level:`internal`,children:e});function Xm({children:e}){let{user:n,loading:r,roleResolved:a}=t.Qi(),[o]=(0,c.useSearchParams)();return r||!a?(0,i.jsx)(Gm,{}):n&&n.emailVerified?(0,i.jsx)(c.Navigate,{to:o.get(`from`)||`/dashboard`,replace:!0}):(0,i.jsx)(i.Fragment,{children:e})}function Zm({children:e}){let{user:n,loading:r,roleResolved:a}=t.Qi();return r||!a?(0,i.jsx)(Gm,{}):n?n.emailVerified?(0,i.jsx)(c.Navigate,{to:`/dashboard`}):(0,i.jsx)(i.Fragment,{children:e}):(0,i.jsx)(c.Navigate,{to:`/`})}function Qm({to:e}){return(0,i.jsx)(c.Navigate,{to:`${e}${(0,c.useLocation)().search}`,replace:!0})}function $m(){return(0,i.jsxs)(`div`,{className:`fixed top-0 left-0 w-full h-full pointer-events-none -z-0 overflow-hidden`,children:[(0,i.jsx)(t.fr.div,{animate:{scale:[1,1.1,1],opacity:[.6,1,.6]},transition:{duration:12,repeat:1/0,ease:`easeInOut`},className:`absolute -top-[30%] md:-top-[400px] -right-[10%] md:-right-[200px] w-[500px] md:w-[800px] h-[500px] md:h-[800px] rounded-full bg-decorator-1 blur-[80px] md:blur-[120px]`}),(0,i.jsx)(t.fr.div,{animate:{scale:[1,1.2,1],opacity:[.5,.9,.5]},transition:{duration:18,repeat:1/0,ease:`easeInOut`,delay:2},className:`absolute -bottom-[20%] md:-bottom-[300px] -left-[10%] md:-left-[100px] w-[400px] md:w-[600px] h-[400px] md:h-[600px] rounded-full bg-decorator-2 blur-[60px] md:blur-[100px]`})]})}function eh(){let e=t.ka().components?.Home||ce,n=(0,c.useNavigate)();return(0,i.jsx)(t.Zi,{onSignedOut:()=>n(`/`,{replace:!0}),children:(0,i.jsxs)(`div`,{className:`min-h-screen relative flex flex-col overflow-x-hidden`,children:[(0,i.jsx)(se,{}),(0,i.jsxs)(c.Routes,{children:[(0,i.jsx)(c.Route,{path:`/`,element:(0,i.jsx)(Xm,{children:(0,i.jsx)(`div`,{className:`fbos-home-slot contents`,children:(0,i.jsx)(e,{})})})}),(0,i.jsx)(c.Route,{path:`/register`,element:(0,i.jsx)(Xm,{children:(0,i.jsx)(ye,{})})}),(0,i.jsx)(c.Route,{path:`/login`,element:(0,i.jsx)(Xm,{children:(0,i.jsx)(be,{})})}),(0,i.jsx)(c.Route,{path:`/reset-password`,element:(0,i.jsx)(Xm,{children:(0,i.jsx)(Re,{})})}),(0,i.jsx)(c.Route,{path:`/verify`,element:(0,i.jsx)(Zm,{children:(0,i.jsx)(xe,{})})}),(0,i.jsx)(c.Route,{path:`/book/:id`,element:(0,i.jsx)(Hd,{})}),(0,i.jsx)(c.Route,{path:`/meet/:id`,element:(0,i.jsx)(Zd,{})}),(0,i.jsx)(c.Route,{path:`/pay/:id`,element:(0,i.jsx)($d,{})}),(0,i.jsx)(c.Route,{path:`/payment-complete`,element:(0,i.jsx)(Em,{})}),(0,i.jsx)(c.Route,{path:`/payment-cancelled`,element:(0,i.jsx)(Em,{cancelled:!0})}),(0,i.jsx)(c.Route,{path:`/guide`,element:(0,i.jsx)(c.Navigate,{to:`/`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/templates`,element:(0,i.jsx)(c.Navigate,{to:`/`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/users`,element:(0,i.jsx)(Jm,{children:(0,i.jsx)(Ot,{})})}),(0,i.jsx)(c.Route,{path:`/users/:id`,element:(0,i.jsx)(Jm,{children:(0,i.jsx)(Ot,{})})}),(0,i.jsx)(c.Route,{path:`/inbox`,element:(0,i.jsx)(Jm,{children:(0,i.jsx)(Ut,{})})}),(0,i.jsx)(c.Route,{path:`/payments`,element:(0,i.jsx)(Jm,{children:(0,i.jsx)($l,{})})}),(0,i.jsx)(c.Route,{path:`/schedule`,element:(0,i.jsx)(Ym,{children:(0,i.jsx)(wd,{})})}),(0,i.jsx)(c.Route,{path:`/my-calendar`,element:(0,i.jsx)(Qm,{to:`/schedule`})}),(0,i.jsx)(c.Route,{path:`/my-bookings`,element:(0,i.jsx)(qm,{children:(0,i.jsx)(Td,{})})}),(0,i.jsx)(c.Route,{path:`/email`,element:(0,i.jsx)(Jm,{children:(0,i.jsx)(ff,{})})}),(0,i.jsx)(c.Route,{path:`/submissions`,element:(0,i.jsx)(c.Navigate,{to:`/inbox`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/requests`,element:(0,i.jsx)(c.Navigate,{to:`/inbox`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/assets`,element:(0,i.jsx)(Jm,{children:(0,i.jsx)(Zt,{})})}),(0,i.jsx)(c.Route,{path:`/drive`,element:(0,i.jsx)(c.Navigate,{to:`/assets`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/drive/:rest`,element:(0,i.jsx)(c.Navigate,{to:`/assets`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/theme`,element:(0,i.jsx)(Jm,{children:(0,i.jsx)(bn,{})})}),(0,i.jsx)(c.Route,{path:`/pages/*`,element:(0,i.jsx)(Jm,{children:(0,i.jsx)(Ps,{})})}),(0,i.jsx)(c.Route,{path:`/forms/*`,element:(0,i.jsx)(Jm,{children:(0,i.jsx)(Ys,{})})}),(0,i.jsx)(c.Route,{path:`/settings`,element:(0,i.jsx)(c.Navigate,{to:`/pages`,replace:!0})}),(0,i.jsx)(c.Route,{path:`/profile`,element:(0,i.jsx)(qm,{children:(0,i.jsx)(Le,{})})}),(0,i.jsx)(c.Route,{path:`/billing`,element:(0,i.jsx)(qm,{children:(0,i.jsx)(Mm,{})})}),(0,i.jsx)(c.Route,{path:`/dashboard`,element:(0,i.jsx)(qm,{children:(0,i.jsx)(Wm,{})})}),(0,i.jsx)(c.Route,{path:`/publish`,element:(0,i.jsx)(Jm,{children:(0,i.jsx)(Hm,{})})}),(0,i.jsx)(c.Route,{path:`/setup`,element:(0,i.jsx)($c,{})}),(0,i.jsx)(c.Route,{path:`/setup/payments`,element:(0,i.jsx)(ql,{})}),(0,i.jsx)(c.Route,{path:`*`,element:(0,i.jsx)(Cm,{})})]}),(0,i.jsx)($m,{})]})})}function th(){return(0,i.jsx)(c.BrowserRouter,{children:(0,i.jsx)(nh,{})})}function nh(){let e=t.ka();return e.firebaseConfig&&e.firebaseConfig.apiKey&&e.firebaseConfig.apiKey.trim()!==``&&e.firebaseConfig.projectId&&e.firebaseConfig.projectId.trim()!==``||Fc()?(0,i.jsx)(eh,{}):(0,i.jsxs)(`div`,{className:`min-h-screen relative flex flex-col overflow-x-hidden`,children:[(0,i.jsx)(se,{standalone:!0}),(0,i.jsx)($c,{standalone:!0}),(0,i.jsx)($m,{})]})}function rh(e){v();let n=e.firebaseConfig;return n&&n.apiKey&&n.apiKey.trim()!==``&&n.projectId&&n.projectId.trim()!==``&&t.wa(n),(0,i.jsx)(t.Oa,{config:{firebaseConfig:e.firebaseConfig,basename:e.basename,onAuthChange:e.onAuthChange,themeConfig:e.themeConfig,components:e.components,customRoutes:e.customRoutes,microcomponents:e.microcomponents,defaultConfigs:e.defaultConfigs},children:(0,i.jsx)(t.Ea,{children:(0,i.jsx)(`div`,{className:`firebase-os flex-1 flex flex-col min-h-screen`,style:{background:`var(--bg-gradient)`,color:`var(--fg-color)`},children:(0,i.jsx)(th,{})})})})}var ih=Object.assign({}),ah={};for(let e in ih){let t=ih[e];if(!t?.default)continue;let n=e.replace(`./`,``).replace(`.tsx`,``);if(n===`registry`)continue;let r=n.replace(/Content$/,``).replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();ah[r]=t.default,ah[r.replace(/_/g,``)]=t.default}if(typeof window<`u`){let e=window.__FBOS_MICROCOMPONENTS__||{};window.__FBOS_MICROCOMPONENTS__={...ah,...e}}var oh=(e,t)=>{let n=e.toLowerCase().replace(/[^a-z0-9]+/g,`_`),r=n.replace(/_/g,``);if(ah[n]=t,ah[r]=t,typeof window<`u`){let e=window.__FBOS_MICROCOMPONENTS__||{};window.__FBOS_MICROCOMPONENTS__={...e,[n]:t,[r]:t}}},sh=({title:e,className:n,children:r,...a})=>(0,i.jsxs)(`div`,{className:t.ur(`border border-[var(--panel-border)] bg-[var(--panel-bg)] px-5 py-4`,n),style:{borderRadius:`var(--card-radius, 1rem)`},...a,children:[e?(0,i.jsx)(`p`,{className:`text-[12px] font-extrabold tracking-tight text-gradient mb-1.5`,children:e}):null,r]});sh.displayName=`Card`;var ch=({sub:e,className:n,children:r,...a})=>(0,i.jsxs)(`div`,{className:t.ur(`mb-4`,n),children:[(0,i.jsx)(`h2`,{className:`text-xl md:text-2xl font-extrabold tracking-tight text-foreground`,...a,children:r}),e?(0,i.jsx)(`p`,{className:`text-[13px] text-foreground/60 font-medium leading-relaxed mt-1`,children:e}):null]});ch.displayName=`SectionHeading`,exports.AdminNotifications=O,exports.Button=t.cr,exports.Card=sh,exports.ConfirmModal=He,exports.ContactPopup=t.t,exports.CustomSelect=t.sr,exports.DashboardNav=Ie,exports.EventCard=Au,exports.FirebaseOS=rh,exports.Input=t.lr,exports.ManagePlanButton=Dm,exports.Navbar=se,exports.PayButton=Qd,exports.PhoneInputField=n.t,exports.SectionHeading=ch,exports.TimeChips=t.q,exports.acceptBooking=t.n,Object.defineProperty(exports,`auth`,{enumerable:!0,get:function(){return t.Sa}}),exports.availableSlots=t.zt,exports.availableSlotsFor=t.Bt,exports.blockedWindows=t.Ut,exports.bookingPath=t.Qt,exports.cancelBooking=t.i,exports.confirmPayment=K,exports.dayBlocked=t.rn,exports.daysLine=t.in,Object.defineProperty(exports,`db`,{enumerable:!0,get:function(){return t.Ca}}),exports.emailAnyone=$r,exports.emailOwner=Zr,exports.emailPerson=Qr,exports.emailStatus=ei,exports.eventName=t.cn,exports.hoursSummary=t._n,exports.meetPath=ai,exports.notify=S,exports.oneEach=t.En,exports.openBillingPortal=ee,exports.partySlots=t.On,exports.payPath=t.kn,exports.registerMicrocomponent=oh,exports.scheduleName=t.Mn,exports.scheduleTitle=t.In,exports.slotsFor=t.Un,exports.startCheckout=W,Object.defineProperty(exports,`storage`,{enumerable:!0,get:function(){return t.Ta}}),exports.timeZoneLabel=t.Kn,exports.togetherSlots=t.Xn,exports.useAuth=t.Qi,exports.useBookings=t.g,exports.useConfig=t.ka,exports.useMemberSchedules=t._,exports.useMyPayments=te,exports.usePaymentsEnabled=X,exports.useSales=ne,exports.useTakenSlots=t.x,exports.useTeamHours=t.S,exports.useTheme=t.Da;
|