your-ai-workflow-firebase-os 1.13.3 → 1.13.4
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.
|
@@ -11,18 +11,18 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
|
|
|
11
11
|
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}
|
|
12
12
|
input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
|
|
13
13
|
input[type="number"]{-moz-appearance:textfield}
|
|
14
|
-
`}),(0,l.jsxs)(`div`,{className:`relative group/date flex flex-col w-full`,children:[(0,l.jsx)(t.g,{type:`date`,label:`Date`,required:!0,value:R.dateStr,onChange:e=>z({...R,dateStr:e.target.value}),className:`pr-10`}),(0,l.jsx)(`div`,{className:`absolute right-4 bottom-4 pointer-events-none group-focus-within/date:text-accent text-foreground/40 transition-colors`,children:(0,l.jsx)(n.ir,{className:`w-4 h-4`})})]}),(0,l.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-4`,children:[J?(0,l.jsx)(t.g,{type:`time`,label:`Time`,value:R.time,onChange:e=>z({...R,time:e.target.value}),required:!0}):(()=>{let{h:e,m:t,ampm:n}=Q(R.time);return(0,l.jsxs)(`div`,{className:`flex flex-col w-full`,children:[(0,l.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,children:`Time`}),(0,l.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,l.jsx)(`input`,{type:`number`,min:1,max:12,value:e,onChange:e=>z({...R,time:ce(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,l.jsx)(`span`,{className:`text-foreground/40 font-bold text-[15px] select-none`,children:`:`}),(0,l.jsx)(`input`,{type:`number`,min:0,max:59,value:t.toString().padStart(2,`0`),onChange:t=>z({...R,time:ce(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,l.jsx)(`button`,{type:`button`,onClick:()=>z({...R,time:ce(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,l.jsx)(t.g,{type:`number`,min:`1`,max:`1440`,label:`Duration (min)`,value:R.duration,onChange:e=>z({...R,duration:e.target.value}),placeholder:`60`,required:!0})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,l.jsx)(`label`,{className:`text-[11px] font-bold text-foreground/50 uppercase tracking-widest mt-1`,children:`Event Color`}),(0,l.jsx)(`div`,{className:`flex gap-2 items-center relative z-10 w-full h-[46px]`,children:Fn.map(e=>(0,l.jsx)(`button`,{type:`button`,onClick:()=>z({...R,color:R.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:R.color===e.text&&(0,l.jsx)(`div`,{className:`w-2.5 h-2.5 rounded-full bg-background`})},e.name))})]}),(0,l.jsx)(`div`,{className:`pt-2`,children:(0,l.jsx)(t.h,{type:`submit`,isLoading:M,className:`w-full py-3`,children:R.id?`Save Changes`:`Create Event`})})]})]})]},`edit-modal`),(0,l.jsx)(me,{isOpen:!!I,title:`Confirm Deletion`,message:(0,l.jsxs)(l.Fragment,{children:[`Are you sure you want to delete `,(0,l.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:I?.title}),` This action is permanent.`]}),onConfirm:Ce,onCancel:()=>{L(null)},isProcessing:P,confirmText:`Yes, Delete`})]});return h?(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:p?.tabTitle||p?.tabName||e}),i&&(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),i]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.jsxs)(n.kt.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:[Oe(),Ae()]})]}),je()]}):(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[c&&(0,l.jsx)(Ne,{to:c}),(0,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(r.y,{children:e}),i&&(0,l.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,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),i]})]})]}),(0,l.jsx)(`div`,{className:`flex flex-col gap-6 flex-1 min-h-0 pb-16`,children:(0,l.jsxs)(n.kt.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,l.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`}),Oe(),Ae()]})}),je()]})}var Rn=[{name:`Purple Standard`,preview:[`#2e1065`,`#cdc1ff`],dark:{buttonText:`#ffffff`,background:`#07070f`,backgroundSecondary:`#0a0a18`,accent:`#a78bfa`,gradient:[`#6d28d9`,`#a78bfa`],text:[`#f0eeff`,`#c4b5fd`,`#a78bfa`]},light:{buttonText:`#ffffff`,background:`#fcfaff`,backgroundSecondary:`#f7f3ff`,accent:`#7c3aed`,gradient:[`#5b21b6`,`#a78bfa`],text:[`#2e1065`,`#6d28d9`,`#cdc1ff`]}},{name:`Royal Navy`,preview:[`#1e3a8a`,`#60a5fa`],dark:{buttonText:`#ffffff`,background:`#050b14`,backgroundSecondary:`#0a192f`,accent:`#60a5fa`,gradient:[`#1d4ed8`,`#60a5fa`],text:[`#dbeafe`,`#93c5fd`,`#60a5fa`]},light:{buttonText:`#ffffff`,background:`#f8fafc`,backgroundSecondary:`#f1f5f9`,accent:`#2563eb`,gradient:[`#1e3a8a`,`#60a5fa`],text:[`#1e3a8a`,`#2563eb`,`#60a5fa`]}},{name:`Emerald Green`,preview:[`#064e3b`,`#10b981`],dark:{buttonText:`#ffffff`,background:`#050806`,backgroundSecondary:`#0a2218`,accent:`#34d399`,gradient:[`#047857`,`#34d399`],text:[`#d1fae5`,`#6ee7b7`,`#34d399`]},light:{buttonText:`#ffffff`,background:`#f6fbf8`,backgroundSecondary:`#eff7f2`,accent:`#059669`,gradient:[`#064e3b`,`#10b981`],text:[`#064e3b`,`#059669`,`#10b981`]}},{name:`Gold`,preview:[`#854d0e`,`#eab308`],dark:{buttonText:`#000000`,background:`#0f0905`,backgroundSecondary:`#1c1208`,accent:`#fcd34d`,gradient:[`#ca8a04`,`#facc15`],text:[`#fefce8`,`#fef08a`,`#facc15`]},light:{buttonText:`#ffffff`,background:`#fbfaf6`,backgroundSecondary:`#f5f2eb`,accent:`#d97706`,gradient:[`#854d0e`,`#eab308`],text:[`#854d0e`,`#ca8a04`,`#eab308`]}},{name:`Silver`,preview:[`#1e293b`,`#94a3b8`],dark:{buttonText:`#ffffff`,background:`#090e17`,backgroundSecondary:`#101725`,accent:`#cbd5e1`,gradient:[`#475569`,`#94a3b8`],text:[`#e2e8f0`,`#94a3b8`,`#cbd5e1`]},light:{buttonText:`#ffffff`,background:`#f8fafc`,backgroundSecondary:`#e2e8f0`,accent:`#64748b`,gradient:[`#1e293b`,`#94a3b8`],text:[`#1e293b`,`#475569`,`#94a3b8`]}},{name:`Barbie Pink`,preview:[`#d946ef`,`#f472b6`],dark:{buttonText:`#ffffff`,background:`#0c030a`,backgroundSecondary:`#1a0515`,accent:`#ff80ff`,gradient:[`#c026d3`,`#f472b6`],text:[`#ffeeff`,`#ffb3ff`,`#ff80ff`]},light:{buttonText:`#ffffff`,background:`#fcf5fa`,backgroundSecondary:`#f5ebf2`,accent:`#d946ef`,gradient:[`#c026d3`,`#ec4899`],text:[`#a21caf`,`#c026d3`,`#ec4899`]}},{name:`Orange`,preview:[`#7c2d12`,`#f97316`],dark:{buttonText:`#ffffff`,background:`#0a0200`,backgroundSecondary:`#1c0b05`,accent:`#fb923c`,gradient:[`#c2410c`,`#fb923c`],text:[`#fff7ed`,`#fdba74`,`#fb923c`]},light:{buttonText:`#ffffff`,background:`#fdf6f2`,backgroundSecondary:`#f5ebe4`,accent:`#ea580c`,gradient:[`#7c2d12`,`#f97316`],text:[`#7c2d12`,`#ea580c`,`#f97316`]}},{name:`Red`,preview:[`#7f1d1d`,`#ef4444`],dark:{buttonText:`#ffffff`,background:`#0a0000`,backgroundSecondary:`#2e0a0a`,accent:`#ef4444`,gradient:[`#b91c1c`,`#f87171`],text:[`#fef2f2`,`#fecaca`,`#f87171`]},light:{buttonText:`#ffffff`,background:`#fdf5f5`,backgroundSecondary:`#f5ebeb`,accent:`#dc2626`,gradient:[`#7f1d1d`,`#ef4444`],text:[`#7f1d1d`,`#dc2626`,`#ef4444`]}},{name:`Black & White`,preview:[`#ffffff`,`#000000`],dark:{buttonText:`#000000`,background:`#000000`,backgroundSecondary:`#111111`,accent:`#ffffff`,gradient:[`#ffffff`,`#e5e7eb`],text:[`#ffffff`,`#f3f4f6`,`#ffffff`]},light:{buttonText:`#ffffff`,background:`#ffffff`,backgroundSecondary:`#f3f4f6`,accent:`#000000`,gradient:[`#000000`,`#1f2937`],text:[`#000000`,`#1f2937`,`#374151`]}}],zn=[{key:`light`,label:`Light mode`,icon:n.Jt,description:`How the site looks for someone with light mode on.`},{key:`dark`,label:`Dark mode`,icon:n.pn,description:`How the site looks for someone with dark mode on.`}],Bn=n.o,Vn=`flex items-center gap-2 w-full h-10 px-1.5 rounded-[var(--input-radius,0.75rem)] border border-[var(--panel-border)] bg-[var(--panel-bg)] transition-all focus-within:border-accent hover:border-accent/40`,Hn=`outline outline-1 outline-[var(--panel-border)]`,Un=e=>JSON.parse(JSON.stringify(e)),Wn=(e,t)=>{if(typeof e!=`object`||!e||Array.isArray(e)||typeof t!=`object`||!t||Array.isArray(t))return JSON.stringify(e)===JSON.stringify(t)?void 0:e;let n={};for(let r of Object.keys(e)){let i=Wn(e[r],t[r]);i!==void 0&&(n[r]=i)}return Object.keys(n).length?n:void 0},Gn=e=>{let t=(e||``).replace(`#`,``).trim();return t.length===3?[0,1,2].map(e=>parseInt(t[e]+t[e],16)):t.length===6?[0,2,4].map(e=>parseInt(t.substring(e,e+2),16)):null},Kn=(e,t,n)=>{let r=e=>Math.max(0,Math.min(255,Math.round(e)));return`#${[e,t,n].map(e=>r(e).toString(16).padStart(2,`0`)).join(``)}`},qn=e=>{let t=(e||``).trim();if(t.startsWith(`#`)){let e=Gn(t);return e?Kn(e[0],e[1],e[2]):null}let n=t.match(/^rgba?\(\s*([\d.]+)[\s,]+([\d.]+)[\s,]+([\d.]+)/i);return n?Kn(parseFloat(n[1]),parseFloat(n[2]),parseFloat(n[3])):null},Jn=(e,t)=>{let n=Gn(e);return n?Kn(n[0]*t,n[1]*t,n[2]*t):e},Yn=e=>e?Array.isArray(e)?e.length===1?e[0]:`linear-gradient(135deg, ${e.join(`, `)})`:e:``,Xn=(e,t)=>{let n=Gn(qn(t)||t);if(!n)return{};let r=e=>`rgba(${n[0]}, ${n[1]}, ${n[2]}, ${e})`;return{panelBg:e===`dark`?r(`0.05`):`rgba(255, 255, 255, 0.70)`,panelBorder:r(e===`dark`?`0.15`:`0.08`),glowColor:r(e===`dark`?`0.40`:`0.30`),selectionBg:r(e===`dark`?`0.40`:`0.30`)}};function Zn({label:e,hint:t,value:r,over:i,onChange:a}){let o=qn(r)||`#7c3aed`;return(0,l.jsxs)(`div`,{className:`flex flex-col gap-1.5 p-3.5 sm:p-4 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,l.jsx)(`label`,{className:`text-[12.5px] font-bold text-foreground truncate`,children:e}),(0,l.jsxs)(`label`,{className:`relative w-7 h-7 rounded-lg cursor-pointer shrink-0 transition-all hover:scale-105 active:scale-95 flex items-center justify-center focus-within:ring-2 focus-within:ring-accent ${Hn}`,title:`Pick a colour for ${e}`,children:[(0,l.jsx)(`span`,{"aria-hidden":!0,className:`absolute inset-0 rounded-[inherit]`,style:{backgroundColor:i||`transparent`}}),(0,l.jsx)(`span`,{"aria-hidden":!0,"data-testid":`color-swatch`,className:`absolute inset-0 rounded-[inherit]`,style:{backgroundColor:r||`transparent`}}),(0,l.jsx)(`input`,{type:`color`,"aria-label":`${e} colour picker`,value:o,onChange:e=>a(e.target.value),className:`absolute inset-0 w-full h-full opacity-0 cursor-pointer p-0 border-0`})]})]}),t&&(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/45 font-medium leading-snug`,children:t}),(0,l.jsx)(`input`,{type:`text`,"aria-label":e,value:r??``,onChange:e=>a(e.target.value),className:Bn})]})}function Qn({label:e,hint:t,value:r,onChange:i}){let a=Array.isArray(r)&&r.length?r:[`#7c3aed`,`#6d28d9`],o=(e,t)=>{let n=[...a];n[e]=t,i(n)};return(0,l.jsxs)(`div`,{className:`flex flex-col gap-2.5 p-3.5 sm:p-4 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,l.jsx)(`label`,{className:`text-[12.5px] font-bold text-foreground truncate`,children:e}),(0,l.jsx)(`div`,{"data-testid":`gradient-preview`,className:`w-16 h-5 rounded-lg shrink-0 ${Hn}`,style:{background:Yn(a)}})]}),t&&(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/45 font-medium leading-snug`,children:t}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-2 pt-1.5`,children:[a.map((t,r)=>(0,l.jsxs)(`div`,{className:Vn,children:[(0,l.jsx)(`label`,{className:`relative w-6 h-6 rounded-md cursor-pointer shrink-0 transition-all hover:scale-105 active:scale-95 flex items-center justify-center ${Hn}`,style:{backgroundColor:t||`transparent`},title:`Pick colour ${r+1} for ${e}`,children:(0,l.jsx)(`input`,{type:`color`,"aria-label":`${e} colour ${r+1} picker`,value:qn(t)||`#7c3aed`,onChange:e=>o(r,e.target.value),className:`absolute inset-0 w-full h-full opacity-0 cursor-pointer p-0 border-0`})}),(0,l.jsx)(`input`,{type:`text`,"aria-label":`${e} colour ${r+1}`,value:t,onChange:e=>o(r,e.target.value),className:`flex-1 min-w-0 h-full bg-transparent border-0 px-0 text-[12px] font-semibold text-foreground outline-none`}),a.length>2&&(0,l.jsx)(`button`,{type:`button`,onClick:()=>i(a.filter((e,t)=>t!==r)),"aria-label":`Remove colour ${r+1} from ${e}`,className:`w-6 h-6 rounded-md flex items-center justify-center text-foreground/35 hover:text-red-500 hover:bg-red-500/10 transition-colors cursor-pointer shrink-0`,children:(0,l.jsx)(n.Pt,{className:`w-3.5 h-3.5`})})]},r)),a.length<6&&(0,l.jsxs)(`button`,{type:`button`,onClick:()=>i([...a,Jn(a[a.length-1]||`#6d28d9`,.9)]),className:`w-full h-9 px-3 rounded-lg border border-dashed border-accent/40 hover:border-accent bg-accent/[0.03] hover:bg-accent/10 text-accent text-[11.5px] font-bold flex items-center justify-center gap-1.5 transition-all active:scale-[0.99] cursor-pointer shadow-2xs mt-0.5`,children:[(0,l.jsx)(n.cn,{className:`w-3.5 h-3.5`}),`Add another colour`]})]})]})}function $n({label:e,hint:t,value:r,onChange:i}){let a=Number.isFinite(r)?r:0;return(0,l.jsx)(n.r,{label:e,hint:t,action:(0,l.jsxs)(`span`,{className:`text-[11px] font-bold text-foreground/50 tabular-nums shrink-0`,children:[Math.round(a*16),`px`]}),children:(0,l.jsx)(`input`,{type:`range`,min:0,max:3,step:.125,value:a,"aria-label":e,onChange:e=>i(parseFloat(e.target.value)),className:`w-full accent-accent cursor-pointer`})})}function er({title:e,onReset:t}){return(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3 pt-2 first:pt-0`,children:[(0,l.jsx)(`span`,{className:`text-[11px] font-black uppercase tracking-wider text-foreground/40`,children:e}),(0,l.jsx)(n.i,{icon:n.rn,compact:!0,title:`Reset ${e.toLowerCase()}`,onClick:t,children:`Reset`})]})}var tr=[`accent`,`foreground`,`background`,`backgroundSecondary`,`textGradient`,`notificationIconColor`],nr=[`buttonGradient`,`buttonHoverGradient`,`buttonText`,`secondaryButton`],rr=[`panelBg`,`panelBorder`,`glowColor`,`selectionBg`,`selectionText`],ir=`fbos_theme_ai_draft`,ar=()=>{try{return JSON.parse(localStorage.getItem(ir)||`{}`)}catch{return{}}},or=`Every mode needs these five: background, backgroundSecondary, foreground, accent and buttonText. Set any other colour I have actually named as well — the button fades, the quiet button, panel fill and edge, the highlight, the focus glow, the notification dot, the heading gradient — using my exact values where I gave them. Any colour I have NOT named, delete from the file rather than leaving it there: the app works those out from the five, and a colour left over from the look before is what makes a new theme come out wrong. Never copy a colour from another theme or an example.`,sr=e=>[...[`Design the look of my whole app. Here is what I am after: ${String(e?.brief||``).trim()||`___`}`,`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.`,`Set the dark colours and the light colours both, so my site reads well either way.`,or,...ur(e)],...dr].join(`
|
|
15
|
-
`),
|
|
16
|
-
`),lr=e=>{let t=e?.defaultTheme||`system`;return t===`light`?`In that same file, set defaultTheme to 'light' so my site always opens in light mode.`:t===`dark`?`In that same file, set defaultTheme to 'dark' so my site always opens in dark mode.`:`In that same file, set defaultTheme to 'system' so my site opens in whichever mode the visitor's device already uses.`},ur=e=>{let t=String(e?.appName||``).trim(),n=String(e?.logoUrl||``).trim(),r=String(e?.faviconUrl||``).trim(),i=[lr(e)];return t&&i.push(`In that same file, set appName to exactly: ${t}`),n&&i.push(`In that same file, set logoUrl to exactly this link: ${n} — that is my logo for the top bar. Use my link character for character, take my colours from the picture, and never swap it for a placeholder or a picture of your own.`),r&&i.push(r===n?`Set faviconUrl to that same link — it is my browser tab icon too.`:`In that same file, set faviconUrl to exactly this link: ${r} — that is my browser tab icon. Use my link character for character.`),!n&&!r?i.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.`):n?r||i.push(`Leave faviconUrl exactly as it is — my browser tab icon is mine, and my Theme screen is the only place it changes.`):i.push(`Leave logoUrl exactly as it is — my logo is mine, and my Theme screen is the only place it changes.`),i},dr=[`Tell me what you picked and why, in one short paragraph.`,`If nothing changes on my site after you edit that file, say so — a look I have saved in the app wins over the file, and I can undo that with Start again on my Theme screen.`],fr=(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.`,pr=[`appName`,`defaultTheme`,`showThemeToggle`],mr=[`cornerRounding`,`cornerRadii`];function hr(){let{activeConfig:e,theme:i}=t.y(),s=n.br(),c=(0,a.useMemo)(()=>Un(s?.themeConfig||n.Tr),[s]),[d,f]=(0,a.useState)(null),[p,m]=(0,a.useState)(ar),[h,g]=(0,a.useState)(`design`),_=(e,t)=>m(n=>{let r={...n,[e]:t};try{localStorage.setItem(ir,JSON.stringify(r))}catch{}return r}),[v,y]=(0,a.useState)(!1),[b,x]=(0,a.useState)(null),[S,C]=(0,a.useState)(!1),[w,T]=(0,a.useState)(null),E=a.default.useRef(null);(0,a.useEffect)(()=>{if(!e)return;let t=JSON.stringify(Un(e)),n=d?JSON.stringify(d):null;n!==t&&(n&&n!==E.current||(E.current=t,f(JSON.parse(t))))},[e,d]),(0,a.useEffect)(()=>{try{let e=sessionStorage.getItem(`fbos_theme_scrollY`);e&&requestAnimationFrame(()=>window.scrollTo(0,parseInt(e,10)))}catch{}let e=()=>{try{sessionStorage.setItem(`fbos_theme_scrollY`,String(window.scrollY))}catch{}};return window.addEventListener(`scroll`,e,{passive:!0}),()=>window.removeEventListener(`scroll`,e)},[]),(0,a.useEffect)(()=>{if(!d)return;let e=JSON.stringify(d);if(e===E.current)return;let t=setTimeout(async()=>{y(!0);try{let t=Wn(d,c);t?await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,`theme`),t):(await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_configs`,`theme`)),localStorage.removeItem(`theme_config_cache`)),E.current=e,x(Date.now())}catch(e){console.error(`Auto-save failed`,e)}y(!1)},300);return()=>clearTimeout(t)},[d,c]);let D=(e,t)=>f(n=>({...n,[e]:t})),O=(e,t)=>f(n=>({...n,colors:{...n.colors,[e]:{...n.colors?.[e]||{},...t}}})),k=(e,t)=>f(n=>({...n,colors:{...n.colors,[e]:{...n.colors?.[e]||{},secondaryButton:{...n.colors?.[e]?.secondaryButton||{},...t}}}})),A=(e,t)=>O(e,{accent:t,notificationIconColor:t,...Xn(e,t)}),j=(e,t,n)=>T({title:e,message:t,apply:n}),M=e=>f(t=>{let n=Un(t);return e.forEach(e=>{c[e]===void 0?delete n[e]:n[e]=Un(c[e])}),n}),N=(e,t)=>f(n=>{let r=Un(n),i=c.colors?.[e]||{};return r.colors=r.colors||{},r.colors[e]=r.colors[e]||{},t.forEach(t=>{i[t]===void 0?delete r.colors[e][t]:r.colors[e][t]=Un(i[t])}),r}),P=e=>{if(!d)return;let t=Un(d);t.colors=t.colors||{},[`dark`,`light`].forEach(n=>{let r=e[n],i=t.colors[n]||{};t.colors[n]={...i,accent:r.accent,buttonGradient:[...r.gradient],buttonHoverGradient:[...r.gradient],buttonText:r.buttonText,notificationIconColor:r.accent,textGradient:[...r.text],foreground:r.text[0],background:r.background,backgroundSecondary:r.backgroundSecondary,...Xn(n,r.accent),...i.secondaryButton?{secondaryButton:{...i.secondaryButton,text:r.text[0]}}:{}}}),f(t)},F=async()=>{C(!0);try{let e=Un(c);await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_configs`,`theme`)),localStorage.removeItem(`theme_config_cache`),localStorage.removeItem(`theme-mode`),localStorage.removeItem(`last-seen-default-theme`),localStorage.removeItem(ir),m({}),g(`design`),E.current=JSON.stringify(e),f(e)}catch{}setTimeout(()=>C(!1),600)},I=e=>{let t=zn.find(t=>t.key===e),r=d?.colors?.[e]||{},a=c.colors?.[e]||{},o=r.background||a.background||`#ffffff`;return(0,l.jsxs)(n.u,{icon:t.icon,title:t.label,description:t.description,defaultOpen:i===e,actions:(0,l.jsx)(n.i,{icon:n.rn,compact:!0,title:`Reset ${t.label.toLowerCase()}`,onClick:n=>{n.stopPropagation(),j(`Reset ${t.label.toLowerCase()}?`,`Every colour in ${t.label.toLowerCase()} — the brand colours, the buttons and the panels — goes back to how it started. The other mode is left alone.`,()=>N(e,[...tr,...nr,...rr]))},children:`Reset`}),children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-3 p-3.5 sm:p-4 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,l.jsx)(`span`,{className:`text-[12.5px] font-bold text-foreground`,children:`Ready-made colour sets`}),(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/45 font-medium leading-snug`,children:`One click repaints light and dark together.`})]}),(0,l.jsx)(`div`,{className:`flex items-center gap-3 overflow-x-auto no-scrollbar py-2.5 px-2.5 -mx-2.5`,children:Rn.map(t=>{let n=r.accent===t[e].accent&&d?.colors?.[e]?.buttonGradient?.[0]===t[e].gradient[0],i=t.name===`Black & White`;return(0,l.jsx)(`button`,{type:`button`,onClick:()=>P(t),"aria-label":t.name,title:t.name,className:`w-9 h-9 rounded-full shrink-0 transition-all relative cursor-pointer outline-offset-2 ${n?`outline-2 outline-accent scale-110 z-10`:`opacity-80 outline-0 hover:opacity-100 hover:outline-2 hover:outline-foreground/25 hover:scale-105`}`,style:i?{background:`linear-gradient(135deg, #ffffff 0%, #ffffff 50%, #000000 50%, #000000 100%)`}:{backgroundImage:`linear-gradient(135deg, ${t.preview[0]}, ${t.preview[1]})`}},t.name)})})]}),(0,l.jsx)(er,{title:`Brand and colours`,onReset:()=>j(`Reset the colours?`,`The brand colour, the text and the two backgrounds in ${t.label.toLowerCase()} go back to how they started. Nothing else changes.`,()=>N(e,tr))}),(0,l.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 items-start`,children:[(0,l.jsx)(Zn,{over:o,label:`Brand colour`,hint:`Links, highlights and the main buttons. Panels follow it too.`,value:r.accent||a.accent||`#7c3aed`,onChange:t=>A(e,t)}),(0,l.jsx)(Zn,{over:o,label:`Text colour`,hint:`Primary typography colour used across the app.`,value:r.foreground||a.foreground||`#111827`,onChange:t=>O(e,{foreground:t})}),(0,l.jsx)(Zn,{over:o,label:`Page background`,hint:`Main background canvas colour under all content.`,value:r.background||a.background||`#ffffff`,onChange:t=>O(e,{background:t})}),(0,l.jsx)(Zn,{over:o,label:`Second background`,hint:`The colour the page background fades into.`,value:r.backgroundSecondary||a.backgroundSecondary||`#f9fafb`,onChange:t=>O(e,{backgroundSecondary:t})}),(0,l.jsx)(Zn,{over:o,label:`Notification dot`,hint:`Colour applied to notification badging.`,value:r.notificationIconColor||r.accent||a.notificationIconColor||`#7c3aed`,onChange:t=>O(e,{notificationIconColor:t})}),(0,l.jsx)(Qn,{label:`Heading colours`,hint:`The colours big headings fade through.`,value:r.textGradient||a.textGradient,onChange:t=>O(e,{textGradient:t})})]}),(0,l.jsx)(er,{title:`Buttons`,onReset:()=>j(`Reset the buttons?`,`Every button colour in ${t.label.toLowerCase()} goes back to how it started. Nothing else changes.`,()=>N(e,nr))}),(0,l.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 gap-3 items-start`,children:[(0,l.jsx)(Qn,{label:`Button colours`,hint:`The colours your main buttons fade through.`,value:r.buttonGradient||a.buttonGradient,onChange:t=>O(e,{buttonGradient:t})}),(0,l.jsx)(Qn,{label:`Button colours on hover`,hint:`How a main button looks under the pointer.`,value:r.buttonHoverGradient||a.buttonHoverGradient,onChange:t=>O(e,{buttonHoverGradient:t})}),(0,l.jsx)(Zn,{over:o,label:`Button text`,hint:`The writing on your main buttons.`,value:r.buttonText||a.buttonText||`#ffffff`,onChange:t=>O(e,{buttonText:t})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-2 mt-1`,children:[(0,l.jsx)(`span`,{className:`text-[10px] font-extrabold uppercase tracking-wider text-foreground/40`,children:`Quieter buttons`}),(0,l.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-3 gap-3 items-start`,children:[(0,l.jsx)(Zn,{over:o,label:`Quiet button fill`,value:r.secondaryButton?.bg||a.secondaryButton?.bg||`rgba(0, 0, 0, 0.03)`,onChange:t=>k(e,{bg:t})}),(0,l.jsx)(Zn,{over:o,label:`Quiet button edge`,value:r.secondaryButton?.border||a.secondaryButton?.border||`rgba(0, 0, 0, 0.06)`,onChange:t=>k(e,{border:t})}),(0,l.jsx)(Zn,{over:o,label:`Quiet button text`,value:r.secondaryButton?.text||a.secondaryButton?.text||`#111827`,onChange:t=>k(e,{text:t})})]})]}),(0,l.jsx)(er,{title:`Panels and highlights`,onReset:()=>j(`Reset the panels?`,`Panels, edges, the focus glow and text highlighting in ${t.label.toLowerCase()} go back to how they started. Nothing else changes.`,()=>N(e,rr))}),(0,l.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 items-start`,children:[(0,l.jsx)(Zn,{over:o,label:`Panel fill`,hint:`Background colour of cards and panels.`,value:r.panelBg||a.panelBg||`rgba(255, 255, 255, 0.70)`,onChange:t=>O(e,{panelBg:t})}),(0,l.jsx)(Zn,{over:o,label:`Panel edge`,hint:`Borders of panels, inputs and dropdowns.`,value:r.panelBorder||a.panelBorder||`rgba(0, 0, 0, 0.08)`,onChange:t=>O(e,{panelBorder:t})}),(0,l.jsx)(Zn,{over:o,label:`Focus glow`,hint:`The glow around the box someone is typing in.`,value:r.glowColor||a.glowColor||`rgba(124, 58, 237, 0.30)`,onChange:t=>O(e,{glowColor:t})}),(0,l.jsx)(Zn,{over:o,label:`Highlight`,hint:`The colour behind text someone has selected.`,value:r.selectionBg||a.selectionBg||`rgba(124, 58, 237, 0.30)`,onChange:t=>O(e,{selectionBg:t})}),(0,l.jsx)(Zn,{over:o,label:`Highlighted text`,hint:`The colour of the selected text itself.`,value:r.selectionText||a.selectionText||`#ffffff`,onChange:t=>O(e,{selectionText:t})})]})]},e)};return(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`Theme`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/theme`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.jsxs)(`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,l.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,l.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-extrabold text-foreground tracking-tight`,children:h===`change`?`Change it with your assistant`:`Design it with your assistant`}),(0,l.jsxs)(`p`,{className:`text-[12.5px] sm:text-[13.5px] font-medium text-foreground/55 mt-1 sm:mt-1.5`,children:[(0,l.jsx)(`span`,{className:`sm:hidden`,children:`Fill these in for your assistant.`}),(0,l.jsx)(`span`,{className:`max-sm:hidden`,children:h===`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.`})]})]}),(0,l.jsxs)(`div`,{className:`shrink-0 flex items-center gap-2`,children:[(0,l.jsx)(n.i,{icon:n.It,compact:!0,title:h===`change`?`Design the whole look instead`:`Change the look you already have`,className:h===`change`?`text-accent border-accent/40 bg-accent/10 max-sm:border-transparent max-sm:bg-accent/10`:``,onClick:()=>g(h===`change`?`design`:`change`),children:`Edit with AI`}),(0,l.jsx)(n.i,{icon:n.rn,tone:`danger`,compact:!0,busy:S,title:`Start the whole look again`,onClick:()=>j(`Start the whole look again?`,`Every colour and every corner goes back to how it was the day you installed, and your answers in the assistant section above clear too. This cannot be undone.`,F),children:`Start again`})]})]}),(0,l.jsx)(r.h,{label:`Logo`,hint:`The picture in the top bar.`,value:p.logoUrl||``,onChange:e=>_(`logoUrl`,e),tips:r.m}),(0,l.jsx)(r.h,{label:`Browser tab icon`,hint:`The tiny picture on the browser tab.`,value:p.faviconUrl||``,onChange:e=>_(`faviconUrl`,e),tips:r.f}),(0,l.jsx)(n.h,{label:`App name`,hint:`It goes in the top bar and on the browser tab.`,value:p.appName||``,onChange:e=>_(`appName`,e),placeholder:`Bright Studio`}),(0,l.jsx)(n.d,{label:`How the site opens`,hint:`Light, dark, or whichever one the visitor already uses on their device.`,value:p.defaultTheme||`system`,onChange:e=>_(`defaultTheme`,e||`system`),allowEmpty:!1,options:[{value:`system`,label:`Whatever their device uses`},{value:`light`,label:`Always light`},{value:`dark`,label:`Always dark`}]}),h===`change`?(0,l.jsx)(n.m,{label:`What would you like changed?`,hint:`Name just the parts you want moved. Everything else stays as it is.`,value:p.changes||``,onChange:e=>_(`changes`,e),placeholder:`Make the buttons a softer green, and warm up the page background a little. Leave the cards as they are.`}):(0,l.jsx)(n.m,{label:`What look would you like?`,hint:`What you do, who it is for, and the feeling you are after.`,value:p.brief||``,onChange:e=>_(`brief`,e),placeholder:`A calm, modern look for a small physiotherapy clinic. Soft greens, lots of white space, nothing shouty. Rounded corners.`}),(0,l.jsx)(r.g,{title:`Copy this to your assistant`,prompt:h===`change`?cr(p):sr(p),locked:!!fr(p,h),onCopied:h===`change`?void 0:()=>g(`change`)}),(0,l.jsxs)(`p`,{className:`text-[11.5px] text-foreground/45 font-medium leading-snug px-1`,children:[`Uploads are kept on your`,` `,(0,l.jsx)(u.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,l.jsxs)(`div`,{className:`mt-10 pt-8 border-t border-[var(--panel-border)]/50 mb-5 flex items-start justify-between gap-3`,children:[(0,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-extrabold text-foreground tracking-tight`,children:`Change it by hand`}),(0,l.jsx)(`p`,{className:`text-[12.5px] sm:text-[13.5px] font-medium text-foreground/55 mt-1 sm:mt-1.5`,children:`One setting at a time. Changes show up straight away and save themselves.`})]}),(0,l.jsx)(`div`,{className:`shrink-0 flex items-center gap-2 pt-1`,children:(0,l.jsx)(n.l,{saving:v,savedAt:b})})]}),d?(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsxs)(n.u,{icon:n.vr,title:`Name and how it opens`,description:`What your site is called, and whether it opens light or dark.`,defaultOpen:!1,actions:(0,l.jsx)(n.i,{icon:n.rn,compact:!0,title:`Reset the name and how it opens`,onClick:()=>j(`Reset the name?`,`The name and the opening mode go back to how they started. Your logo and your browser tab icon are left alone.`,()=>M(pr)),children:`Reset`}),children:[(0,l.jsx)(n.h,{label:`Site name`,hint:`The name people see in the top bar and on the browser tab.`,value:d.appName||``,onChange:e=>D(`appName`,e),placeholder:`Your AI Firebase`}),(0,l.jsx)(r.h,{label:`Logo`,hint:`The picture in the top bar — changes straight away.`,value:d.logoUrl||``,onChange:e=>D(`logoUrl`,e),tips:r.m,action:(d.logoUrl||``)===(c.logoUrl||``)?void 0:(0,l.jsx)(n.i,{icon:n.rn,onClick:()=>D(`logoUrl`,c.logoUrl||``),children:`Put the original back`})}),(0,l.jsx)(r.h,{label:`Browser tab icon`,hint:`The tiny picture on the browser tab — changes straight away.`,value:d.faviconUrl||``,onChange:e=>D(`faviconUrl`,e),tips:r.f,action:(d.faviconUrl||``)===(c.faviconUrl||``)?void 0:(0,l.jsx)(n.i,{icon:n.rn,onClick:()=>D(`faviconUrl`,c.faviconUrl||``),children:`Put the original back`})}),(0,l.jsx)(n.d,{label:`How the site opens`,hint:`Light, dark, or whichever one the visitor already uses on their device.`,value:d.defaultTheme||`system`,onChange:e=>D(`defaultTheme`,e||`system`),allowEmpty:!1,options:[{value:`system`,label:`Whatever their device uses`},{value:`light`,label:`Always light`},{value:`dark`,label:`Always dark`}]}),(d.defaultTheme||`system`)===`system`&&(0,l.jsx)(n._,{label:`Let visitors switch it themselves`,hint:`Shows the sun and moon button in the top bar.`,enabled:d.showThemeToggle!==!1,onChange:e=>D(`showThemeToggle`,e)})]}),zn.map(e=>I(e.key)),(0,l.jsxs)(n.u,{icon:n.Yt,title:`Corners`,description:`How rounded everything looks.`,defaultOpen:!1,actions:(0,l.jsx)(n.i,{icon:n.rn,compact:!0,title:`Reset the corners`,onClick:()=>j(`Reset the corners?`,`Every corner goes back to how it started.`,()=>M(mr)),children:`Reset`}),children:[(0,l.jsx)(n.d,{label:`Rounding`,hint:`Keep the rounding we ship with, or set each corner yourself.`,value:d.cornerRounding||`default`,onChange:e=>D(`cornerRounding`,e||`default`),allowEmpty:!1,options:[{value:`default`,label:`Standard rounding`},{value:`custom`,label:`Set them myself`}]}),d.cornerRounding===`custom`&&(0,l.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-3`,children:[(0,l.jsx)($n,{label:`Buttons`,hint:`How round every button is.`,value:d.cornerRadii?.buttonRadius??.75,onChange:e=>D(`cornerRadii`,{...d.cornerRadii||{},buttonRadius:e})}),(0,l.jsx)($n,{label:`Boxes people type in`,hint:`Form fields and search boxes.`,value:d.cornerRadii?.inputRadius??.75,onChange:e=>D(`cornerRadii`,{...d.cornerRadii||{},inputRadius:e})}),(0,l.jsx)($n,{label:`Cards`,hint:`The panels your content sits on.`,value:d.cornerRadii?.cardRadius??1.5,onChange:e=>D(`cornerRadii`,{...d.cornerRadii||{},cardRadius:e})}),(0,l.jsx)($n,{label:`Pop-ups`,hint:`Dialogs and confirmation boxes.`,value:d.cornerRadii?.modalRadius??2.5,onChange:e=>D(`cornerRadii`,{...d.cornerRadii||{},modalRadius:e})})]})]})]}):(0,l.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,l.jsx)(n.yn,{className:`w-6 h-6 animate-spin text-accent`})})]})]}),(0,l.jsx)(me,{isOpen:!!w,title:w?.title||``,message:w?.message||``,confirmText:`Reset`,cancelText:`Keep it`,isProcessing:S,onCancel:()=>T(null),onConfirm:()=>{w?.apply(),T(null)}})]})}function gr({tone:e,title:t,message:n,action:r}){let i=e===`red`?`border-red-500/20`:`border-amber-500/25`,a=e===`red`?`bg-red-500/5`:`bg-amber-500/5`,o=e===`red`?`text-red-500`:`text-amber-500`;return(0,l.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,l.jsxs)(`div`,{className:`glass-panel p-8 md:p-10 rounded-3xl border ${i} text-center shadow-xl max-w-sm w-full relative overflow-hidden`,children:[(0,l.jsx)(`div`,{className:`absolute inset-0 ${a}`}),(0,l.jsx)(`h2`,{className:`text-2xl font-black ${o} mb-3 relative z-10 tracking-tight`,children:t}),(0,l.jsx)(`p`,{className:`text-[14px] text-foreground/70 font-medium leading-relaxed relative z-10 mb-6`,children:n}),(0,l.jsx)(`div`,{className:`relative z-10`,children:r})]})})}var _r=`w-full block py-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground text-[14px] font-bold rounded-xl transition-colors`,vr=`No access`,yr=`You do not have access to view this page. If you think you should, ask whoever runs this app.`,br=()=>(0,l.jsx)(gr,{tone:`amber`,title:vr,message:yr,action:(0,l.jsx)(u.Link,{to:`/dashboard`,className:_r,children:`Back to dashboard`})}),xr=br,Sr=br,Cr={route:`/page_1`,pageName:`New Page`,pageTitle:`My New Page`,template:`none`,form:``},wr={tabName:`New Page`,iconName:``,route:`/new-page`,tabTitle:`Your Page`,template:`none`,form:``},Tr={tabName:`New Admin Page`,iconName:``,route:`/new-admin-page`,tabTitle:`Admin Page`,template:`none`,form:``},Er={tabName:`New Team Page`,iconName:``,route:`/new-team-page`,tabTitle:`Team Page`,template:`none`,form:``},Dr=`sys_payments`,Or=`_settings`,kr=()=>({on:!1,amount:``,priceId:``,livePriceId:``}),Ar=()=>({name:``,description:``,monthly:{...kr(),on:!0},yearly:kr()}),jr=()=>({name:``,amount:``}),Mr=e=>({id:e,name:``,description:``,kind:``,amount:``,items:[],plans:[],how:``,emailReceipt:!0,notifyOwner:!0,pageIds:[],pagesNote:``,customNote:``,customPath:``,createdAt:Date.now()}),Nr=e=>e.kind===`once`?e.items.length?e.items:e.name.trim()||e.amount.trim()?[{name:e.name,amount:e.amount}]:[]:[],Pr=e=>{let t=Number(String(e||``).trim().replace(/[^0-9.]/g,``));return Number.isFinite(t)&&t>0?t:null},Fr=e=>({on:!!e?.on,amount:String(e?.amount||``),priceId:String(e?.priceId||``),livePriceId:String(e?.livePriceId||``)}),Ir=e=>/^(no|none|nothing|n\/?a|nothing needed|nothing else|-)[.!]*$/i.test(e.trim()),Lr=e=>/[.!?]$/.test(e)?e:`${e}.`,Rr=e=>{let t=[],n=String(e?.how||``),r=String(e?.collect||``).trim();r&&!Ir(r)&&t.push(`Before paying, the buyer tells me: ${Lr(r)}`);let i=String(e?.after||``).trim();if(i&&t.push(`After they pay: ${Lr(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: ${Lr(r)}`),i&&t.push(`Someone on ${e} sees: ${Lr(i)}`)}return t.length?[...n.trim()?[Lr(n.trim())]:[],...t].join(` `):n},zr=(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:Fr(e?.monthly),yearly:Fr(e?.yearly)})):[],how:Rr(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}},Br=e=>/^price_[A-Za-z0-9]+$/.test(e.trim()),Vr=(e,t=wi())=>t?e.livePriceId:e.priceId;function Hr(e,t=wi()){if(!e.kind)return`Say how it is paid — once, or a subscription.`;if(e.kind===`once`){let t=Nr(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(Pr(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(Pr(i.amount)===null)return`Give ${e} its ${r} price — just a number.`;if(!Br(Vr(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 Ur=(e,t=wi())=>Hr(e,t)===``,Wr=e=>e.kind===`subscription`&&e.plans.length>0&&e.plans.every(e=>e.name.trim()!==``&&(e.monthly.on||e.yearly.on)&&(!e.monthly.on||Pr(e.monthly.amount)!==null)&&(!e.yearly.on||Pr(e.yearly.amount)!==null));function Gr(e){let t=e.name.trim();if(t)return t;let n=Nr(e);return n.length===1&&n[0].name.trim()?n[0].name.trim():`this product`}function Kr(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=Nr(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 qr(e,t,n=wi()){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 Jr=e=>e.includes(`'`)?`"${e}"`:`'${e}'`,Yr=`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.`,Xr=(e,t=wi())=>{let n=e.name.trim()||`this product`,r=e.description.trim();if(e.kind===`once`){let t=Nr(e),r=e=>`<PayButton amount={${Pr(e.amount)??0}} productName=${Jr(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='${Vr(n.monthly,t).trim()}' mode='subscription'>`),n.yearly.on&&a.push(`${n.yearly.amount.trim()} per year: <PayButton priceId='${Vr(n.yearly,t).trim()}' mode='subscription'>`),i.push(`${e}${r?` (${r})`:``} — ${a.join(`; `)}.`)}return i},Zr=`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.`,Qr=`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 $r(e,t=``,n=wi()){let r=[...Xr(e,n)],i=e.how.trim();i&&r.push(`Here is how this payment should work, start to finish: ${i}`),r.push(Zr),e.kind===`subscription`&&r.push(Qr),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 ei=e=>e===`internal`||e===`admin`,ti=()=>({name:``,address:``,type:`internal`,iconName:``,template:`none`,form:``,formFields:``,formButton:``,formSpot:``,about:``}),ni=e=>Array.isArray(e?.links)?e.links.map(e=>{let t={pageId:String(e?.pageId||``),how:String(e?.how||``)};if(e?.draft&&typeof e.draft==`object`){let n=e.draft,r=ti();t.draft={name:String(n.name??r.name),address:String(n.address??r.address),type:String(n.type||r.type),iconName:String(n.iconName??r.iconName),template:String(n.template||r.template),form:String(n.form??r.form),formFields:String(n.formFields??r.formFields),formButton:String(n.formButton??r.formButton),formSpot:String(n.formSpot??r.formSpot),about:String(n.about??r.about)}}return t}):[],ri=(e,t)=>t.find(t=>t.id===e)||t.find(t=>String(t.config?.contentKey||``).trim()===e),ii=(e,t)=>e===t.id||e===String(t.config?.contentKey||``).trim();function ai(e){return e.how.trim()?``:`Describe how this payment will work.`}var oi=(e,t)=>t.filter(t=>e.pageIds.some(e=>ii(e,t))),si=(e,t)=>e.pageIds.some(e=>ii(e,t)),ci=(e,t)=>si(e,t)?e.pageIds.filter(e=>!ii(e,t)):[...e.pageIds,t.id],li=(e,t)=>oi(e,t).length||e.pagesNote.trim()?``:`Tick the pages it goes on, or describe a page to add.`;function ui(e,t,n=wi()){if(!e.length)return`Describe what you sell first — the request is built from it.`;for(let t of e){let e=Kr(t).split(` — `)[0];if(!Ur(t,n))return`Finish ${e} under What you sell.`;if(ai(t))return`Say how ${e} works under How your payments work.`}for(let n of e){let e=Kr(n).split(` — `)[0];if(li(n,t))return`Say where ${e} goes — tick its pages, or describe a page to add.`}return``}var di={public:`anyone`,user:`signed-in users`,internal:`your team`,admin:`admins only`},fi=`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, CustomSelect } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button, and every dropdown is CustomSelect (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser's own <select>, which ignores my theme. The design should be minimal, modern and clean.`,pi=`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.`,mi="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.",hi=[`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.`],gi=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``);function _i(e){let t=e.audience||`public`,n=ei(t),r=di[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 t=e.config||{},n=gi(String(t.contentKey||t.tabName||t.pageName||t.pageId||e.title||``))||`Page`,r=n.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/${n}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 ${n}Content from './${n}Content'; and registerMicrocomponent('${r}', ${n}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.`);let a=String(t.form||``).trim();a&&a!==`__new__`&&i.push(`The page already has a form, '${a}' — show it with <ContactPopup formId='${a}' /> 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(mi),i}var vi=e=>`${e.path}${e.title?` (${e.title})`:``}`;function yi(e,t,n=wi()){let r=[`Build ${e.length===1?`my payment`:`my payments`} into my app. ${Yr}`],i=[],a=!1;for(let o of e){let e=oi(o,t);for(let t of e)i.includes(t)||i.push(t);let s=e.filter(e=>!ei(e.audience)),c=s.length===1?s[0].path:``;r.push(...$r(o,c,n));let l=Gr(o);e.length&&r.push(`${l} goes on ${e.length===1?`this page`:`these pages`} of mine: ${e.map(vi).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(..._i(e))}return a?r.push(`If my words name a page that does not exist yet, add it. ${hi[0]}`,...hi.slice(1)):r.push(`If the payments need a page my words do not name, make it the app's way. ${hi[0]}`),r.push(fi,pi),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(`
|
|
17
|
-
`)}var
|
|
18
|
-
`)}var Di=`Could not reach the server. Check your connection and try again.`;async function Oi(e,t){try{let n=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}),r=await n.json().catch(()=>({}));return!n.ok||r?.success===!1?typeof r?.error==`string`&&r.error||`The email could not be sent.`:null}catch{return Di}}function ki(e,t={}){return Oi(`/api/email/notify`,{template:e,data:t})}function Ai(e,t,n,r={}){return Mi(`/api/email/send`,{template:e,collection:t,docId:n,data:r})}function ji(e,t,n,r={}){return Mi(`/api/email/compose`,{to:e,subject:t,message:n,...r})}async function Mi(e,t){try{let r=await n.xr?.currentUser?.getIdToken().catch(()=>null),i=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,...r?{Authorization:`Bearer ${r}`}:{}},body:JSON.stringify(t)}),a=await i.json().catch(()=>({}));return!i.ok||a?.success===!1?typeof a?.error==`string`&&a.error||`The email could not be sent.`:null}catch{return Di}}async function Ni(){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:Di}}}var Pi=e=>`${n.st(e)} · ${n.pt(e.slotMinutes)}`;function Fi({schedules:e,selected:t,onPick:r,placeholder:i=`Pick a schedule`}){let[o,s]=(0,a.useState)(!1);if(e.length===0)return(0,l.jsxs)(`p`,{className:n.a,children:[`No schedule yet — add one on the`,` `,(0,l.jsx)(u.Link,{to:`/schedule`,className:`text-accent font-bold hover:underline`,children:`Schedule screen`}),` first.`]});let c=t.map(t=>e.find(e=>e.id===t)).filter(e=>!!e);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,l.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 ${o?`border-accent`:`border-[var(--panel-border)] hover:border-accent/40`}`,children:[(0,l.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-wrap items-center gap-1.5`,children:[c.length===0&&(0,l.jsx)(`button`,{type:`button`,onClick:()=>s(e=>!e),className:`text-[14px] text-foreground/35 text-left cursor-pointer`,children:i}),c.map(e=>(0,l.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,l.jsx)(`span`,{className:`truncate`,children:n.st(e)}),(0,l.jsx)(`button`,{type:`button`,"aria-label":`Remove ${n.st(e)}`,onClick:()=>r(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,l.jsx)(n.Pt,{className:`w-3 h-3`})})]},e.id))]}),(0,l.jsx)(`button`,{type:`button`,"aria-label":o?`Close the list of schedules`:`Open the list of schedules`,"aria-expanded":o,onClick:()=>s(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,l.jsx)(n.tr,{className:`w-4 h-4 transition-transform ${o?`rotate-180`:``}`})})]}),o&&(0,l.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 i=t.includes(e.id),a=e.enabled?n.it(e)?`Unfinished on the Schedule screen`:``:`Turned off on the Schedule screen`;return(0,l.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":i,"aria-label":n.st(e),onClick:()=>r(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 ${n.I(e)?``:`opacity-70`}`,children:[(0,l.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${i?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:i&&(0,l.jsx)(n.nr,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,l.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate min-w-0`,children:Pi(e)}),a&&(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 whitespace-nowrap shrink-0 max-sm:hidden`,children:a})]},e.id)})}),(0,l.jsx)(`span`,{className:n.a,children:`One schedule per person — picking a second one of theirs replaces the first.`})]})}var Ii=!1,Li=e=>{Ii=e},Ri=()=>Ii,zi=[{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:`setup`,title:`Setup`,path:`/setup`,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}],Bi=new Set([`home`,`dashboard`,`profile`]),Vi=e=>[...e,...zi.filter(t=>!e.some(e=>e.id===t.id))],Hi={public:`Anyone`,user:`Signed-in users`,internal:`Your team`,admin:`Admins only`},Ui=e=>e.draft?`draft`:e.hidden?`hidden`:`live`,Wi={draft:`Draft`,live:`Live`,hidden:`Hidden`},Gi={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.`},Ki=e=>(e||``).trim().toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9_-]/g,``),qi=e=>String(e||``).replace(/^\/+/,``).replace(/[^a-zA-Z0-9_-]/g,`_`).toLowerCase();function Ji(e){let t=Ki(e.address);if(!t)throw Error(`A page needs a web address.`);let n=qi(`/`+t),r=e.type===`public`,i={form:e.form||``,formFields:e.formFields||``,formButton:e.formButton||``,formSpot:e.formSpot||``},a=r?{route:`/`+t,pageName:e.name,pageTitle:e.name,...i,brief:e.about,contentKey:n}:{route:`/`+t,tabName:e.name,tabTitle:e.name,iconName:e.iconName||``,template:na.some(t=>t.value===e.template)?e.template:`none`,...i,brief:e.about,pageType:e.type,contentKey:n};return a.form===`__new__`&&(a.form=Xa(a),a.formIsNew=!0),{id:n,config:a,isPublic:r}}async function Yi(e){let{id:t,config:r,isPublic:i}=Ji(e);await(0,o.setDoc)((0,o.doc)(n.Sr,i?`sys_pages`:`sys_tabs`,t),r);let a=i?`page_order`:`tab_order`,s=await(0,o.getDoc)((0,o.doc)(n.Sr,`sys_configs`,a)),c=(s.exists()?s.data()?.order:null)||[];return c.some(e=>(typeof e==`string`?e:String(e?.id))===t)||await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,a),{order:[...c,{id:t,hidden:!1}]}),t}var Xi=(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},Zi=()=>Object.fromEntries(S()),Qi=(e,t=!1)=>{let n={};for(let[i,a]of Object.entries(Zi())){let o=!!a.isPublic;if(o!==e)continue;let s=a.config||{};!t&&s.enabled===!1||(n[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`:r.V(s.pageType),isSystem:!1,enabled:s.enabled!==!1,fromFile:!0})}return n};function $i({value:e,onChange:t,busy:i}){return(0,l.jsx)(`div`,{className:`shrink-0`,onClick:e=>e.stopPropagation(),children:(0,l.jsx)(n.Et,{compact:!0,portal:!0,direction:`auto`,className:`console-select`,ariaLabel:`Who can open this page`,value:e,disabled:i,onChange:e=>t(e),options:r.P.map(e=>({value:e,label:Hi[e]}))})})}var ea=`Add it here — a name and what you would like to see on it — then copy the sentence for your assistant.`,ta=`Add it here, then copy the sentence for your assistant.`,na=[{value:`none`,label:`From scratch`},{value:`board`,label:`Board`},{value:`table`,label:`Table`},{value:`calendar`,label:`Calendar`},{value:`drive`,label:`Files`}],ra=[`board`,`table`,`calendar`,`drive`],ia={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()`}},aa=e=>{let t=ia[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=>r.v(e,1)[0]||``,sa=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``),ca=(e,t)=>t?.contentKey||t?.tabName||t?.pageName||t?.pageId||e.title,la=(e,t)=>`src/your-ai-workflow-firebase-os/microcomponents/${sa(ca(e,t))||`Page`}Content.tsx`,ua=(e,t)=>{let n=String(t?.route||``).trim();return n?n.startsWith(`/`)?n:`/`+n:e.path||``},da=(e,t,r=[])=>ua(e,t).replace(/^\/+/,``)?String(t?.brief||``).trim()?Za(t)?`Say what the form should ask for, and this sentence is ready to copy.`:ro(t)||fo(t,r)||n.L(t,n.X()):`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.`,fa=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||``)})):fa(e),ma=e=>String(e?.imageNotes||``).trim(),ha=e=>{let t=fa(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=ma(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.`]},ga=e=>{let t=String(e?.pageWish||``).trim(),n=[];return t&&n.push(`Here is what I would like on the page: ${t}`),n.push(...ha(e)),n},_a=e=>ga(e).length>0,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, CustomSelect } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button, and every dropdown is CustomSelect (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme — so nothing gets a look of its own. The design should be minimal, modern and clean and match the app.`,ya=(e,t,n=[])=>{let r=ua(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=sa(ca(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: ${la(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,`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.`,ba];ra.includes(o)&&f.push(aa(o));let p=ja(t);return p?f.push(...Ma(t,l)):s?f.push(...Na(t,s)):Ea(c)&&f.push(Da(t,l)),f.push(...Pa(t,p)),f.push(...ka(t,l)),f.push(...io(t)),f.push(...ha(t)),f.push(`Here is what I would like on it: ${c||`___`}`),f.push(...vo(t,n)),f.join(`
|
|
19
|
-
`)},
|
|
20
|
-
`)){let e=r.match(
|
|
21
|
-
`).trim(),t},
|
|
22
|
-
`),
|
|
23
|
-
`)},
|
|
24
|
-
`)},za=(e,t)=>{let n=e=>{let{_uiKey:t,pageType:n,route:r,contentKey:i,...a}=e||{};return a},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},Ba=(e,t)=>{let n=Zi(),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},Va=(e,t)=>{let{_uiKey:n,...r}=e||{};return Object.keys(r).length>0?{...r,pageType:t}:{pageType:t}},Ha=`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`,Ua=`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`,Wa={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`},Ga={draft:`bg-foreground/30`,live:`bg-emerald-500 shadow-[0_0_5px] shadow-emerald-500/60`,hidden:`bg-foreground/25`};function Ka({status:e}){return(0,l.jsxs)(`span`,{title:Gi[e],className:`inline-flex items-center gap-1.5 text-[11px] font-semibold px-2.5 py-[3px] rounded-full border ${Wa[e]}`,children:[(0,l.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full shrink-0 ${Ga[e]}`}),Wi[e]]})}var qa=e=>{let t=typeof window<`u`?window.location.host:``;return t?`${t}${e}`:e},Ja=e=>e.replace(/[_-]+/g,` `).replace(/^./,e=>e.toUpperCase()),Ya=`__new__`,Xa=e=>String(e?.contentKey||``).toLowerCase().replace(/-+/g,`_`),Za=e=>ja(e)&&!Aa(e)&&!String(e?.formFields||``).trim(),Qa=[{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}],$a=e=>Qa.filter(t=>!t.team||ei(e)),eo=[{value:`text`,label:`Simple text`},{value:`notification`,label:`Notification`}],to=e=>e.look===`text`||e.look===`notification`?e.look:Qa.find(t=>t.id===e.kind)?.look||`text`,no=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=>Qa.some(t=>t.id===e.kind))},ro=e=>{if(!Ri())return``;for(let t of no(e))if(!t.what.trim())return`Say what the email should be about, and this sentence is ready to copy.`;return``},io=e=>{if(!Ri())return[];let t=oo(e),n=[];for(let r of no(e)){let e=r.what.trim();if(!e)continue;let i=to(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},ao=(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=sa(ca(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: ${la(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||``);ra.includes(d)&&r.push(aa(d));let f=String(n.form||``).trim(),p=ja(n);return p?(Aa(n)||String(n.formFields||``).trim())&&r.push(...Ma(n,n.pageType?`private`:`public`)):f&&r.push(...Na(n,f)),r.push(ba),r.push(...io(n)),r.push(...ha(n)),r.push(...Pa(n,p)),s()},oo=e=>ei(r.V(e?.pageType)),so=e=>!!String(e?.form||``).trim()||!!e?.formIsNew,co=e=>`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.`,lo=(e,t)=>e.pageId?ri(e.pageId,t):void 0,uo=(e,t)=>e.pageId?lo(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.`,fo=(e,t)=>{for(let n of ni(e)){let e=uo(n,t);if(e)return e}return``},po=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`}}},mo={public:0,user:1,internal:2,admin:3},ho=e=>e?.pageType?r.V(e.pageType):`public`,go=e=>({user:`user_`,internal:`mem_`,admin:`admin_`})[e]||`pub_`,_o=(e,t)=>{let n=ho(e),r=t.audience||`public`;if(mo[n]===mo[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=mo[n]>mo[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=go(i.audience);return[`The two pages are for different people, so they cannot share one collection: a ${po(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 ${po(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 vo(e,t){let r=[],i=so(e);for(let a of ni(e)){let o=lo(a,t),s=a.how.trim();if(!o||!s)continue;let c=o.audience===`admin`,l=ei(o.audience),u=po(o.audience);r.push(`This page is linked to the ${u.kind} page at ${o.path}, which ${u.who} can open. Build both pages of the link in this one request — this page and the one at ${o.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.`),r.push(`Here is how the two pages are linked: ${s}`),r.push(..._o(e,o));let d=n.Z(o.path,o.config,n.X(),oo(e));d&&r.push(d),i&&l&&!c&&r.push(`Entries from the form on this page land in the Inbox collections, which only admins may read. ${co(o.path)}`),r.push(`For the page at ${o.path}:`),r.push(...ao(o))}return r.length&&r.push(`Do not touch any page this request does not name.`),r}var yo=(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&&ni(r[t.id]).some(e=>e.pageId&&i.has(e.pageId))&&o.push(t.title);return o};function bo({images:e,notes:t,onChange:i,onNotes:a,onBlur:o}){let s=e.filter(e=>e.url),c=e=>i(s.filter((t,n)=>n!==e));return(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[s.length>0&&(0,l.jsx)(`div`,{className:`flex flex-wrap gap-2.5`,"aria-label":`Your pictures`,children:s.map((e,t)=>(0,l.jsxs)(`div`,{className:`relative w-20 h-20 rounded-xl overflow-hidden border border-[var(--panel-border)] bg-[var(--panel-bg)]`,children:[(0,l.jsx)(`img`,{src:e.url,alt:`Picture ${t+1}`,className:`w-full h-full object-cover`}),(0,l.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:t+1}),(0,l.jsx)(`button`,{type:`button`,"aria-label":`Remove picture ${t+1}`,title:`Remove this picture`,onClick:()=>c(t),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,l.jsx)(n.Pt,{className:`w-3 h-3`})})]},`${e.url}-${t}`))}),(0,l.jsx)(r.h,{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&&i([...s,{url:e,where:``}])},tips:s.length?void 0:r.p}),s.length>0&&(0,l.jsx)(n.m,{label:`How should the pictures be used?`,hint:`Optional — say it by number. Anything you leave out, your assistant decides.`,value:t,onChange:a,onBlur:o,placeholder:`1 across the top behind the heading, 2 and 3 side by side under it`})]})}function xo({emails:e,audience:t,onChange:r,onBlur:i}){let o=$a(t),s=o.map(e=>({value:e.id,label:e.label})),[c,u]=(0,a.useState)(!1),d=e.length?c?[...e,{kind:``,what:``}]:e:[{kind:``,what:``}],f=(e,t)=>{u(!1),r(d.map((n,r)=>r===e?{kind:t,what:n.what}:n).filter(e=>!!e.kind),!0)},p=(e,t)=>r(d.map((n,r)=>r===e?{...n,what:t}:n).filter(e=>!!e.kind),!1),m=(e,t)=>r(d.map((n,r)=>r===e?{...n,look:t}:n).filter(e=>!!e.kind),!0),h=!c&&e.length>0&&e.length<o.length;return(0,l.jsx)(n.r,{label:`Emails on this page`,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,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[d.map((e,t)=>{let r=o.find(t=>t.id===e.kind),a=s.filter(t=>t.value===e.kind||!d.some(e=>e.kind===t.value));return(0,l.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5`,children:[(0,l.jsx)(n.d,{label:t===0?`Would you like to add emails to this page?`:`Another email`,value:e.kind,onChange:e=>f(t,e),options:a,placeholder:`No`}),r&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.m,{label:r.ask,hint:r.hint,value:e.what,onChange:e=>p(t,e),onBlur:i,placeholder:r.placeholder}),(0,l.jsx)(n.d,{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:to(e),onChange:e=>m(t,e),options:eo,allowEmpty:!1})]})]},t)}),h&&(0,l.jsx)(`div`,{className:`flex`,children:(0,l.jsx)(n.i,{icon:n.cn,onClick:()=>u(!0),children:`Another email`})})]})})}var So=e=>{let t=e?.booking&&typeof e.booking==`object`?e.booking:{};return{schedules:n.mt(t),how:String(t.how||``)}};function Co({booking:e,audience:t,schedules:r,onChange:i,onHow:a,onBlur:o}){let s=ei(t),c=e.schedules.length>0;return(0,l.jsx)(n.r,{label:`Booking on this page`,hint:s?`Pick whose bookings your team follows here — every booking, who, when. Schedules are made on the Schedule screen.`:`Pick what can be booked on this page — a schedule from the Schedule screen, one per person. Its length, hours and price come with it.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,l.jsx)(Fi,{schedules:r,selected:e.schedules,onPick:t=>i({...e,schedules:n.tt(e.schedules,t,r)})}),c&&(0,l.jsx)(n.m,{label:`How should booking work here?`,hint:s?`What your team sees here — every booking, who, when.`:`The length and the price are set by the schedule — say the rest: who this is for, what the visitor reads first, what they should tell you before they pick a time, and what happens after. Your assistant shapes the picker from this — a whole calendar when the page is about booking, one compact question when it is not.`,value:e.how,onChange:a,onBlur:o,placeholder:s?`Every booking as a row — who, with whom, when — soonest first.`:`For new clients. Explain what the session covers, ask what they need help with before they pick a time, and say I will confirm by email.`})]})})}var wo=`__new_linked_page__`,To=[{value:`public`,label:`Anyone`},{value:`user`,label:`Signed-in people`},{value:`internal`,label:`Your team`},{value:`admin`,label:`Admins only`}],Eo=e=>Ki(e.address)||Ki(e.name),Do=(e,t,n)=>{let r=Eo(e);return!(!e.name.trim()||!r||n(r)||!t.trim()||e.form===`__new__`&&!e.formFields.trim())},Oo=(e,t=``)=>{let n=To.some(t=>t.value===e.type)?e.type:`internal`;return{name:e.name.trim(),address:Eo(e),type:n,about:e.about.trim()||t.trim(),iconName:e.iconName||(n===`public`?``:oa(e.name)),template:e.template,form:e.form,formFields:e.formFields.trim(),formButton:e.formButton.trim(),formSpot:e.formSpot.trim()}};function ko({draft:e,taken:t,onEdit:r,onSave:i,onBlur:o}){let[s,c]=(0,a.useState)(``),u=Eo(e),d=()=>e.name.trim()?!u||t(u)?(c(u?`Another page already lives at /${u}. Pick a different name.`:`Use a name with a letter or a number in it.`),!1):(c(``),!0):(c(`Give the new page a name, for example Bookings`),!1);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h,{label:`Name of the new page`,hint:u?`It will live at /${u} — its address, heading and icon can be changed in its settings later.`:`What it is called in the menu.`,value:e.name,onChange:e=>{r({name:e}),s&&c(``)},onBlur:()=>{d(),o()},error:s,placeholder:`Bookings`}),(0,l.jsx)(n.d,{label:`Who can open it`,hint:`Anyone is your public website. Your team is everyone you have marked internal, plus admins.`,value:e.type,onChange:e=>i({type:e}),options:To,allowEmpty:!1})]})}function Ao({link:e,links:t,index:r,targets:i,self:o,onPatch:s,onBlur:c,onRemove:u,taken:d,onCreatePage:f}){let[p,m]=(0,a.useState)(!1),[h,g]=(0,a.useState)(``),_=lo(e,i),v=i.filter(e=>!ii(o.id,e)&&!(o.contentKey&&ii(o.contentKey,e))&&(e.id===_?.id||!t.some((t,n)=>n!==r&&lo(t,i)?.id===e.id))),y=e.pageId?_?.id||e.pageId:e.draft?wo:``,b=e=>{s(e===`__new_linked_page__`?{pageId:``,draft:ti()}:{pageId:e,draft:void 0},!0)},x=async()=>{if(e.draft){m(!0),g(``);try{s({pageId:await f(Oo(e.draft,e.how)),draft:void 0},!0)}catch(e){console.error(`Failed to create the linked page:`,e),g(`The page could not be created. Check its web address and try again.`)}m(!1)}},S=!!e.draft&&Do(e.draft,e.how,d);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-4`,children:[(0,l.jsx)(n.d,{label:`Which page is it linked to?`,hint:y?void 0:`One of your pages — or a new one, made right here with its own settings.`,value:y,onChange:b,options:[{value:wo,label:`+ A new page, made right here`},...v.map(e=>({value:e.id,label:`${e.title} — ${e.path}`}))],placeholder:`Pick a page`}),!!e.pageId&&!_&&(0,l.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,l.jsx)(ko,{draft:e.draft,taken:d,onEdit:t=>s({draft:{...e.draft,...t}},!1),onSave:t=>s({draft:{...e.draft,...t}},!0),onBlur:c}),(!!_||!!e.draft)&&(0,l.jsx)(n.m,{label:e.draft?`What is the new page, and how are the two linked?`:`How will the pages be linked?`,hint:e.draft?`In your own words — what the new page shows, and what made here should show up there. Your assistant decides the rest.`:`In your own words — what made here should show up there. It goes into the sentence below.`,value:e.how,onChange:e=>s({how:e},!1),onBlur:c,placeholder:e.draft?`A page for my team with every booking made here — who, when, what for — newest first.`:`Every booking made on this page appears there, newest first.`}),!!h&&(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500`,children:h}),(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 pt-1`,children:[e.draft?(0,l.jsx)(n.i,{icon:n.cn,busy:p,disabled:!S,onClick:x,children:`Create and link it`}):(0,l.jsx)(`span`,{}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Unlink`,onClick:u,children:`Unlink`})]})]})}function jo({links:e,targets:t,self:r,onChange:i,onBlur:a,taken:o,onCreatePage:s}){let c=(t,n,r)=>i(e.map((e,r)=>{if(r!==t)return e;let i={...e,...n};return i.draft||delete i.draft,i}),r),u=t=>i(e.filter((e,n)=>n!==t),!0),d=()=>i([...e,{pageId:``,how:``}],!0),f=e.every(e=>!!lo(e,t));return e.length?(0,l.jsx)(n.r,{label:`Linked pages`,hint:`Another of your pages that shows what happens here, usually one only your team can open — and how the two connect. It rides the sentence below, so one copy builds both.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.map((n,i)=>(0,l.jsx)(Ao,{link:n,links:e,index:i,targets:t,self:r,onPatch:(e,t)=>c(i,e,t),onBlur:a,onRemove:()=>u(i),taken:o,onCreatePage:s},i)),f&&(0,l.jsx)(`div`,{className:`flex`,children:(0,l.jsx)(n.i,{icon:n.cn,onClick:d,children:`Link another page`})})]})}):(0,l.jsx)(`div`,{className:`flex`,children:(0,l.jsx)(n.i,{icon:n.cn,onClick:d,title:`Another of your pages that shows what happens here — usually one only your team can open`,children:`Link a page`})})}function Mo({page:e,config:t,forms:i,saving:o,onSave:s,addressTaken:c,actions:u,footer:d,isNew:f,quick:p,editing:m,linkTargets:h,onCreateLinkedPage:g,emailOn:_}){let v=e.type===`public`,y=v?`pageName`:`tabName`,b=v?`pageTitle`:`tabTitle`,[x,S]=(0,a.useState)(()=>({...t||{}})),[C,w]=(0,a.useState)(``),[T,E]=(0,a.useState)(``),D=(e,t)=>S(n=>({...n,[e]:t})),O=e=>{S(t=>({...t,...e}));let n={...t||{},...x,...e};delete n._uiKey,s(n)},k=e=>{(t||{})[e]!==x[e]&&O({[e]:x[e]})},A=String(x.route??``).replace(/^\/+/,``),j=()=>{let n=Ki(A);if(!n){w(`Give this page a web address, for example pricing`);return}if(c(e.id,n)){w(`Another page already lives at this address. Pick a different one.`);return}w(``),n===String(t?.route??``).replace(/^\/+/,``)?D(`route`,`/`+n):O({route:`/`+n})},M=String(x.pageWords??``),N=wa(M),P=Ki(N.address)||Ki(A)||Ki(N.name),F=()=>{if(!N.name){E(M.trim()?`Start with the page’s name on a line of its own — Name: Photos`:`Give the page a name — Name: Photos`);return}if(!P){E(`Use a name or an address with a letter or a number in it.`);return}let n=Ki(A);if(P!==n&&c(e.id,P)){E(`Another page already lives at /${P}. Pick a different name or address.`);return}E(``);let r={pageWords:M,[y]:N.name,brief:N.brief,formWish:N.formWish},i=String(x[b]??``).trim();N.heading?r[b]=N.heading:(!i||i===String(t?.[y]??``).trim())&&(r[b]=N.name),!v&&!String(x.iconName??``).trim()&&(r.iconName=oa(N.name)),P!==n&&(r.route=`/`+P),Object.keys(r).some(e=>(t||{})[e]!==r[e])?O(r):S(e=>({...e,...r}))},I=p?P:Ki(A),L={...t||{},...x,...p?{[y]:N.name,brief:N.brief,formWish:N.formWish,...N.heading?{[b]:N.heading}:{}}:{},route:I?`/`+I:``,contentKey:t?.contentKey||I||void 0},R=String(x.form??``),z=ja(x),B=(0,l.jsx)(bo,{images:pa(x),notes:String(x.imageNotes??``),onChange:e=>O({images:e}),onNotes:e=>D(`imageNotes`,e),onBlur:()=>k(`imageNotes`)}),V=n.X().length>0&&(0,l.jsx)(Co,{booking:So(x),audience:e.type,schedules:n.X(),onChange:e=>O({booking:e}),onHow:e=>D(`booking`,{...So(x),how:e}),onBlur:()=>k(`booking`)}),H=!!h&&!!g&&(e.type===`public`||e.type===`user`)&&(0,l.jsx)(jo,{links:ni(x),targets:h,self:{id:e.id,contentKey:String(t?.contentKey||I||``)},taken:e=>c(`__new_linked_page__`,e),onCreatePage:g,onChange:(e,t)=>t?O({links:e}):D(`links`,e),onBlur:()=>k(`links`)}),U=(0,l.jsxs)(l.Fragment,{children:[d?.(L),(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 pt-2 border-t border-[var(--panel-border)]/60`,children:[(0,l.jsx)(n.l,{saving:o}),(0,l.jsx)(`div`,{className:`flex flex-wrap items-center gap-2 ml-auto`,children:u})]})]});if(m)return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-5`,children:[(0,l.jsx)(n.m,{label:`Describe what you would like to change`,hint:`In your own words. Anything you do not mention stays as it is.`,value:x.pageChange??``,onChange:e=>D(`pageChange`,e),onBlur:()=>k(`pageChange`),placeholder:`Show the albums three to a row, put a search box above them, and take the prices off.`}),U]});if(p){let e=Ta(v,n.X().length>0);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-5`,children:[(0,l.jsx)(n.m,{label:`Describe the page`,hint:f?`One box for everything, a line each — its name first. The page is created as soon as you leave the box${P?` — it will live at /${P}`:``}. Whatever you skip, your assistant decides.`:`One box for everything, a line each — its name first${P?`; it lives at /${P}`:``}. Whatever you skip, your assistant decides. Open the row again for every setting.`,value:M,onChange:e=>{D(`pageWords`,e),T&&E(``)},onBlur:F,error:T,placeholder:e,rows:e.split(`
|
|
25
|
-
`).length}),B,U]})}return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-5`,children:[(0,l.jsx)(n.h,{label:`Web address`,hint:`Where this page lives, e.g. /photos`,prefix:`/`,value:A,onChange:e=>{D(`route`,e),C&&w(``)},onBlur:j,error:C,placeholder:`photos`}),(0,l.jsx)(n.h,{label:v?`Name in the menu`:`Name in the dashboard`,hint:v?`What visitors see in the site menu.`:`What people see in the dashboard menu.`,value:x[y]??``,onChange:e=>D(y,e),onBlur:()=>k(y),placeholder:`Photos`}),(0,l.jsx)(n.h,{label:`Page heading`,hint:`The big heading people read at the top of the page.`,value:x[b]??``,onChange:e=>D(b,e),onBlur:()=>k(b),placeholder:`Our photos`}),!v&&(0,l.jsx)(r._,{label:`Icon`,hint:`Shown next to the name in the dashboard menu.`,value:x.iconName??``,onChange:e=>O({iconName:e})}),!v&&(0,l.jsx)(n.d,{label:`Starting layout`,hint:`What the page starts as. Your assistant fills in the rest when you ask.`,value:na.some(e=>e.value===x.template)?x.template:`none`,onChange:e=>O({template:e}),options:na,allowEmpty:!1}),(0,l.jsx)(n.d,{label:`Form`,hint:`Answers arrive in your Inbox. Your assistant builds it with the page.`,value:z?Ya:R,onChange:e=>O(e===`__new__`?{form:Ya}:{form:e,formIsNew:!1}),options:[{value:Ya,label:`A new form made for this page`},...i.map(e=>({value:e,label:Ja(e)}))],placeholder:`No form`}),(z||!!R)&&(0,l.jsx)(n.m,{label:z?`What should the form ask, and what happens after?`:`How should the form work on this page?`,hint:z?`The questions in your own words, and what the person sees once they have sent it. Where it goes and what its button says, your assistant decides.`:`Optional — where it belongs on the page and what happens after, in your own words.`,value:x.formWish??``,onChange:e=>D(`formWish`,e),onBlur:()=>k(`formWish`),placeholder:`Name, email and what they need. After sending, thank them and say I answer within a day.`}),(0,l.jsx)(n.m,{label:`What would you like to see on this page?`,hint:`What your assistant builds — it goes into the sentence below.`,value:x.brief??``,onChange:e=>D(`brief`,e),onBlur:()=>k(`brief`),placeholder:`A photo gallery where I can upload pictures, put them in albums and open one full screen.`}),B,V,_&&(0,l.jsx)(xo,{emails:no(x),audience:e.type,onChange:(e,t)=>t?O({emails:e}):D(`emails`,e),onBlur:()=>k(`emails`)}),H,U]})}function No({page:e,answers:t,saving:i,resetting:o,onSave:s,onReset:c,onCopied:u}){let[d,f]=(0,a.useState)(()=>({...t||{}})),p=(e,t)=>f(n=>({...n,[e]:t})),m=e=>{(t||{})[e]!==d[e]&&s({[e]:d[e]})},h={...t||{},...d},g=La[e.id],_=!_a(h);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-5`,children:[(0,l.jsx)(n.m,{label:g.ask,hint:`In your own words. Everything you do not mention stays as it is.`,value:d.pageWish??``,onChange:e=>p(`pageWish`,e),onBlur:()=>m(`pageWish`),placeholder:g.example}),e.type===`public`&&(0,l.jsx)(bo,{images:pa(d),notes:String(d.imageNotes??``),onChange:e=>{p(`images`,e),s({images:e})},onNotes:e=>p(`imageNotes`,e),onBlur:()=>m(`imageNotes`)}),(0,l.jsx)(r.g,{compact:!0,title:g.title,prompt:Ra(e.id,h),locked:_,onCopied:u}),(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3 pt-1`,children:[(0,l.jsx)(`div`,{children:_a(h)&&c&&(0,l.jsx)(n.i,{icon:n.rn,tone:`danger`,compact:!0,title:`Start again`,busy:o,onClick:c,children:`Reset`})}),(0,l.jsx)(n.l,{saving:i})]})]})}function Po(){let{userRole:e}=r.j(),i=(0,u.useLocation)(),[s,c]=(0,a.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_pages`);if(e)return Vi(JSON.parse(e))}}catch{}return zi}),[d,f]=(0,a.useState)(()=>{try{return sessionStorage.getItem(`fbos_pages_expandedId`)||null}catch{return null}}),p=(0,a.useRef)(d),[m,h]=(0,a.useState)(null),g=e=>{let t=typeof window<`u`?window.location.origin:``;navigator.clipboard?.writeText(`${t}${e.path}`),h(e.id),setTimeout(()=>h(null),2e3)},[_,v]=(0,a.useState)(null),[y,b]=(0,a.useState)(null),[x,S]=(0,a.useState)(!1),[C,w]=(0,a.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_page_configs`);if(e)return JSON.parse(e)}}catch{}return{}}),[T,E]=(0,a.useState)({}),[D,O]=(0,a.useState)(()=>{try{let e=localStorage.getItem(`fbos_swr_page_briefs`);if(e)return JSON.parse(e)}catch{}return{}}),k=(0,a.useRef)(D);(0,a.useEffect)(()=>{k.current=D},[D]),(0,a.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(n.Sr,`sys_configs`,`page_briefs`),e=>{let t=e.exists()?e.data():{};O(t);try{localStorage.setItem(`fbos_swr_page_briefs`,JSON.stringify(t))}catch{}},()=>{}),[]),t.c();let[A,j]=(0,a.useState)(!1);(0,a.useEffect)(()=>{let e=!1;return Ni().then(t=>{e||(Li(t.configured),j(t.configured))}),()=>{e=!0}},[]);let M=async(e,t)=>{let r={...k.current[e]||{},...t};O(t=>({...t,[e]:r})),E(t=>({...t,[e]:!0}));try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,`page_briefs`),{[e]:r},{merge:!0})}catch(e){console.error(`Could not save the page answers`,e)}E(t=>({...t,[e]:!1}))},[N,P]=(0,a.useState)({}),[F,I]=(0,a.useState)({}),[L,R]=(0,a.useState)(null),[z,B]=(0,a.useState)(null),[V,H]=(0,a.useState)(!1),U=(0,a.useRef)(null);(0,a.useEffect)(()=>{function e(e){U.current&&!U.current.contains(e.target)&&S(!1)}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let[ee,W]=(0,a.useState)(new Set),[G,K]=(0,a.useState)(new Set),[q,J]=(0,a.useState)([]),[Y,X]=(0,a.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,a.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.doc)(n.Sr,`sys_configs`,`page_order`),e=>{let t=te(e.exists()&&e.data().order||[]);J(t),W(new Set(t.filter(e=>e.hidden).map(e=>e.id)))}),t=(0,o.onSnapshot)((0,o.doc)(n.Sr,`sys_configs`,`tab_order`),e=>{let t=te(e.exists()&&e.data().order||[]);X(t),K(new Set(t.filter(e=>e.hidden).map(e=>e.id)))});return()=>{e(),t()}},[]),(0,a.useEffect)(()=>{let e=i.pathname.split(`/pages/`)[1]?.split(`/`)[0];e&&!d&&s.some(t=>t.id===e)&&f(e)},[i.pathname,s]),(0,a.useEffect)(()=>{p.current=d;try{d?sessionStorage.setItem(`fbos_pages_expandedId`,d):sessionStorage.removeItem(`fbos_pages_expandedId`)}catch{}},[d]);let ne=(0,a.useRef)(null);(0,a.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,a.useEffect)(()=>{(async()=>{try{let[e,t]=await Promise.all([(0,o.getDocs)((0,o.collection)(n.Sr,`sys_pages`)),(0,o.getDocs)((0,o.collection)(n.Sr,`sys_tabs`))]),i=[`home`,`drive`,`assets`,`contact`,`guide`,`templates`,`setup`,`support`,`theme`,`page_order`,`tab_order`],a=[],s={};e.forEach(e=>{if(!i.includes(e.id)){let t=e.data();a.push({id:e.id,title:t.pageName||t.title||e.id,path:t.route||`/`+e.id,type:`public`,isSystem:!1,enabled:t.enabled!==!1}),s[e.id]=t}}),t.forEach(e=>{if(!i.includes(e.id)){let t=e.data(),n=r.V(t.pageType);a.push({id:e.id,title:t.tabName||t.title||e.id,path:t.route||`/`+e.id,type:n,isSystem:!1,enabled:t.enabled!==!1}),s[e.id]=t}});let l=Zi(),u={...Qi(!0,!0),...Qi(!1,!0)};for(let[e,t]of Object.entries(u)){if(s[e])continue;let n=a.find(e=>e.path===t.path);if(n){n.fromFile=!0;continue}a.push(t),s[e]=l[e]?.config||{}}c(e=>{let t=Vi(e.filter(e=>(e.isSystem||e.id.startsWith(`draft_`))&&e.id!==`drive`)),n=a.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}),w(e=>{let t={...e,...s};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,ie]=(0,a.useState)([`contact`]),[ae,Z]=(0,a.useState)([`support`]);(0,a.useEffect)(()=>{let e=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},r={...t._,...e},i=new Set([`contact`]),a=new Set([`support`]);Object.entries(r).forEach(([e,t])=>{t.formType===`private`?a.add(t.systemName||e):i.add(t.systemName||e)}),(0,o.getDocs)((0,o.collection)(n.Sr,`sys_forms`)).then(e=>{e.docs.forEach(e=>{e.data().formType===`private`?a.add(e.id):i.add(e.id)}),ie(Array.from(i)),Z(Array.from(a))}).catch(e=>{console.warn(`Failed fetching sys_forms in PagesAdmin:`,e),ie(Array.from(i)),Z(Array.from(a))})},[]);let oe=async(e,t,r)=>{if(t.route&&!t.route.startsWith(`/`)&&(t.route=`/`+t.route),!String(t.route||``).replace(/^\/+/,``).trim()){w(n=>({...n,[e]:t}));return}let i=s.find(t=>t.id===e),a=r||i?.type||t.pageType||(e.startsWith(`pub_`)?`public`:void 0),l=a===`public`?`sys_pages`:`sys_tabs`;a&&a!==`public`?t.pageType=a:delete t.pageType;let u=Object.fromEntries(Object.entries(t).filter(([e,t])=>t!==void 0)),d=t.route?qi(t.route):e;u.contentKey||=d,t={...t,contentKey:u.contentKey},u.form===`__new__`&&(u.form=Xa(u),u.formIsNew=!0,t={...t,form:u.form,formIsNew:!0}),E(t=>({...t,[e]:!0,[d]:!0}));try{if(d!==e&&d.trim()!==``&&d!==`draft`){try{let{deleteDoc:t}=await import(`firebase/firestore`);await t((0,o.doc)(n.Sr,l,e))}catch{}await(0,o.setDoc)((0,o.doc)(n.Sr,l,d),u),c(n=>n.map(n=>n.id===e?{...n,id:d,_uiKey:n._uiKey||e,path:t.route,title:t.pageName||t.tabName||t.title||n.title}:n)),p.current===e&&(f(d),window.history.replaceState(null,``,`/pages/${d}`)),b(t=>t===e?d:t),w(n=>{let r={...n};return r[d]=t,delete r[e],r});let r=a===`public`,i=r?`page_order`:`tab_order`,s=r?q:Y;if(!s.some(e=>e.id===d)){let t=[...s.filter(t=>t.id!==e),{id:d,hidden:!1}];try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,i),{order:t})}catch(e){console.error(`Failed to update tab order:`,e)}}}else await(0,o.setDoc)((0,o.doc)(n.Sr,l,e),u),w(n=>({...n,[e]:t})),c(n=>n.map(n=>n.id===e?{...n,path:t.route||n.path,title:t.pageName||t.tabName||t.title||n.title}:n))}catch(t){console.error(`Failed to save ${e} config:`,t)}finally{setTimeout(()=>{E(t=>({...t,[e]:!1,[d]:!1}))},500)}},Q=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};c(e=>[...e,n]),w(e=>({...e,[t]:r})),f(t),b(t),S(!1),setTimeout(()=>{document.getElementById(`page-${t}`)?.scrollIntoView?.({behavior:`smooth`,block:`center`})},100)},ce=e=>e.id.startsWith(`draft_`);if(e!==`admin`)return(0,l.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,l.jsx)(br,{})});let le=async(e,t,r)=>{let i=r===`public`,a=i?`page_order`:`tab_order`,l=i?q:Y,u=(i?ee:G).has(e);c(s.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)(n.Sr,`sys_configs`,a),{order:d})},ue=e=>!!e.fromFile&&(e.type===`public`?q:Y).some(t=>t.id===e.id&&t.removed),de=async(e,t)=>{if(e.type===t)return;let r=e.type;c(n=>n.map(n=>n.id===e.id?{...n,type:t}:n)),E(t=>({...t,[e.id]:!0}));let i=Va(C[e.id],t);try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_tabs`,e.id),i,{merge:!0}),w(n=>n[e.id]?{...n,[e.id]:{...n[e.id],pageType:t}}:n)}catch(t){console.error(`Failed to change the audience of ${e.id}:`,t),c(t=>t.map(t=>t.id===e.id?{...t,type:r}:t))}finally{E(t=>({...t,[e.id]:!1}))}},fe=(e,t)=>{if(!t){if(ce({id:e})){c(t=>t.filter(t=>t.id!==e)),w(t=>{let n={...t};return delete n[e],n}),d===e&&f(null),b(t=>t===e?null:t);return}R(e)}},pe=async()=>{if(L){H(!0);try{let{deleteDoc:e,collection:t,getDocs:r,doc:i,getDoc:a,query:o,where:l}=await import(`firebase/firestore`),{ref:u,deleteObject:p}=await import(`firebase/storage`),m=s.find(e=>e.id===L),h=m?.type===`public`?`sys_pages`:`sys_tabs`;if(h===`sys_tabs`&&m){let s=C[L];if(!s)try{let e=await a(i(n.Sr,`sys_tabs`,L));e.exists()&&(s=e.data())}catch{}let c=(s?.tabName||s?.pageId||L).toLowerCase().replace(/[^a-z0-9]+/g,`_`),d=[`admin_${c}_records`,`mem_${c}_records`,`user_${c}_records`],f={[`admin_${c}_records`]:{prefix:`admin_files`,driveCollection:`admin_files`},[`mem_${c}_records`]:{prefix:`mem_files`,driveCollection:`mem_files`},[`user_${c}_records`]:{prefix:`user_files`,driveCollection:`user_files`}},m=[];for(let i of d)m.push((async()=>{try{let a=await r(t(n.Sr,i)),s=f[i],c=[];for(let i of a.docs){let a=i.data();a.recordType===`file`&&a.downloadURL&&s&&c.push((async()=>{try{let i=`${s.prefix}%2F`,c=a.downloadURL.split(i)[1]?.split(`?`)[0];c&&await p(u(n.wr,`${s.prefix}/${decodeURIComponent(c)}`)).catch(()=>{});let d=await r(o(t(n.Sr,s.driveCollection),l(`downloadURL`,`==`,a.downloadURL)));await Promise.all(d.docs.map(t=>e(t.ref)))}catch(e){console.error(`Error deleting storage file:`,e)}})())}await Promise.all(c),await Promise.all(a.docs.map(t=>e(t.ref)));try{localStorage.removeItem(`fbos_records_${i}`)}catch{}}catch(e){console.error(`Error cleaning up collection ${i}:`,e)}})());for(let i of[`admin_files`,`mem_files`,`user_files`])m.push((async()=>{try{let a=await r(o(t(n.Sr,i),l(`sourceTab`,`==`,c)));await Promise.all(a.docs.map(async t=>{let r=t.data();if(r.downloadURL)try{let e=`${i}%2F`,t=r.downloadURL.split(e)[1]?.split(`?`)[0];t&&await p(u(n.wr,`${i}/${decodeURIComponent(t)}`)).catch(()=>{})}catch{}await e(t.ref)}))}catch{}})());await Promise.all(m)}await e(i(n.Sr,h,L));let g=h===`sys_pages`?`page_order`:`tab_order`,_=h===`sys_pages`?q:Y,{setDoc:v}=await import(`firebase/firestore`),y=m?.fromFile?[..._.filter(e=>e.id!==L),{id:L,hidden:!0,removed:!0}]:_.filter(e=>e.id!==L);await v(i(n.Sr,`sys_configs`,g),{order:y}),c(e=>e.filter(e=>e.id!==L)),d===L&&f(null)}catch(e){console.error(`Error deleting page:`,e)}H(!1),R(null)}},he=async(e,t)=>{if(e.isSystem)return;let r=e.type===`public`,i=r?`page_order`:`tab_order`,a=[...r?q:Y];s.filter(e=>e.type===`public`===r&&!e.isSystem&&!a.some(t=>t.id===e.id)).forEach(e=>a.push({id:e.id,hidden:!1}));let c=Xi(a,e.id,t,r?`home`:void 0);if(c){r?J(c):X(c);try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,i),{order:c})}catch(e){console.error(`Failed to reorder pages:`,e)}}},ge=(e,t)=>{let n=t.replace(/[^a-zA-Z0-9_-]/g,`_`).toLowerCase();return s.some(r=>{if(r.id===e)return!1;let i=String(C[r.id]?.route??r.path??``).replace(/^\/+/,``).toLowerCase();return i!==``&&i===t||r.id===n})},_e=e=>e===`admin`?Tr:e===`internal`?Er:e===`public`?Cr:wr,ve=async()=>{let e=s.find(e=>e.id===z);if(!e){B(null);return}I(t=>({...t,[e.id]:!0}));let t=C[e.id]||{};if(e.isSystem){try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,`page_briefs`),{[e.id]:(0,o.deleteField)()},{merge:!0}),O(t=>{let n={...t};return delete n[e.id],n}),P(t=>({...t,[e.id]:(t[e.id]||0)+1}))}catch(e){console.error(`Failed to clear the page answers`,e)}I(t=>({...t,[e.id]:!1})),B(null);return}let r=Ba(e,t);if(r)try{await(0,o.deleteDoc)((0,o.doc)(n.Sr,e.type===`public`?`sys_pages`:`sys_tabs`,e.id)),w(t=>({...t,[e.id]:r})),c(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 oe(e.id,{..._e(e.type),...t.contentKey?{contentKey:t.contentKey}:{}});I(t=>({...t,[e.id]:!1})),B(null)},ye=s.filter(e=>!e.isSystem&&!ce(e)&&!ue(e)).map(e=>({id:e.id,title:e.title,path:e.path,brief:String(C[e.id]?.brief||``),config:C[e.id],audience:e.type})),be=async e=>{let{id:t,config:n,isPublic:r}=Ji(e);return await Yi(e),c(r=>r.some(e=>e.id===t)?r:[...r,{id:t,title:e.name,path:n.route,type:e.type,isSystem:!1,enabled:!0}]),w(e=>({...e,[t]:n})),(r?J:X)(e=>e.some(e=>e.id===t)?e:[...e,{id:t,hidden:!1}]),t},xe=[{id:`public`,title:`Anyone`,icon:n.Mn,description:`On your website and in the site menu — open to everyone, signed in or not.`,filter:e=>e.type===`public`},{id:`user`,title:`Signed-in users`,icon:n.vn,description:`In the dashboard for every signed-in person — each sees only their own.`,filter:e=>e.type===`user`},{id:`internal`,title:`Your team`,icon:n.In,description:`In the dashboard for admins and your team — invisible to everyone else.`,filter:e=>e.type===`internal`},{id:`admin`,title:`Admins only`,icon:n.Qt,description:`In the dashboard, for admins alone.`,filter:e=>e.type===`admin`}];return(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:`Your Pages`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/pages`]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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,l.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,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(`div`,{className:`flex items-center min-h-[40px]`,children:(0,l.jsx)(`h2`,{className:`text-lg md:text-xl font-extrabold text-foreground tracking-tight leading-tight truncate`,children:`Your pages`})}),(0,l.jsxs)(`p`,{className:`text-[12.5px] md:text-[14px] font-medium text-foreground/60 leading-relaxed max-w-3xl`,children:[(0,l.jsx)(`span`,{className:`md:hidden`,children:`Add a page, say what goes on it, paste the sentence into your assistant.`}),(0,l.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,l.jsx)(`div`,{className:`relative z-50 shrink-0 flex items-center gap-1`,children:(0,l.jsxs)(`div`,{className:`relative`,children:[(0,l.jsx)(t.h,{variant:`secondary`,onClick:()=>S(!x),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,l.jsx)(n.cn,{className:`w-4 h-4 text-foreground/60 group-hover:text-foreground transition-colors`})}),(0,l.jsx)(n.At,{children:x&&(0,l.jsxs)(n.kt.div,{ref:U,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,l.jsx)(`span`,{className:`px-3 pt-1 pb-2 text-[10px] font-bold uppercase tracking-widest text-foreground/40`,children:`Add a page for`}),[`public`,`user`,`internal`,`admin`].map(e=>(0,l.jsx)(`button`,{onClick:()=>Q(e),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:Hi[e]},e))]})})]})})]}),(0,l.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:xe.map((e,t)=>{let i=s.filter(e.filter).filter(e=>!ue(e)),a=e.id===`public`?q:Y,o=i.sort((e,t)=>{if(e.id===`home`)return-1;if(t.id===`home`)return 1;let n=a.findIndex(t=>t.id===e.id),r=a.findIndex(e=>e.id===t.id);return n===-1&&r===-1?0:n===-1?1:r===-1?-1:n-r}),c=e.icon,p=e=>e.type===`public`?ee.has(e.id):G.has(e.id),h=o.filter(e=>!p(e)),x=o.filter(e=>p(e)),S=(t,i)=>{let a=t.isSystem?La[t.id]:void 0,o=d===t.id,c=ce(t),p=Ui({draft:c,hidden:i}),h=!t.isSystem||!!a,x=!t.isSystem&&!c,S=o&&_===t.id,w=t.isSystem?[]:yo(t,C[t.id],s,C),E=e=>{f(t.id),v(e===`edit`?t.id:null),window.history.replaceState(null,``,`/pages/${t.id}`)},O=()=>{f(null),v(null),b(null),window.history.replaceState(null,``,`/pages`)};return(0,l.jsxs)(`div`,{id:`page-${t.id}`,onClick:()=>{h&&(o?O():E(`settings`))},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`:``} ${i?`opacity-60 bg-foreground/[0.01] border-[var(--panel-border)]/50`:`border-transparent hover:border-[var(--panel-border)]`}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between w-full gap-2 sm:gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2 flex-1 min-w-0`,children:[!t.isSystem&&!c&&(0,l.jsxs)(`div`,{className:`max-sm:hidden sm:flex flex-col shrink-0`,onClick:e=>e.stopPropagation(),children:[(0,l.jsx)(`button`,{type:`button`,title:`Move up`,"aria-label":`Move ${t.title} up`,onClick:()=>he(t,`up`),className:Ha,children:(0,l.jsx)(n.Qn,{className:`w-3.5 h-3.5`})}),(0,l.jsx)(`button`,{type:`button`,title:`Move down`,"aria-label":`Move ${t.title} down`,onClick:()=>he(t,`down`),className:Ha,children:(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5`})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,l.jsx)(`h3`,{className:`text-[14.5px] font-bold text-foreground tracking-tight truncate`,children:t.title}),!t.isSystem&&(0,l.jsx)(Ka,{status:p}),t.fromFile&&(0,l.jsxs)(`span`,{className:Ua,title:`Your assistant wrote this one as a file. Delete hides it and gives you the sentence that removes its files.`,children:[(0,l.jsx)(n.Fn,{className:`w-3 h-3`}),` Written as a file`]}),w.length>0&&(0,l.jsxs)(`span`,{className:Ua,title:`This page shows what happens on ${w.join(`, `)}.`,children:[(0,l.jsx)(n.Sn,{className:`w-3 h-3`}),` Linked to `,w.join(`, `)]})]}),c&&(0,l.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 truncate`,children:`Not saved yet — give it a name`})]})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2 shrink-0`,children:[!t.isSystem&&t.type!==`public`&&!c&&(0,l.jsx)(`div`,{className:`max-sm:hidden`,children:(0,l.jsx)($i,{value:t.type,busy:T[t.id],onChange:e=>de(t,e)})}),x&&(0,l.jsx)(n.i,{icon:n.It,compact:!0,title:`Edit this page with your assistant`,className:S?`text-accent border-accent/40 bg-accent/10 max-sm:border-transparent max-sm:bg-accent/10`:``,onClick:e=>{e.stopPropagation(),E(S?`settings`:`edit`)},children:`Edit with AI`}),!Bi.has(t.id)&&!c&&(0,l.jsx)(n.i,{icon:i?n.In:n.Ln,compact:!0,title:i?`Show this page`:`Hide this page`,onClick:e=>{e.stopPropagation(),le(t.id,t.isSystem,t.type)},children:i?`Show`:`Hide`}),h?(0,l.jsx)(`div`,{className:`p-1.5 transition-transform duration-300 text-foreground/40 shrink-0 ${o?`rotate-180`:``}`,children:(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5`})}):(0,l.jsx)(`div`,{className:`w-[24px] shrink-0`})]})]}),t.path&&o&&(0,l.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 mt-1.5`,onClick:e=>e.stopPropagation(),children:[(0,l.jsx)(u.Link,{to:t.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:qa(t.path)}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>g(t),title:`Copy this link`,"aria-label":`Copy the link to ${t.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:m===t.id?(0,l.jsx)(n.nr,{className:`w-3.5 h-3.5 text-accent`}):(0,l.jsx)(n.Un,{className:`w-3.5 h-3.5`})})]}),(0,l.jsxs)(n.At,{children:[o&&a&&(0,l.jsx)(n.kt.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,l.jsx)(No,{page:t,answers:D[t.id],saving:T[t.id],resetting:F[t.id],onSave:e=>M(t.id,e),onReset:()=>B(t.id),onCopied:O},`${t.id}:${N[t.id]||0}`)}),o&&!t.isSystem&&C[t.id]&&(0,l.jsxs)(n.kt.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:[!c&&(0,l.jsxs)(`div`,{className:`sm:hidden flex items-center justify-between gap-3 mb-5`,children:[(0,l.jsx)(`span`,{className:`text-[12px] font-semibold text-foreground/55`,children:`Spot in the menu`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,l.jsx)(n.i,{icon:n.dr,title:`Move up`,onClick:()=>he(t,`up`),children:`Up`}),(0,l.jsx)(n.i,{icon:n.hr,title:`Move down`,onClick:()=>he(t,`down`),children:`Down`})]})]}),!t.isSystem&&t.type!==`public`&&!c&&(0,l.jsxs)(`div`,{className:`sm:hidden flex items-center justify-between gap-3 mb-5`,children:[(0,l.jsx)(`span`,{className:`text-[12px] font-semibold text-foreground/55`,children:`Who can open this page`}),(0,l.jsx)($i,{value:t.type,busy:T[t.id],onChange:e=>de(t,e)})]}),(0,l.jsx)(Mo,{page:t,config:C[t.id],forms:t.type===`public`?re:ae,saving:T[t.id],isNew:c,quick:y===t.id,editing:S,onSave:e=>oe(t.id,e),addressTaken:ge,linkTargets:ye,onCreateLinkedPage:be,emailOn:A,footer:e=>S?(0,l.jsx)(r.g,{compact:!0,title:`Copy this to change the page`,prompt:Ia(t,e),locked:!!Fa(e),onCopied:O}):(0,l.jsx)(r.g,{compact:!0,title:`Then copy this into your assistant’s chat`,description:x?`This one builds the page from scratch. If it has been built already, switch to Edit with AI so your assistant changes it instead of starting over.`:void 0,prompt:ya(t,e,ye),locked:!!da(t,e,ye),onCopied:O}),actions:(0,l.jsxs)(l.Fragment,{children:[za(C[t.id],Ba(t,C[t.id])??_e(t.type))&&(0,l.jsx)(n.i,{icon:n.rn,tone:`danger`,compact:!0,title:`Reset this page`,busy:F[t.id],onClick:()=>B(t.id),children:`Reset`}),!t.isSystem&&(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Delete this page`,onClick:()=>fe(t.id,t.isSystem),children:`Delete`})]})},t._uiKey||t.id)]})]})]},`${e.id}-${t._uiKey||t.id}`)};return(0,l.jsx)(n.kt.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex flex-col relative`,children:(0,l.jsx)(n.u,{icon:c,title:e.title,description:e.description,children:o.length===0?(0,l.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,l.jsx)(n.i,{icon:n.cn,onClick:()=>Q(e.id),children:`Add a page`}),(0,l.jsxs)(`p`,{className:`text-[12.5px] text-foreground/55 font-medium leading-relaxed`,children:[(0,l.jsx)(`span`,{className:`sm:hidden`,children:ta}),(0,l.jsx)(`span`,{className:`max-sm:hidden`,children:ea})]})]}):(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[h.map(e=>S(e,!1)),(0,l.jsx)(`div`,{className:`flex items-center rounded-2xl border border-dashed border-[var(--panel-border)] px-5 py-3`,children:(0,l.jsx)(n.i,{icon:n.cn,onClick:()=>Q(e.id),children:`Add a page`})}),x.length>0&&(0,l.jsxs)(`details`,{className:`mt-4 group/details`,children:[(0,l.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,l.jsx)(n.tr,{className:`w-3.5 h-3.5 group-open/details:-rotate-180 transition-transform`}),`Hidden pages (`,x.length,`)`]}),(0,l.jsx)(`div`,{className:`flex flex-col gap-4 mt-4`,children:x.map(e=>S(e,!0))})]})]})})},e.id)})})]})]}),(0,l.jsx)(me,{isOpen:!!L,onCancel:()=>R(null),onConfirm:pe,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:V}),(0,l.jsx)(me,{isOpen:!!z,onCancel:()=>B(null),onConfirm:ve,title:s.find(e=>e.id===z)?.isSystem?`Start this page again?`:`Reset this page?`,message:(()=>{let e=s.find(e=>e.id===z);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&&Ba(e,C[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:s.find(e=>e.id===z)?.isSystem?`Start again`:`Reset page`,isProcessing:!!z&&!!F[z]})]})}var Fo=new Set([`contact`,`support`]),Io=[{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`}],Lo={value:`schedule`,label:`A time to book`},Ro={age:`Age`},zo=e=>[...Io,Lo].find(t=>t.value===e)?.label||Ro[e||``]||`Short text`,Bo=(e,t=!1)=>{let n=t||e===`schedule`?[...Io,Lo]:Io;return n.some(t=>t.value===e)||!e?n:[...n,{value:e,label:zo(e)}]},Vo=(e,t)=>{let r=n.mt(e).map(e=>{let r=t.find(t=>t.id===e);return r?n.st(r):``}).filter(Boolean);return r.length?r.join(`, `):`nothing picked yet`},Ho={public:`Anyone`,private:`Signed-in users`},Uo=e=>(e||``).toLowerCase().trim().replace(/[^a-z0-9]+/g,`_`).replace(/^_+|_+$/g,``),Wo=(e,t)=>{if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}_${n}`);)n++;return`${e}_${n}`},Go=(e,t,n)=>{if(!(!e.name||e.name===Uo(e.label||``)))return e.name;let r=Uo(t);return r?Wo(r,n.filter(t=>t!==e).map(e=>e.name)):``},Ko=()=>({name:``,type:`text`,label:``,placeholder:``,required:!1}),qo={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.`},Jo=`(max-width: 767px)`,Yo=()=>typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(Jo).matches;function Xo(){let[e,t]=(0,a.useState)(Yo);return(0,a.useEffect)(()=>{if(typeof window>`u`||typeof window.matchMedia!=`function`)return;let e=window.matchMedia(Jo),n=()=>t(e.matches);return n(),e.addEventListener?.(`change`,n),()=>e.removeEventListener?.(`change`,n)},[]),e}function Zo({choices:e,onChange:t}){return(0,l.jsx)(n.r,{label:`Choices`,hint:`The options people pick from.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.length===0&&(0,l.jsx)(`span`,{className:`text-[12px] text-foreground/40 font-medium px-1`,children:`No choices yet — add the first one.`}),e.map((r,i)=>(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`input`,{type:`text`,value:r,"aria-label":`Choice ${i+1}`,placeholder:`e.g. Under 1,000`,onChange:n=>t(e.map((e,t)=>t===i?n.target.value:e)),className:n.o}),(0,l.jsx)(n.i,{icon:n.Pt,tone:`danger`,title:`Remove choice ${i+1}`,onClick:()=>t(e.filter((e,t)=>t!==i)),children:`Remove`})]},i)),(0,l.jsx)(`div`,{children:(0,l.jsx)(n.i,{icon:n.cn,onClick:()=>t([...e,``]),children:`Add choice`})})]})})}function Qo(){let{userRole:e}=r.j(),i=(0,u.useNavigate)(),s=n.br(),c=()=>{let e=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},n={...t._,contact:s?.defaultConfigs?.contactForm||t._.contact,support:s?.defaultConfigs?.supportForm||t._.support};for(let[t,r]of Object.entries(e))n[t]=r;return n},[d,f]=(0,a.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_forms`);if(e)return JSON.parse(e)}let e={...t._,contact:s?.defaultConfigs?.contactForm||t._.contact,support:s?.defaultConfigs?.supportForm||t._.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{}}}),[p,m]=(0,a.useState)(()=>!(typeof window<`u`&&localStorage.getItem(`fbos_swr_forms`))),[h,g]=(0,a.useState)({}),[_,v]=(0,a.useState)(null),[y,b]=(0,a.useState)(new Set),x=Xo(),{schedules:S}=t.c(),[C,w]=(0,a.useState)({}),[T,E]=(0,a.useState)(null),[D,O]=(0,a.useState)(!1),[k,A]=(0,a.useState)({}),j=(0,a.useRef)({}),M=(e,t)=>{j.current={...j.current,[e]:t},A(j.current)};(0,a.useEffect)(()=>{N()},[]);let N=async()=>{try{m(!0);let e=await(0,o.getDocs)((0,o.collection)(n.Sr,`sys_forms`)),t={},r=new Set;e.forEach(e=>{if(e.id!==`pubForm`&&e.id!==`userForm`){let n=e.data();n._uiKey=d[e.id]?._uiKey||n._uiKey||Math.random().toString(36).substring(7),t[e.id]=n,r.add(e.id)}}),b(r);try{await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_forms`,`pubForm`)),await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_forms`,`userForm`))}catch{}let i=c();for(let[e,n]of Object.entries(i))if(!t[e]){let r={...n};r._uiKey=d[e]?._uiKey||Math.random().toString(36).substring(7),t[e]=r}else if(t[e]._uiKey=d[e]?._uiKey||t[e]._uiKey||Math.random().toString(36).substring(7),!t[e].fields||t[e].fields.length===0){let n=i[e];t[e].fields=n.fields||[]}let a={};for(let e of Object.keys(i))t[e]&&(a[e]=t[e]);for(let e of Object.keys(t))a[e]||(a[e]=t[e]);let s=window.location.pathname.split(`/forms/`)[1]?.split(`/`)[0];s&&a[s]&&w({[s]:!0}),j.current={},A({}),f(a),typeof window<`u`&&localStorage.setItem(`fbos_swr_forms`,JSON.stringify(a))}catch(e){console.error(`Failed to load forms:`,e)}finally{m(!1)}},P=async(e,t)=>{let r={...t};d[e]?._uiKey&&(r._uiKey=d[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()!==``){f(t=>{let n={};for(let a of Object.keys(t))a===e?n[i]=r:n[a]=t[a];return n}),C[e]&&w(t=>{let n={};for(let r of Object.keys(t))r===e?n[i]=t[r]:n[r]=t[r];return n}),g(e=>({...e,[i]:!0}));try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_forms`,i),r),await(0,o.deleteDoc)((0,o.doc)(n.Sr,`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(()=>{g(e=>({...e,[i]:!1}))},500)}}else{f(t=>({...t,[e]:r})),g(t=>({...t,[e]:!0}));try{await(0,o.setDoc)((0,o.doc)(n.Sr,`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(()=>{g(t=>({...t,[e]:!1}))},500)}}},F=(e,t,n)=>M(e,{...t,...n}),I=(e,t,n)=>{let r={...t,...n};M(e,r),P(e,r)},L=e=>{let t=j.current[e];t&&P(e,t)},R=(e,t,n)=>I(e,t,{fields:n}),z=async e=>{if(!Fo.has(e)){O(!0);try{await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_forms`,e)),f(t=>{let n={...t};return delete n[e],n}),i(`/forms`)}catch(e){console.error(`Failed to delete form`,e)}finally{O(!1),E(null)}}},B=async e=>{if(!y.has(e)){E(null);return}O(!0);let t=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},r=Fo.has(e)||!!t[e]||!!s?.defaultConfigs?.[e]||!!s?.defaultConfigs?.[`${e}Form`];try{r?(g(t=>({...t,[e]:!0})),await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_forms`,e)),localStorage.removeItem(`fbos_form_${e}`),localStorage.removeItem(`fbos_custom_form_${e}`),await N(),setTimeout(()=>g(t=>({...t,[e]:!1})),500)):await P(e,c().contact||c().support)}catch(e){console.error(`Reset failed:`,e)}finally{O(!1),E(null)}};if(e!==`admin`)return(0,l.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,l.jsx)(br,{})});let V=e=>{w(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})},H=Object.keys(C).find(e=>C[e]),U=(e,t,r,i,a)=>{let o=(n,r)=>{let o=a.map((e,t)=>t===i?{...e,...n}:e);r?R(e,t,o):F(e,t,{fields:o})},s=n=>{let o=n===`schedule`?{type:n,look:`compact`,schedules:[]}:n===`select`?{type:n,options:r.options||[]}:{type:n};R(e,t,a.map((e,t)=>{if(t!==i)return e;let r={...e,...o};return n!==`schedule`&&(delete r.members,delete r.schedules,delete r.look),r}))},c=n=>{let r=i+n;if(r<0||r>=a.length)return;let o=[...a];[o[i],o[r]]=[o[r],o[i]],R(e,t,o)},u=r.type!==`checkbox`&&r.type!==`select`&&r.type!==`date`&&r.type!==`file`&&r.type!==`schedule`;return(0,l.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,l.jsxs)(`div`,{className:`flex items-center justify-between gap-2 flex-wrap`,children:[(0,l.jsxs)(`span`,{className:`text-[13px] font-bold text-foreground`,children:[`Question `,i+1,r.type===`schedule`&&(0,l.jsxs)(`span`,{className:`font-medium text-foreground/50`,children:[` · A time to book — `,Vo(r,S)]})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,l.jsx)(n.i,{icon:n.dr,disabled:i===0,title:`Move up`,onClick:()=>c(-1),children:`Up`}),(0,l.jsx)(n.i,{icon:n.hr,disabled:i===a.length-1,title:`Move down`,onClick:()=>c(1),children:`Down`}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,title:`Remove question ${i+1}`,onClick:()=>R(e,t,a.filter((e,t)=>t!==i)),children:`Remove`})]})]}),(0,l.jsx)(n.h,{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=>o({label:e,name:Go(r,e,a)},!1),onBlur:()=>L(e)}),(0,l.jsx)(n.d,{label:`Kind of answer`,hint:`Sets the box people type into and what counts as a valid answer.`,value:r.type||`text`,options:Bo(r.type,S.length>0),allowEmpty:!1,onChange:s}),(0,l.jsx)(n._,{label:`Required`,hint:`On means the form cannot be sent until this is answered.`,hintWideOnly:!0,enabled:!!r.required,onChange:e=>o({required:e},!0)}),r.type===`select`&&(0,l.jsx)(Zo,{choices:r.options||[],onChange:e=>o({options:e},!0)}),r.type===`schedule`&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.r,{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:n.mt(r).length?void 0:`Pick at least one schedule`,children:(0,l.jsx)(Fi,{schedules:S,selected:n.mt(r),onPick:e=>{o({schedules:n.tt(n.mt(r),e,S)},!0)}})}),(0,l.jsx)(n.d,{label:`How should the booking look?`,value:r.look||`compact`,options:n.y,allowEmpty:!1,onChange:e=>o({look:e===`calendar`?`calendar`:`compact`},!0)})]}),r.type===`file`&&(0,l.jsx)(n.h,{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=>o({placeholder:e},!1),onBlur:()=>L(e)}),r.type===`currency`&&(0,l.jsx)(n.h,{label:`Currency symbol`,hint:`Shown inside the box, before the amount.`,value:r.currencySymbol||``,placeholder:`$`,onChange:e=>o({currencySymbol:e},!1),onBlur:()=>L(e)}),u&&(0,l.jsx)(n.h,{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=>o({placeholder:e},!1),onBlur:()=>L(e)})]},i)},ee=(e,t)=>{let r=k[e]||t,i=Fo.has(e),a=r.formType||`public`,o=r.fields||[],s=y.has(e);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsxs)(n.u,{icon:n.Ht,title:`Basics`,description:`What people see at the top of this form and on its button.`,children:[(0,l.jsx)(n.h,{label:`Form name`,hint:`The heading at the top of the form.`,value:r.title||``,placeholder:`e.g. Get in touch`,onChange:t=>F(e,r,{title:t}),onBlur:()=>L(e)}),(0,l.jsx)(n.h,{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=>F(e,r,{buttonName:t,submitText:t}),onBlur:()=>L(e)})]}),(0,l.jsx)(n.u,{icon:n.Rt,title:`Who it is for`,description:`Who can fill this in, and where their answers land.`,children:(0,l.jsx)(n.d,{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:a,allowEmpty:!1,disabled:!0,options:[{value:`public`,label:`Anyone`},{value:`private`,label:`Signed-in users`}],onChange:t=>I(e,r,{formType:t})})}),(0,l.jsx)(n.u,{icon:n.tn,title:`After sending`,description:`What happens the moment someone sends this form.`,children:(0,l.jsx)(n.h,{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=>F(e,r,{redirectTo:t}),onBlur:()=>L(e)})}),(0,l.jsxs)(n.u,{icon:n.bn,title:`Questions`,description:`Everything this form asks for, in the order people answer it.`,actions:(0,l.jsx)(n.i,{icon:n.cn,compact:!0,title:`Add a question`,onClick:()=>R(e,r,[...o,Ko()]),children:`Add question`}),children:[o.length===0?(0,l.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.`}):o.map((t,n)=>U(e,r,t,n,o)),o.length>0&&(0,l.jsx)(`div`,{className:`flex justify-start`,children:(0,l.jsx)(n.i,{icon:n.cn,onClick:()=>R(e,r,[...o,Ko()]),children:`Add question`})})]}),(s||!i)&&(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 pt-1`,children:[s&&(0,l.jsx)(n.i,{icon:n.rn,tone:`danger`,compact:!0,title:`Reset this form`,onClick:()=>E({kind:`reset`,id:e}),children:`Reset this form`}),!i&&(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Delete this form`,onClick:()=>E({kind:`delete`,id:e}),children:`Delete this form`})]})]})};return(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:`Forms`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/forms`,H?`/${H}`:``]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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,l.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,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-lg md:text-xl font-extrabold text-foreground tracking-tight leading-tight md:leading-7`,children:`Your forms`}),(0,l.jsxs)(`p`,{className:`text-[12.5px] md:text-[14px] font-medium text-foreground/60 mt-1 md:mt-2 leading-relaxed`,children:[(0,l.jsx)(`span`,{className:`md:hidden`,children:`Look a form over and touch it up. Answers arrive in your Inbox.`}),(0,l.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,l.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(d).length===0&&!p?(0,l.jsx)(`div`,{className:`flex flex-col gap-4`,children:(0,l.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,l.jsx)(n.an,{className:`w-6 h-6 text-foreground/40`}),(0,l.jsx)(`p`,{className:`text-[13px] font-bold text-foreground/60`,children:`You have no forms yet.`}),(0,l.jsx)(`p`,{className:`text-[12.5px] text-foreground/55 font-medium leading-relaxed text-center max-w-md`,children:qo.firstForm})]})}):(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsx)(n.At,{children:Object.entries(d).map(([e,t])=>{let r=k[e]||t,i=C[e],a=h[e],o=(r.fields||[]).length;return(0,l.jsxs)(n.kt.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},exit:{opacity:0,y:-12},transition:{duration:.35,ease:`easeOut`},onClick:()=>V(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 ${i?`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,l.jsxs)(`div`,{className:`flex flex-row justify-between w-full gap-2 ${x?`items-start`:`items-center`}`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-1 min-w-0 flex-1 pr-2 sm:pr-4`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`h3`,{className:`text-[14px] font-bold text-foreground break-words ml-1 leading-snug`,children:r.title||`Untitled form`}),a&&(0,l.jsx)(n.yn,{className:`w-3 h-3 animate-spin text-accent ml-2 shrink-0`})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 mt-1.5 ml-1`,children:[(0,l.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,l.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full shrink-0 ${r.formType===`private`?`bg-blue-500`:`bg-emerald-500`}`}),Ho[r.formType||`public`]]}),(0,l.jsx)(`span`,{className:`max-sm:hidden text-[11px] font-medium text-foreground/45`,children:o===1?`1 question`:`${o} questions`})]})]}),x?(0,l.jsxs)(`div`,{className:`flex items-center gap-0.5 shrink-0 -mt-0.5 -mr-1.5`,children:[(0,l.jsx)(`button`,{type:`button`,title:`Preview this form`,"aria-label":`Preview this form`,onClick:e=>{e.stopPropagation(),v(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,l.jsx)(n.In,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{type:`button`,title:i?`Close this form`:`Open this form`,"aria-label":i?`Close this form`:`Open this form`,"aria-expanded":i,onClick:t=>{t.stopPropagation(),V(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,l.jsx)(n.tr,{className:`w-4 h-4 transition-transform duration-300 ${i?`rotate-180`:``}`})})]}):(0,l.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,l.jsx)(n.i,{icon:n.In,title:`Preview this form`,onClick:e=>{e.stopPropagation(),v(r)},children:`Preview`}),(0,l.jsx)(`button`,{type:`button`,title:i?`Close this form`:`Open this form`,"aria-label":i?`Close this form`:`Open this form`,"aria-expanded":i,onClick:t=>{t.stopPropagation(),V(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,l.jsx)(n.tr,{className:`w-4 h-4 transition-transform duration-300 ${i?`rotate-180`:``}`})})]})]}),(0,l.jsx)(n.At,{children:i&&(0,l.jsx)(n.kt.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:ee(e,t)})})]},t._uiKey||e)})}),p&&(0,l.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,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin text-accent`}),(0,l.jsx)(`span`,{className:`text-[12px] font-bold text-foreground/50 tracking-wider uppercase select-none`,children:`Loading your forms`})]})]})})]})]}),(0,l.jsx)(me,{isOpen:!!T,onCancel:()=>E(null),onConfirm:()=>{T&&(T.kind===`delete`?z(T.id):B(T.id))},title:T?.kind===`reset`?`Reset this form`:`Delete this form`,message:T?.kind===`reset`?`Undo every change made to ${d[T.id]?.title||T.id} and put it back the way it shipped. Answers already collected are kept.`:`Permanently delete ${T?d[T.id]?.title||T.id:``}. This cannot be undone. Answers already collected are kept.`,confirmText:T?.kind===`reset`?`Reset form`:`Delete form`,isProcessing:D}),_&&(0,l.jsx)(t.t,{formConfig:_,onClose:()=>v(null)})]})}var $o=[{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`}],es=new Set([`home`,`drive`,`assets`,`contact`,`guide`,`templates`,`setup`,`support`,`theme`,`page_order`,`tab_order`]),ts={public:0,user:1,internal:2,admin:3},ns=(e,t)=>{let n=String(e||``).trim();return n?n.startsWith(`/`)?n:`/${n}`:`/${t}`},rs=e=>new Set((Array.isArray(e?.order)?e.order:[]).filter(e=>e&&typeof e==`object`&&e.removed).map(e=>String(e.id)));function is(e,t,n,i,a=S()){let o=[...$o];for(let{id:t,data:n}of e)es.has(t)||o.push({id:t,title:String(n?.pageName||n?.title||t),path:ns(n?.route,t),brief:String(n?.brief||``),config:n,audience:`public`});for(let{id:e,data:n}of t)es.has(e)||o.push({id:e,title:String(n?.tabName||n?.title||e),path:ns(n?.route,e),brief:String(n?.brief||``),config:n,audience:r.V(n?.pageType)});for(let[e,t]of a){if(es.has(e)||o.some(t=>t.id===e))continue;let a=!!t.isPublic;if((a?n:i).has(e))continue;let s=t.config||{},c=ns(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`:r.V(s.pageType)})}return o.sort((e,t)=>(ts[e.audience||`public`]??9)-(ts[t.audience||`public`]??9)||e.title.localeCompare(t.title))}function as(){let[e,t]=(0,a.useState)(null),[r,i]=(0,a.useState)(null),[s,c]=(0,a.useState)(new Set),[l,u]=(0,a.useState)(new Set);return(0,a.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)(n.Sr,`sys_pages`),n=>t(e(n)),()=>t([])),(0,o.onSnapshot)((0,o.collection)(n.Sr,`sys_tabs`),t=>i(e(t)),()=>i([])),(0,o.onSnapshot)((0,o.doc)(n.Sr,`sys_configs`,`page_order`),e=>c(rs(e.exists()?e.data():null)),()=>{}),(0,o.onSnapshot)((0,o.doc)(n.Sr,`sys_configs`,`tab_order`),e=>u(rs(e.exists()?e.data():null)),()=>{})];return()=>r.forEach(e=>e())},[]),e===null||r===null?null:is(e,r,s,l)}function os({product:e,live:t,open:r,onToggle:i,onChange:a,onProceed:o}){let s=t=>a({...e,...t});if(!Ur(e,t))return(0,l.jsx)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] opacity-50`,"aria-disabled":`true`,children:(0,l.jsxs)(`div`,{className:`w-full flex items-center justify-between gap-3 px-4 py-3`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/60 truncate`,children:Kr(e)}),(0,l.jsx)(n.f,{state:`off`,label:`Finish it above first`})]})});let c=ai(e),u=e.kind===`subscription`;return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`button`,{type:`button`,onClick:i,"aria-expanded":r,className:`w-full flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Kr(e)}),(0,l.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,l.jsx)(n.f,{state:c?`off`:`saved`,label:c?`Question left`:`Described`}),(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${r?`rotate-180`:``}`})]})]}),r&&(0,l.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,l.jsx)(n.m,{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=>s({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,l.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5`,children:[(0,l.jsx)(n._,{label:`Email the buyer a confirmation`,hint:`Needs email set up on this screen.`,hintWideOnly:!0,enabled:e.emailReceipt,onChange:e=>s({emailReceipt:e})}),(0,l.jsx)(n._,{label:`Email me when someone buys`,hint:`Needs email set up on this screen.`,hintWideOnly:!0,enabled:e.notifyOwner,onChange:e=>s({notifyOwner:e})})]}),(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:[c?(0,l.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:c}):(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Described — press Proceed to say where it goes.`}),c?(0,l.jsx)(`span`,{}):(0,l.jsx)(n.i,{icon:n.pr,onClick:o,children:`Proceed`})]})]})]})}function ss({products:e,live:t,openId:r,onToggle:i,onChange:a,onProceed:o}){return e===null?(0,l.jsx)(`p`,{className:n.a,children:`Loading your payments…`}):e.length===0?(0,l.jsx)(`p`,{className:`${n.a} 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,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.map(e=>(0,l.jsx)(os,{product:e,live:t,open:r===e.id,onToggle:()=>i(e.id),onChange:a,onProceed:()=>o(e.id)},e.id))})}var cs=[{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 ls({row:e,on:t,onToggle:r}){return(0,l.jsxs)(`button`,{type:`button`,role:`checkbox`,"aria-checked":t,"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,l.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${t?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:t&&(0,l.jsx)(n.nr,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,l.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate min-w-0`,children:e.title}),(0,l.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/40 truncate shrink-0`,children:e.path})]})}function us({product:e,pageRows:t,live:r,open:i,onToggle:a,onChange:o}){let s=t=>o({...e,...t});if(!(Ur(e,r)&&!ai(e)))return(0,l.jsx)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] opacity-50`,"aria-disabled":`true`,children:(0,l.jsxs)(`div`,{className:`w-full flex items-center justify-between gap-3 px-4 py-3`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/60 truncate`,children:Kr(e)}),(0,l.jsx)(n.f,{state:`off`,label:`Describe it above first`})]})});let c=li(e,t);return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`button`,{type:`button`,onClick:a,"aria-expanded":i,className:`w-full flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Kr(e)}),(0,l.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,l.jsx)(n.f,{state:c?`off`:`saved`,label:c?`Where does it go?`:`Placed`}),(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${i?`rotate-180`:``}`})]})]}),i&&(0,l.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,l.jsx)(n.r,{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,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[cs.map(n=>{let r=t.filter(e=>(e.audience||`public`)===n.audience);return r.length?(0,l.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,l.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-widest text-foreground/40 px-1`,children:n.label}),(0,l.jsx)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60 px-2 py-1.5`,children:r.map(t=>(0,l.jsx)(ls,{row:t,on:si(e,t),onToggle:()=>s({pageIds:ci(e,t)})},t.id))})]},n.audience):null}),(0,l.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Pages you make on the`,` `,(0,l.jsx)(u.Link,{to:`/pages`,className:`text-accent font-bold hover:underline`,children:`Pages screen`}),` `,`appear here on their own.`]})]})}),(0,l.jsx)(n.m,{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=>s({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,l.jsx)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:c?(0,l.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:c}):(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Placed — the request under these carries it.`})})]})]})}function ds({products:e,pageRows:t,live:i,openId:a,onToggle:o,onChange:s}){if(e===null||t===null)return(0,l.jsx)(`p`,{className:n.a,children:`Loading your pages…`});if(e.length===0)return(0,l.jsx)(`p`,{className:`${n.a} px-1`,children:`Nothing here yet. Each payment you describe above appears here with one question: which pages it goes on.`});let c=ui(e,t,i),u=c?``:yi(e,t,i);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.map(e=>(0,l.jsx)(us,{product:e,pageRows:t,live:i,open:a===e.id,onToggle:()=>o(e.id),onChange:s},e.id))}),(0,l.jsx)(r.g,{title:`Copy this to wire everything in`,prompt:u,locked:u===``}),c?(0,l.jsx)(`span`,{className:n.a,children:c}):(0,l.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 on the Pages screen, with Edit with AI.`})]})}function fs({title:e,path:t,hint:r}){let[i,o]=(0,a.useState)(!1),s=n.M(t);return(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-2.5 rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/80 truncate`,children:e}),(0,l.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 truncate`,children:r||s})]}),(0,l.jsx)(n.i,{icon:i?n.nr:n.Un,compact:!0,title:`Copy the link to ${e}`,onClick:()=>{try{navigator.clipboard?.writeText(s)?.catch(()=>{})}catch{}o(!0),setTimeout(()=>o(!1),1500)},children:i?`Copied`:`Copy link`})]})}var ps=e=>Ki(`pay-${Gr(e)}`)||`pay-${e.id}`,ms=e=>{let t=Nr(e).map(e=>e.amount.trim()).filter(Boolean).join(` + `);return`${Gr(e)}${t?` — ${t}`:``}`};function hs(e,t,n){return[ya(t,n),`This page is the page of my payment link for ${Gr(e)} — everyone I send ${t.path} to lands here and pays here.`,...$r(e,t.path)].join(`
|
|
26
|
-
`)}function gs({product:e,open:t,onToggle:i,onChange:o,onRemove:s,onCustomise:c}){let[u,d]=(0,a.useState)(!1),[f,p]=(0,a.useState)(!1),[m,h]=(0,a.useState)(``),[g,_]=(0,a.useState)(``),v=e.customPath.trim(),y=v?v.startsWith(`/`)?v:`/${v}`:n.et(e.id);return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2 pr-3`,children:[(0,l.jsxs)(`button`,{type:`button`,onClick:i,"aria-expanded":t,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:ms(e)}),(0,l.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,l.jsx)(n.f,{state:v?`saved`:`off`,label:v?`Your own page`:`Ready-made page`}),(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${t?`rotate-180`:``}`})]})]}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Remove the link to ${Gr(e)}`,onClick:()=>d(!0),children:`Remove`})]}),(0,l.jsx)(me,{isOpen:u,title:`Remove the link to ${Gr(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:()=>d(!1),onConfirm:()=>{d(!1),s()}}),t&&(0,l.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,l.jsx)(n.r,{label:`The link`,hint:`Send it to anyone. The page wears your theme and your app's name.`,children:(0,l.jsx)(fs,{title:Gr(e),path:y})}),(0,l.jsx)(n.h,{label:`What is it called?`,value:Nr(e)[0]?.name||``,onChange:t=>o({...e,items:[{...Nr(e)[0]||{amount:``},name:t},...Nr(e).slice(1)]}),placeholder:`A one-hour session`}),(0,l.jsx)(n.m,{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,l.jsx)(n.h,{label:`The price`,value:Nr(e)[0]?.amount||``,onChange:t=>o({...e,items:[{...Nr(e)[0]||{name:``},amount:t},...Nr(e).slice(1)]}),placeholder:`25`,error:Nr(e)[0]?.amount.trim()&&Pr(Nr(e)[0].amount)===null?`Just a number, like 25.`:void 0}),!v&&!f&&!m&&(0,l.jsx)(n.i,{icon:n.It,onClick:()=>p(!0),children:`Customise this page`}),(f||m)&&(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-4`,children:[(0,l.jsx)(n.m,{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}),g&&(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:g}),m?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(r.g,{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:m}),(0,l.jsx)(n._,{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?`/${ps(e)}`:``})})]}):(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(n.i,{icon:n.It,disabled:!e.customNote.trim(),onClick:async()=>{_(``);let e=await c();if(typeof e==`string`){_(e);return}h(e.prompt)},children:`Make the page`}),(0,l.jsx)(n.i,{onClick:()=>{p(!1),_(``)},children:`Never mind`})]})]}),v&&!m&&(0,l.jsx)(n._,{label:`The page is built — send people there`,hint:`The link opens ${y}. Change the page on the Pages screen with Edit with AI. Turn this off to go back to the ready-made page.`,enabled:!0,onChange:t=>o({...e,customPath:t?e.customPath:``})})]})]})}function _s({products:e,onChange:t,onRemove:r}){let[i,o]=(0,a.useState)(null),s=e.filter(e=>e.kind===`once`),c=()=>{let e={...Mr(`p_${Date.now().toString(36)}`),kind:`once`,items:[{name:``,amount:``}]};t(e),o(e.id)},u=async e=>{let t=ps(e),n=`Pay — ${Gr(e)}`,r={name:n,address:t,type:`public`,about:e.customNote.trim()};try{await Yi(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}=Ji(r),a={title:n,path:`/${t}`};return{path:a.path,prompt:hs(e,a,i)}};return(0,l.jsx)(n.u,{icon:n.Sn,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:(0,l.jsx)(n.i,{icon:n.cn,title:`Add a payment link`,onClick:c,children:`Add a payment link`}),children:(0,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:s.length===0?(0,l.jsx)(`p`,{className:`${n.a} 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.`}):s.map(e=>(0,l.jsx)(gs,{product:e,open:i===e.id,onToggle:()=>o(i===e.id?null:e.id),onChange:t,onRemove:()=>r(e.id),onCustomise:()=>u(e)},e.id))})})}var vs=e=>e.trim()&&Pr(e)===null?`Just a number, like 25.`:void 0,ys=e=>/^price_[A-Za-z0-9]+$/.test(e.trim());function bs({item:e,index:t,onChange:r,onRemove:i,removable:a}){let o=vs(e.amount);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`input`,{type:`text`,value:e.name,onChange:t=>r({...e,name:t.target.value}),placeholder:t===0?`A one-hour call`:`A two-hour call`,"aria-label":`Thing ${t+1} — its name`,className:`${n.o} flex-1 min-w-0`}),(0,l.jsx)(`input`,{type:`text`,inputMode:`decimal`,value:e.amount,onChange:t=>r({...e,amount:t.target.value}),placeholder:`25`,"aria-label":`Thing ${t+1} — its price`,className:`${n.o} w-24 shrink-0 text-right ${o?`border-red-500/50`:``}`}),a&&(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Remove ${e.name.trim()||`thing ${t+1}`}`,onClick:i,children:`Remove`})]}),o&&(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:o})]})}function xs({plan:e,index:t,onChange:r,onRemove:i}){let a=t=>r({...e,...t});return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-4`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,l.jsxs)(`span`,{className:`text-[11px] font-bold uppercase tracking-widest text-foreground/40`,children:[`Plan `,t+1]}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Remove this plan`,onClick:i,children:`Remove plan`})]}),(0,l.jsx)(n.h,{label:`What is this plan called?`,value:e.name,onChange:e=>a({name:e}),placeholder:`Basic`}),(0,l.jsx)(n.h,{label:`One line about it`,hint:`Optional — what a buyer gets on this plan.`,value:e.description,onChange:e=>a({description:e}),placeholder:`Up to 3 projects and email support`}),[[`monthly`,`Billed monthly`,`a month`],[`yearly`,`Billed yearly`,`a year`]].map(([r,i,o])=>(0,l.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 ml-1`,children:i}),(0,l.jsx)(n.g,{enabled:e[r].on,onChange:t=>a({[r]:{...e[r],on:t}}),label:`${i} — plan ${t+1}`})]}),e[r].on&&(0,l.jsx)(n.h,{label:`The price ${o}`,hint:`Just the number — 25 charges 25 ${o} in your Stripe account's currency.`,value:e[r].amount,onChange:t=>a({[r]:{...e[r],amount:t}}),placeholder:r===`monthly`?`25`:`250`,error:vs(e[r].amount)})]},r))]})}function Ss({product:e,plan:t,index:r,live:i,onChange:a}){let o=i?`livePriceId`:`priceId`,s=(e,t)=>({...e,[o]:t}),c=(!t.monthly.on||ys(t.monthly[o]))&&(!t.yearly.on||ys(t.yearly[o])),u=e=>a({...t,...e}),d=e=>e.trim()&&!ys(e)?`A price id starts with price_ — copy it from the price you just made.`:void 0;return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:t.name.trim()||`Plan ${r+1}`}),(0,l.jsx)(n.f,{state:c?`saved`:`off`,label:c?`Done`:i?`Waiting for its live ids`:`Waiting for its ids`})]}),(0,l.jsx)(`ol`,{className:`space-y-1.5 list-decimal list-inside text-[12.5px] font-medium text-foreground/60 leading-relaxed`,children:qr(e,t,i).map((e,t)=>(0,l.jsx)(`li`,{children:e},t))}),t.monthly.on&&(0,l.jsx)(n.h,{label:i?`Paste the live monthly price id`:`Paste the monthly price id`,value:t.monthly[o],onChange:e=>u({monthly:s(t.monthly,e)}),placeholder:`price_…`,error:d(t.monthly[o])}),t.yearly.on&&(0,l.jsx)(n.h,{label:i?`Paste the live yearly price id`:`Paste the yearly price id`,value:t.yearly[o],onChange:e=>u({yearly:s(t.yearly,e)}),placeholder:`price_…`,error:d(t.yearly[o])}),i&&(0,l.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 Cs({product:e,open:t,live:r,onToggle:i,onChange:o,onRemove:s,onProceed:c}){let u=t=>o({...e,...t}),d=(t,n)=>u({plans:e.plans.map((e,r)=>r===t?n:e)}),f=Ur(e,r),p=Hr(e,r),[m,h]=(0,a.useState)(!1),g=Gr(e);return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2 pr-3`,children:[(0,l.jsxs)(`button`,{type:`button`,onClick:i,"aria-expanded":t,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Kr(e)}),(0,l.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[e.kind&&(0,l.jsx)(n.f,{state:f?`saved`:`off`,label:f?`Ready`:`In progress`}),(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${t?`rotate-180`:``}`})]})]}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Remove ${g}`,onClick:()=>h(!0),children:`Remove`})]}),(0,l.jsx)(me,{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),s()}}),t&&(0,l.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,l.jsx)(n.d,{label:`How is it paid?`,value:e.kind,onChange:t=>u({kind:t===`once`||t===`subscription`?t:``,plans:t===`subscription`&&!e.plans.length?[Ar()]:e.plans,items:t===`once`&&!e.items.length?[jr()]:e.items}),options:[{value:`once`,label:`Once — one payment`},{value:`subscription`,label:`A subscription that renews`}],placeholder:`Choose one`}),e.kind===`once`&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.r,{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,l.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.items.map((t,n)=>(0,l.jsx)(bs,{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,l.jsx)(n.i,{icon:n.cn,className:`self-start`,onClick:()=>u({items:[...e.items,jr()]}),children:`Add another`})]})}),e.items.length>1&&(0,l.jsx)(n.h,{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,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h,{label:`What is the subscription called?`,value:e.name,onChange:e=>u({name:e}),placeholder:`Membership`}),(0,l.jsx)(n.m,{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,l.jsx)(n.r,{label:`Its plans`,hint:`Each plan can be billed monthly, yearly, or both.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.plans.map((t,n)=>(0,l.jsx)(xs,{plan:t,index:n,onChange:e=>d(n,e),onRemove:()=>u({plans:e.plans.filter((e,t)=>t!==n)})},n)),(0,l.jsx)(n.i,{icon:n.cn,className:`self-start`,onClick:()=>u({plans:[...e.plans,Ar()]}),children:`Add a plan`})]})}),Wr(e)&&(0,l.jsx)(n.r,{label:r?`Now make it in Stripe — live mode`:`Now make it in Stripe`,hint:r?`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,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.plans.map((t,n)=>(0,l.jsx)(Ss,{product:e,plan:t,index:n,live:r,onChange:e=>d(n,e)},n))})})]}),(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:[e.kind&&!f?(0,l.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:p}):e.kind?(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Ready — press Proceed to say how it works.`}):(0,l.jsx)(`span`,{}),f?(0,l.jsx)(n.i,{icon:n.pr,onClick:c,children:`Proceed`}):(0,l.jsx)(`span`,{})]})]})]})}function ws(){let[e,t]=(0,a.useState)(null),[r,i]=(0,a.useState)(!1),[s,c]=(0,a.useState)(null),[u,d]=(0,a.useState)(null),[f,p]=(0,a.useState)(null),[m,h]=(0,a.useState)(``),g=(0,a.useRef)(new Map),_=(0,a.useRef)(null),v=(0,a.useRef)(null),y=as();(0,a.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(n.Sr,Dr),e=>{let n=!!e.docs.find(e=>e.id===Or)?.data()?.liveMode;if(i(n),Ci(n),g.current.size)return;let r=[];e.forEach(e=>{e.id!==`_settings`&&r.push(zr(e.id,e.data()))}),r.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)),t(r)},()=>t([]));return()=>e()},[]);let b=e=>{let t=g.current.get(e.id);t&&clearTimeout(t),g.current.set(e.id,setTimeout(async()=>{g.current.delete(e.id);try{let{id:t,...r}=e;await(0,o.setDoc)((0,o.doc)(n.Sr,Dr,t),r)}catch(e){console.error(`Could not save the product`,e)}},600))},x=e=>{t(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=Mr(`p_${Date.now().toString(36)}`);t(t=>[...t||[],e]),c(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(``),t(e=>(e||[]).filter(e=>e.id!==r)),s===r&&c(null),u===r&&d(null),f===r&&p(null);try{await(0,o.deleteDoc)((0,o.doc)(n.Sr,Dr,r))}catch(e){console.error(`Could not remove the product`,e),a&&t(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=>{c(null),d(e),_.current?.scrollIntoView({behavior:`smooth`,block:`start`})};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.u,{icon:n.Zt,title:`What you sell`,description:`Things paid for once, each with a price; or a subscription with plans and their Stripe ids.`,children:(0,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:e===null?(0,l.jsx)(`p`,{className:n.a,children:`Loading what you sell…`}):(0,l.jsxs)(l.Fragment,{children:[e.length===0&&(0,l.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,l.jsx)(Cs,{product:e,open:s===e.id,live:r,onToggle:()=>c(s===e.id?null:e.id),onChange:x,onRemove:()=>C(e.id),onProceed:()=>w(e.id)},e.id)),!!m&&(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:m}),(0,l.jsx)(n.i,{icon:n.cn,className:`self-start`,onClick:S,children:`Add something you sell`})]})})}),(0,l.jsx)(`div`,{ref:_,children:(0,l.jsx)(n.u,{icon:n.Ft,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,l.jsx)(ss,{products:e,live:r,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,l.jsx)(`div`,{ref:v,children:(0,l.jsx)(n.u,{icon:n.ln,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,l.jsx)(ds,{products:e,pageRows:y,live:r,openId:f,onToggle:e=>p(f===e?null:e),onChange:x})})}),(0,l.jsx)(_s,{products:e||[],onChange:x,onRemove:C})]})}function Ts(e,t,n){return!e&&t!==`live`?{state:`off`,label:`In test mode`}:t===`live`?n?{state:`saved`,label:`Live`}:{state:`saved`,label:`Live — webhook still to add`}:{state:`saving`,label:`Waiting for the live key`}}function Es(){let[e,t]=(0,a.useState)(null),[i,s]=(0,a.useState)([]),[c,u]=(0,a.useState)(null),[d,f]=(0,a.useState)(!1);(0,a.useEffect)(()=>(0,o.onSnapshot)((0,o.collection)(n.Sr,Dr),e=>{t(!!e.docs.find(e=>e.id===Or)?.data()?.liveMode);let n=[];e.forEach(e=>{e.id!==`_settings`&&n.push(zr(e.id,e.data()))}),n.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)),s(n)},()=>t(!1)),[]),(0,a.useEffect)(()=>{let e=!0,t=async()=>{try{let t=await(await fetch(`/api/payments/status`)).json();if(!e)return;u(t?.mode===`live`||t?.mode===`test`?t.mode:null),f(!!t?.webhookConfigured)}catch{}};t();let n=setInterval(t,5e3);return()=>{e=!1,clearInterval(n)}},[]);let p=async e=>{t(e);try{await(0,o.setDoc)((0,o.doc)(n.Sr,Dr,Or),{liveMode:e},{merge:!0})}catch(e){console.error(`Could not save the go-live switch`,e)}};if(!d)return null;let m=!!e,h=Ts(m,c,d),g=i.filter(e=>Ur(e,!1)),_=g.filter(e=>!Ur(e,!0)),v=g.length>0&&_.length===0;return(0,l.jsx)(n.p,{icon:n.in,title:`Go live`,description:m?`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:h,enabled:e===null?null:m,onChange:p,children:m&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-[12.5px] font-medium text-foreground/70 leading-relaxed`,children:[(0,l.jsxs)(`li`,{children:[`In your Stripe dashboard, switch `,(0,l.jsx)(`strong`,{children:`Test mode`}),` OFF. If Stripe asks you to `,(0,l.jsx)(`strong`,{children:`activate your account`}),` first — business details, a bank account for payouts — finish that: live payments only run on an activated account.`]}),(0,l.jsxs)(`li`,{children:[`Open`,` `,(0,l.jsx)(`a`,{href:`https://dashboard.stripe.com/apikeys`,target:`_blank`,rel:`noopener noreferrer`,className:`text-accent font-bold hover:underline`,children:`Developers → API keys`}),` `,`and copy the live Secret key — it starts with `,(0,l.jsx)(`strong`,{children:`sk_live_`}),`. In AI Studio's Secrets tab, open `,(0,l.jsx)(`strong`,{children:`STRIPE_SECRET_KEY`}),` and paste it over the old value.`]}),(0,l.jsxs)(`li`,{children:[`Open`,` `,(0,l.jsx)(`a`,{href:`https://dashboard.stripe.com/webhooks`,target:`_blank`,rel:`noopener noreferrer`,className:`text-accent font-bold hover:underline`,children:`Developers → Webhooks`}),` `,`and click `,(0,l.jsx)(`strong`,{children:`Add endpoint`}),`. As the endpoint URL, paste exactly this:`,(0,l.jsx)(`div`,{className:`my-2`,children:(0,l.jsx)(r.l,{code:r.k(),label:`Copy your webhook address`,compact:!0})}),`When Stripe asks which events to listen for, click`,` `,(0,l.jsx)(`strong`,{children:`Select events`}),`, search for`,` `,(0,l.jsx)(`strong`,{children:`checkout.session.completed`}),` and tick just that one. Save, then put the `,(0,l.jsx)(`strong`,{children:`Signing secret`}),` it shows (whsec_…) into the`,` `,(0,l.jsx)(`strong`,{children:`STRIPE_WEBHOOK_SECRET`}),` secret. This is what keeps receipts and your sale alerts sending even when a buyer closes the tab before coming back.`]}),(0,l.jsxs)(`li`,{children:[`Rebuild the app so it starts with the new keys — the chip up here flips to`,` `,(0,l.jsx)(`strong`,{children:`Live`}),` on its own once it has.`]})]}),(0,l.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,l.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.`]}),g.length>0&&!v&&(0,l.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,l.jsx)(`strong`,{children:`live`}),` price ids — `,_.length===g.length?`each one`:`${_.length} of ${g.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.`]}),v&&(0,l.jsx)(r.g,{title:`Tell your assistant about the switch`,prompt:Ei(g)})]})})}var Ds={email:{collection:`sys_configs`,doc:`email`},payments:{collection:`sys_payments`,doc:`_settings`}},Os=e=>e?.enabled!==!1;function ks(e){let{collection:t,doc:i}=Ds[e],[s,c]=(0,a.useState)({loading:!0,on:!0});return(0,a.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(n.Sr,t,i),e=>c({loading:!1,on:Os(e.exists()?e.data():null)}),()=>c({loading:!1,on:!0})),[t,i]),{loading:s.loading,on:s.on,set:async a=>{let l=s.on;c({loading:!1,on:a});try{return await(0,o.setDoc)((0,o.doc)(n.Sr,t,i),{enabled:a},{merge:!0}),e===`payments`&&r.w(),null}catch{return c({loading:!1,on:l}),`The switch could not be saved. Check that you are signed in as an admin.`}}}}function As(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 js(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 Ms=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`}},Ns=e=>e?new Date(e*1e3).toLocaleDateString(void 0,{day:`numeric`,month:`short`,year:`numeric`}):``;function Ps({label:e,tone:t}){return(0,l.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 Fs({children:e,tone:t=`quiet`}){return(0,l.jsx)(`p`,{className:`text-[12.5px] font-medium leading-relaxed px-1 ${t===`error`?`text-red-500`:`text-foreground/50`}`,children:e})}function Is(){let{user:e}=r.j(),[t,i]=(0,a.useState)(null),[o,s]=(0,a.useState)(``),[c,d]=(0,a.useState)(null),[f,p]=(0,a.useState)(``),[m,h]=(0,a.useState)([]),[g,_]=(0,a.useState)([]),[v,y]=(0,a.useState)(!1),[b,x]=(0,a.useState)(``),[S,C]=(0,a.useState)(!1),[w,T]=(0,a.useState)(!1),[E,D]=(0,a.useState)(``),O=ks(`payments`),[k,A]=(0,a.useState)(``),j=Ms(O.on),M=(0,a.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]);(0,a.useEffect)(()=>{let e=!1;return fetch(`/api/payments/status`).then(e=>e.json()).then(t=>{e||i(t)}).catch(()=>{e||s(`The server could not be reached.`)}),()=>{e=!0}},[]);let N=(0,a.useCallback)((e,t)=>{let n=e.charges||[],r=e.subscriptions||[];h(e=>t?[...e,...n]:n),_(e=>t?[...e,...r]:r),C(!!(e.chargesHasMore||e.subscriptionsHasMore))},[]);(0,a.useEffect)(()=>{if(!t?.configured||!e)return;let n=!1;return M(`/api/payments/products`).then(e=>{n||d(e.products||[])}).catch(e=>{n||p(e.message)}),M(`/api/payments/orders`).then(e=>{n||(N(e,!1),y(!0))}).catch(e=>{n||(x(e.message),y(!0))}),()=>{n=!0}},[t?.configured,e,M,N]);let P=async()=>{T(!0);try{let e=new URLSearchParams,t=m[m.length-1],n=g[g.length-1];t&&e.set(`starting_after`,t.id),n&&e.set(`subscriptions_after`,n.id),N(await M(`/api/payments/orders?${e}`),!0)}catch(e){x(e.message)}T(!1)},F=e=>{navigator.clipboard?.writeText(e),D(e),setTimeout(()=>D(``),2e3)},I=[...m,...g].sort((e,t)=>(t.created||0)-(e.created||0)),L=(c||[]).flatMap(e=>e.prices),R=t?.mode===`live`?`https://dashboard.stripe.com/products`:`https://dashboard.stripe.com/test/products`,z=!!(t&&!t.configured);return(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`Payments`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/payments`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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:!t&&!o?(0,l.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,l.jsx)(n.yn,{className:`w-6 h-6 animate-spin text-accent`})}):z?(0,l.jsxs)(n.u,{icon:n.Hn,title:`Connect Stripe`,description:`This app is not taking payments yet.`,collapsible:!1,children:[(0,l.jsx)(Fs,{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,l.jsxs)(u.Link,{to:`/setup`,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]`,children:[`Set up payments`,(0,l.jsx)(n.pr,{className:`w-3.5 h-3.5`})]})]}):(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[t?.mode===`live`&&(0,l.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,l.jsx)(n.Ut,{className:`w-4 h-4 text-red-500 shrink-0`}),(0,l.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,l.jsx)(n.p,{icon:n.sn,title:`Take payments`,description:j.description,chip:j.chip,enabled:O.loading?null:O.on,onChange:async e=>A(await O.set(e)||``),children:k?(0,l.jsx)(Fs,{tone:`error`,children:k}):null}),(0,l.jsx)(n.u,{icon:n.ln,title:`Connection`,description:`Whether this app can take money right now.`,defaultOpen:!t?.webhookConfigured,actions:o?(0,l.jsx)(n.f,{state:`error`,label:`Unreachable`}):(0,l.jsx)(n.f,{state:`saved`,label:t?.mode===`live`?`Live`:`Test mode`}),children:o?(0,l.jsx)(Fs,{tone:`error`,children:o}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(Fs,{children:t?.mode===`live`?`Stripe is connected with a live key. Payments made anywhere on your site are real.`:`Stripe is connected with a test key. Buttons work end to end, but only test cards are accepted and no real money moves.`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2.5 px-1 flex-wrap`,children:[(0,l.jsx)(n.f,{state:t?.webhookConfigured?`saved`:`off`,label:t?.webhookConfigured?`Webhook connected`:`Webhook not set`}),!t?.webhookConfigured&&(0,l.jsxs)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Add it on the`,` `,(0,l.jsx)(u.Link,{to:`/setup`,className:`text-accent font-bold hover:underline`,children:`setup page`}),` `,`— it keeps receipts and sale alerts sending, and the Go live switch appears here once it is in.`]})]})]})}),(0,l.jsx)(Es,{}),(0,l.jsx)(ws,{}),(0,l.jsx)(n.u,{icon:n.Kt,title:`In your Stripe account`,description:`The products and prices Stripe has right now — where price ids come from.`,defaultOpen:!1,children:f?(0,l.jsx)(Fs,{tone:`error`,children:f}):c===null?(0,l.jsx)(`div`,{className:`flex items-center justify-center py-6 text-foreground/40`,children:(0,l.jsx)(n.yn,{className:`w-5 h-5 animate-spin text-accent`})}):L.length===0?(0,l.jsxs)(Fs,{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,l.jsx)(`a`,{href:R,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,l.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:L.map(e=>(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${n.n}`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate min-w-0 flex-1`,children:e.productName||`Unnamed product`}),(0,l.jsxs)(`span`,{className:`text-[12.5px] font-semibold text-foreground/60 whitespace-nowrap shrink-0`,children:[js(e.amount,e.currency),e.interval?` / ${e.interval}`:``]}),(0,l.jsx)(n.i,{compact:!0,icon:E===e.id?n.nr:n.Un,title:`Copy the price id for ${e.productName||`this price`}`,onClick:()=>F(e.id),children:E===e.id?`Copied`:`Copy price id`})]},e.id))})}),(0,l.jsx)(n.u,{icon:n.on,title:`Payments received`,description:`Every charge and subscription, straight from Stripe.`,defaultOpen:!1,children:b?(0,l.jsx)(Fs,{tone:`error`,children:b}):v?I.length===0?(0,l.jsx)(Fs,{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,l.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[I.map(e=>{let t=As(e);return(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.name||e.email||`Someone`}),(0,l.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,l.jsx)(`span`,{className:`max-sm:hidden text-[11.5px] font-medium text-foreground/45 whitespace-nowrap shrink-0`,children:Ns(e.created)}),(0,l.jsxs)(`span`,{className:`text-[12.5px] font-semibold text-foreground/70 whitespace-nowrap shrink-0`,children:[js(e.amount,e.currency),e.kind===`subscription`&&e.interval?` / ${e.interval}`:``]}),(0,l.jsx)(Ps,{label:t.label,tone:t.tone})]},e.id)}),S&&(0,l.jsx)(n.i,{busy:w,onClick:P,className:`self-center mt-1`,children:`Show older payments`})]}):(0,l.jsx)(`div`,{className:`flex items-center justify-center py-6 text-foreground/40`,children:(0,l.jsx)(n.yn,{className:`w-5 h-5 animate-spin text-accent`})})})]})})]})]})}var Ls={from:`09:00`,to:`17:00`},Rs=e=>e.name.trim()||e.email.split(`@`)[0]||``,zs=e=>n.I(e)?{state:`saved`,label:`Bookable`}:e.enabled?{state:`off`,label:`In progress`}:{state:`off`,label:`Turned off`},Bs=()=>`s_${Date.now().toString(36)}${Math.random().toString(36).slice(2,6)}`,Vs=e=>({...n.F(Bs(),e.id,Rs(e),n.G()),createdAt:Date.now()}),Hs=`__new_payment__`,Us=`w-[6.5rem] shrink-0`,Ws=`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 Gs({day:e,windows:t,onChange:r}){let i=t.length>0,a=(e,n)=>r(t.map((t,r)=>r===e?{...t,...n}:t));return(0,l.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,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3 h-9`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-medium ${i?`text-foreground/80`:`text-foreground/40`}`,children:n.C[e]}),(0,l.jsx)(n.g,{enabled:i,onChange:e=>r(e?[Ls]:[]),label:`${n.C[e]} — bookable`})]}),i&&(0,l.jsxs)(`div`,{className:`flex flex-col gap-2 min-w-0`,children:[t.map((i,o)=>(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`div`,{className:Us,children:(0,l.jsx)(n.Et,{ariaLabel:`${n.C[e]} from${o?` (${o+1})`:``}`,value:i.from,options:n.T,onChange:e=>a(o,{from:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),(0,l.jsx)(`span`,{className:`w-3 text-center text-foreground/40 text-[13px] shrink-0 select-none`,children:`–`}),(0,l.jsx)(`div`,{className:Us,children:(0,l.jsx)(n.Et,{ariaLabel:`${n.C[e]} to${o?` (${o+1})`:``}`,value:i.to,options:n.w,onChange:e=>a(o,{to:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),t.length>1&&(0,l.jsx)(`button`,{type:`button`,title:`Remove these hours on ${n.C[e]}`,"aria-label":`Remove ${n.C[e]} hours ${o+1}`,onClick:()=>r(t.filter((e,t)=>t!==o)),className:Ws,children:(0,l.jsx)(n.Pt,{className:`w-3.5 h-3.5`})})]},o)),t.length<2&&(0,l.jsx)(`button`,{type:`button`,onClick:()=>r([...t,{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 Ks({value:e,products:t,onChange:r,onCreate:i}){let[o,s]=(0,a.useState)(!1),[c,u]=(0,a.useState)(``),[d,f]=(0,a.useState)(``),[p,m]=(0,a.useState)(``),h=[...t.map(e=>({value:e.id,label:`${Gr(e)} — ${Nr(e).map(e=>e.amount).filter(Boolean).join(` + `)||`no price yet`}`})),{value:Hs,label:`+ Create a one-time payment`}];return(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,l.jsx)(n.d,{label:`Add a payment for this meeting`,hint:t.find(t=>t.id===e)?`Taken on the booking page before the time is confirmed. Its price and receipts are on the Payments screen.`:`Optional. A one-time payment taken on the booking page before the time is confirmed.`,value:o?Hs:e,placeholder:`No payment`,options:h,onChange:e=>{if(e===`__new_payment__`){s(!0);return}s(!1),r(e)}}),o&&(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-3`,children:[(0,l.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-widest text-foreground/40`,children:`A new one-time payment`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`input`,{type:`text`,value:c,onChange:e=>u(e.target.value),placeholder:`A one-hour session`,"aria-label":`The payment's name`,className:`w-full h-11 px-4 rounded-[var(--input-radius,0.75rem)] border border-[var(--panel-border)] bg-[var(--panel-bg)] text-[14px] text-foreground outline-none transition-all duration-300 placeholder:text-foreground/35 hover:border-accent/40 focus:border-accent disabled:opacity-50 disabled:cursor-not-allowed console-field flex-1 min-w-0`}),(0,l.jsx)(`input`,{type:`text`,inputMode:`decimal`,value:d,onChange:e=>f(e.target.value),placeholder:`25`,"aria-label":`The payment's price`,className:`w-full h-11 px-4 rounded-[var(--input-radius,0.75rem)] border border-[var(--panel-border)] bg-[var(--panel-bg)] text-[14px] text-foreground outline-none transition-all duration-300 placeholder:text-foreground/35 hover:border-accent/40 focus:border-accent disabled:opacity-50 disabled:cursor-not-allowed console-field w-24 shrink-0 text-right`})]}),p&&(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:p}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(n.i,{icon:n.cn,onClick:async()=>{if(!c.trim()){m(`Give the payment a name.`);return}if(Pr(d)===null){m(`Just a number for the price, like 25.`);return}m(``);let e=await i(c.trim(),d.trim());if(e){m(e);return}s(!1),u(``),f(``)},children:`Create it`}),(0,l.jsx)(n.i,{onClick:()=>{s(!1),m(``)},children:`Never mind`})]})]})]})}function qs({schedule:e,members:t,products:r,onChange:i,onCreatePayment:a}){let o=t=>i({...e,...t}),s=n.it(e),c=t.find(t=>t.id===e.memberId);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h,{label:`What is it called?`,hint:`The kind of meeting — visitors read this on the booking page.`,value:e.name,onChange:e=>o({name:e}),placeholder:`A 1-hour session`}),(0,l.jsx)(n.m,{label:`A line or two about it`,hint:`Optional — what it is for, what to bring, what happens after.`,value:e.description,onChange:e=>o({description:e}),placeholder:`A first conversation about what you need and how I can help.`}),t.length>1&&(0,l.jsx)(n.d,{label:`Whose time is it?`,value:e.memberId,options:t.map(e=>({value:e.id,label:Rs(e)||e.email})),allowEmpty:!1,onChange:n=>{let r=t.find(e=>e.id===n);o({memberId:n,memberName:(!e.memberName.trim()||c&&e.memberName===Rs(c))&&r?Rs(r):e.memberName})}}),(0,l.jsx)(n.h,{label:`The name visitors see`,value:e.memberName,onChange:e=>o({memberName:e}),placeholder:`Anna`}),(0,l.jsx)(n._,{label:`Can be booked`,hint:`Off until the hours are complete and you turn this on.`,enabled:e.enabled,onChange:e=>o({enabled:e})}),(0,l.jsx)(n.t,{value:e.timeZone,onChange:e=>o({timeZone:e})}),(0,l.jsx)(n.d,{label:`How long is one booking?`,value:String(e.slotMinutes),options:n.k,allowEmpty:!1,onChange:e=>o({slotMinutes:Number(e)})}),(0,l.jsx)(n.r,{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 under any of their schedules is taken here too.`,children:(0,l.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:n.S.map(t=>(0,l.jsx)(Gs,{day:t,windows:e.days[t]||[],onChange:n=>o({days:{...e.days,[t]:n}})},t))})}),(0,l.jsx)(n.d,{label:`How far ahead can people book?`,value:String(e.horizonDays),options:n.E,allowEmpty:!1,onChange:e=>o({horizonDays:Number(e)})}),(0,l.jsx)(n.d,{label:`How much notice do you need?`,value:String(e.noticeHours),options:n.D,allowEmpty:!1,onChange:e=>o({noticeHours:Number(e)})}),(0,l.jsx)(Ks,{value:e.paymentId,products:r,onChange:e=>o({paymentId:e}),onCreate:async(e,t)=>{let n=await a(e,t);return n&&n.startsWith(`p_`)?(o({paymentId:n}),null):n||`The payment could not be made — make sure you are signed in as an admin and try again.`}}),(0,l.jsx)(n.r,{label:`Booking link`,hint:n.I(e)?`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 schedule is complete and turned on.`,children:(0,l.jsx)(fs,{title:n.st(e),path:n.H(e.id)})}),(0,l.jsx)(`div`,{className:`pt-1`,children:s?(0,l.jsx)(`span`,{className:n.a,children:s}):e.enabled?(0,l.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,l.jsx)(`span`,{className:n.a,children:`Complete — turn on Can be booked to offer it.`})})]})}function Js({schedule:e,members:t,products:r,open:i,stale:o,error:s,onToggle:c,onChange:u,onRemove:d,onCreatePayment:f}){let p=zs(e),[m,h]=(0,a.useState)(!1),g=n.st(e);return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] ${o?`opacity-60`:``}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2 pr-3`,children:[(0,l.jsxs)(`button`,{type:`button`,onClick:c,"aria-expanded":i,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:n.ot(e)}),(0,l.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[o?(0,l.jsx)(`span`,{className:`${n.a} max-sm:hidden`,children:`No longer on the team`}):(0,l.jsx)(n.f,{state:p.state,label:p.label}),(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${i?`rotate-180`:``}`})]})]}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Remove ${g}`,onClick:()=>h(!0),children:`Remove`})]}),(0,l.jsx)(me,{isOpen:m,title:`Remove ${g}?`,message:o?`They are no longer on the team, so nobody can book them. Bookings already taken are kept.`:`Its booking link stops working and it leaves every page and form it was picked on. Bookings already taken are kept.`,confirmText:`Yes, remove`,cancelText:`Keep it`,onCancel:()=>h(!1),onConfirm:()=>{h(!1),d()}}),i&&(0,l.jsx)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:(0,l.jsx)(qs,{schedule:e,members:t,products:r,onChange:u,onCreatePayment:f})}),s&&(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-4 pb-3`,children:s})]})}var Ys=e=>({id:e.uid,name:String(e.displayName||``),email:String(e.email||``),role:`admin`});function Xs(){let[e,t]=(0,a.useState)([]);return(0,a.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(n.Sr,Dr),e=>{let n=[];e.forEach(e=>{e.id!==`_settings`&&n.push(zr(e.id,e.data()))}),t(n.filter(e=>e.kind===`once`).sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)))},()=>t([]));return()=>e()},[]),e}function Zs(){let{user:e}=r.j(),{loading:i,members:s}=t.d(),{loading:c,schedules:d}=t.c(),f=Xs(),[p,m]=(0,a.useState)({}),[h,g]=(0,a.useState)([]),[_,v]=(0,a.useState)(null),[y,b]=(0,a.useState)({}),x=(0,a.useRef)(new Map),S=(0,a.useMemo)(()=>{let e=new Map(d.map(e=>[e.id,e]));for(let t of Object.values(p))e.set(t.id,t);for(let t of h)e.delete(t);return[...e.values()].sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)||e.id.localeCompare(t.id))},[d,p,h]),C=e=>{let n=x.current.get(e.id);n&&clearTimeout(n),x.current.set(e.id,setTimeout(async()=>{x.current.delete(e.id);let n=await t.o(e);b(t=>{let r={...t};return n?r[e.id]=n:delete r[e.id],r})},600))},w=e=>{m(t=>({...t,[e.id]:e})),C(e)},T=e?s.find(t=>t.id===e.uid)||Ys(e):null,E=T&&!s.some(e=>e.id===T.id)?[T,...s]:s,D=()=>{if(!T)return;let e=Vs(T);m(t=>({...t,[e.id]:e})),v(e.id),C(e)},O=async e=>{let n=x.current.get(e);n&&(clearTimeout(n),x.current.delete(e)),m(t=>{let n={...t};return delete n[e],n}),g(t=>[...t,e]),_===e&&v(null);let r=await t.a(e);r&&(g(t=>t.filter(t=>t!==e)),b(t=>({...t,[e]:r})))},k=async(e,t)=>{let r={...Mr(`p_${Date.now().toString(36)}`),kind:`once`,items:[{name:e,amount:t}]};try{let{id:e,...t}=r;return await(0,o.setDoc)((0,o.doc)(n.Sr,Dr,e),t),e}catch(e){return console.error(`Could not make the payment`,e),null}},A=i||c,j=new Set(E.map(e=>e.id));return(0,l.jsx)(n.u,{icon:n.sr,title:`Your schedules`,description:`One per kind of meeting — a name, whose time it is, the hours, the length, a payment if you like, and a link to send.`,actions:A?void 0:(0,l.jsx)(n.i,{icon:n.cn,title:`Add a schedule`,onClick:D,children:`Add a schedule`}),children:(0,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:A?(0,l.jsx)(`p`,{className:n.a,children:`Loading your schedules…`}):S.length===0?(0,l.jsxs)(`div`,{className:`flex flex-col items-start gap-3 px-1`,children:[(0,l.jsxs)(`p`,{className:n.a,children:[`No schedule yet. A schedule is one kind of meeting somebody offers — a 1-hour session, a 2-hour workshop — with its own hours, length and link. Everyone marked Internal or Admin on the`,` `,(0,l.jsx)(u.Link,{to:`/users`,className:`text-accent font-bold hover:underline`,children:`Users screen`}),` can have as many as you like; a person's schedules share their availability.`]}),(0,l.jsx)(n.i,{icon:n.cn,title:`Add a schedule`,onClick:D,children:`Add a schedule`})]}):S.map(e=>(0,l.jsx)(Js,{schedule:e,members:E,products:f,stale:!j.has(e.memberId),open:_===e.id,error:y[e.id],onToggle:()=>v(_===e.id?null:e.id),onChange:w,onRemove:()=>O(e.id),onCreatePayment:k},e.id))})})}function Qs({booking:e,zone:t,onCancel:r}){let[i,o]=(0,a.useState)(!1),[s,c]=(0,a.useState)(!1);return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-3`,children:[(0,l.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col gap-0.5`,children:[(0,l.jsxs)(`span`,{className:`text-[13px] font-semibold text-foreground/80 truncate`,children:[n.ft(e,t),e.memberName?` with ${e.memberName}`:``,e.scheduleName?` · ${e.scheduleName}`:``]}),(0,l.jsxs)(`span`,{className:`text-[12px] font-medium text-foreground/50 truncate`,children:[e.name||`Someone`,e.email&&(0,l.jsxs)(`span`,{className:`max-sm:hidden`,children:[` · `,e.email]})]})]}),(0,l.jsx)(n.i,{icon:n.Pt,tone:`danger`,compact:!0,title:`Cancel this booking`,onClick:()=>o(!0),children:`Cancel`})]}),(0,l.jsx)(me,{isOpen:i,title:`Cancel this booking?`,message:`The time becomes free again.`,confirmText:`Yes, cancel`,cancelText:`Keep it`,isProcessing:s,onCancel:()=>o(!1),onConfirm:async()=>{c(!0),await r(),c(!1),o(!1)}})]})}function $s(){let e=n.G(),{loading:r,bookings:i,error:o}=t.s(),[s,c]=(0,a.useState)(``);return(0,l.jsx)(n.u,{icon:n.cr,title:`Bookings`,description:`Shown in your time — ${n.ht(e)}. Each person also sees their own on My calendar.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[r?(0,l.jsx)(`p`,{className:n.a,children:`Loading bookings…`}):o?(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:o}):i.length===0?(0,l.jsx)(`p`,{className:`${n.a} px-1`,children:`Nothing booked yet. Bookings appear here the moment someone takes a time — and in your Inbox, like any form entry.`}):i.map(n=>(0,l.jsx)(Qs,{booking:n,zone:e,onCancel:async()=>{c(``);let e=await t.n(n.id);e&&c(e)}},n.id)),!!s&&(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:s})]})})}function ec(){let{userRole:e}=r.j();return e===`admin`?(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`Schedule`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/schedule`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsx)(`div`,{className:`flex flex-col gap-1.5 px-1`,children:(0,l.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/60 leading-relaxed`,children:`The kinds of meeting you and your team can be booked for, each in its person's own time zone. Every schedule has a link to send; you can also pick it on a page under Booking on this page, or add it to a form as a Pick-a-time question.`})}),(0,l.jsx)(Zs,{}),(0,l.jsx)($s,{})]})})]})]}):(0,l.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,l.jsx)(br,{})})}var tc=[`M`,`T`,`W`,`T`,`F`,`S`,`S`],nc=e=>e.slice(0,7),rc=e=>{let[t,n]=e.split(`-`).map(Number);return new Intl.DateTimeFormat(void 0,{month:`long`,year:`numeric`,timeZone:`UTC`}).format(new Date(Date.UTC(t,n-1,1)))},ic=(e,t)=>{let[n,r]=e.split(`-`).map(Number),i=new Date(Date.UTC(n,r-1+t,1));return`${i.getUTCFullYear()}-${String(i.getUTCMonth()+1).padStart(2,`0`)}`};function ac(e,t){let r=new Map;for(let i of e){let e=n._t(new Date(i.start),t).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 oc(e,t){return!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`}}function sc({booking:e,zone:t,paid:r,onCancel:i}){let[o,s]=(0,a.useState)(!1),[c,u]=(0,a.useState)(!1),d=oc(e,r),f=e.end<new Date().toISOString();return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] ${f?`opacity-60`:``}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-3`,children:[(0,l.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col gap-0.5`,children:[(0,l.jsxs)(`span`,{className:`text-[13px] font-semibold text-foreground/80 truncate`,children:[n.q(new Date(e.start),t),`–`,n.q(new Date(e.end),t),e.scheduleName?` · ${e.scheduleName}`:``]}),(0,l.jsxs)(`span`,{className:`text-[12px] font-medium text-foreground/50 truncate`,children:[e.name||`Someone`,e.email&&(0,l.jsxs)(`span`,{className:`max-sm:hidden`,children:[` · `,e.email]}),e.answers.note&&(0,l.jsxs)(`span`,{className:`max-sm:hidden`,children:[` · `,e.answers.note]})]})]}),d&&(0,l.jsx)(n.f,{state:d.state,label:d.label}),!f&&(0,l.jsx)(n.i,{icon:n.Pt,tone:`danger`,compact:!0,title:`Cancel this booking`,onClick:()=>s(!0),children:`Cancel`})]}),(0,l.jsx)(me,{isOpen:o,title:`Cancel this booking?`,message:`The time becomes free again on every schedule of yours.`,confirmText:`Yes, cancel`,cancelText:`Keep it`,isProcessing:c,onCancel:()=>s(!1),onConfirm:async()=>{u(!0),await i(),u(!1),s(!1)}})]})}function cc({bookings:e,zone:r,paid:i,onCancel:o,now:s}){let c=n._t(s?s():new Date,r).dateKey,u=(0,a.useMemo)(()=>ac(e,r),[e,r]),[d,f]=(0,a.useState)(nc(c)),[p,m]=(0,a.useState)(c),h=t.m(d),g=u.get(p)||[],_=new Intl.DateTimeFormat(void 0,{timeZone:`UTC`,weekday:`long`,day:`numeric`,month:`long`}).format(new Date(`${p}T00:00:00Z`));return(0,l.jsxs)(`div`,{className:`flex flex-col md:flex-row gap-5 md:gap-8 w-full`,children:[(0,l.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,l.jsx)(`h4`,{className:`text-[15px] sm:text-[17px] font-bold text-foreground tracking-tight truncate`,children:rc(d)}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,l.jsx)(`button`,{type:`button`,onClick:()=>{f(nc(c)),m(c)},className:`px-3 py-1.5 text-[12.5px] font-bold border border-[var(--panel-border)] rounded-xl mr-1 hover:bg-foreground/5 transition-colors cursor-pointer`,children:`Today`}),(0,l.jsx)(`button`,{type:`button`,"aria-label":`Previous month`,onClick:()=>f(e=>ic(e,-1)),className:`p-1.5 rounded-xl text-foreground/50 hover:text-foreground hover:bg-foreground/5 transition-colors border border-transparent hover:border-[var(--panel-border)] cursor-pointer`,children:(0,l.jsx)(n.er,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{type:`button`,"aria-label":`Next month`,onClick:()=>f(e=>ic(e,1)),className:`p-1.5 rounded-xl text-foreground/50 hover:text-foreground hover:bg-foreground/5 transition-colors border border-transparent hover:border-[var(--panel-border)] cursor-pointer`,children:(0,l.jsx)(n.$n,{className:`w-4 h-4`})})]})]}),(0,l.jsxs)(`div`,{className:`grid grid-cols-7 gap-1`,role:`grid`,"aria-label":rc(d),children:[tc.map((e,t)=>(0,l.jsx)(`div`,{className:`text-center text-[11px] font-bold uppercase tracking-wider text-foreground/40 py-1`,children:e},t)),h.map((e,t)=>{if(!e)return(0,l.jsx)(`div`,{"aria-hidden":!0},`blank-${t}`);let n=u.get(e)?.length||0,r=e===p,i=e===c;return(0,l.jsxs)(`button`,{type:`button`,role:`gridcell`,"aria-label":`${e}${n?`, ${n} booked`:``}`,"aria-selected":r,onClick:()=>m(e),className:`relative flex flex-col items-center justify-center aspect-square rounded-xl text-[14px] font-semibold transition-all cursor-pointer ${r?`bg-accent text-[var(--button-fg,#fff)] shadow-lg shadow-accent/20`:n?`text-foreground hover:bg-foreground/[0.06]`:`text-foreground/40 hover:bg-foreground/[0.04]`} ${i&&!r?`ring-1 ring-accent/50`:``}`,children:[Number(e.slice(8,10)),n>0&&(0,l.jsx)(`span`,{"aria-hidden":!0,className:`absolute bottom-1 text-[9px] font-bold leading-none px-1 rounded-full ${r?`bg-[var(--button-fg,#fff)]/20`:`bg-accent/15 text-accent`}`,children:n})]},e)})]})]}),(0,l.jsxs)(`div`,{className:`md:w-[320px] shrink-0 flex flex-col gap-2`,children:[(0,l.jsx)(`p`,{className:`text-[13px] font-bold text-foreground`,children:_}),g.length===0?(0,l.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50`,children:`Nothing booked on this day.`}):g.map(e=>(0,l.jsx)(sc,{booking:e,zone:r,paid:i[e.paymentSession],onCancel:()=>o(e.id)},e.id))]})]})}function lc(){let{user:e,userRole:i}=r.j(),o=e?.uid||``,s=n.G(),{schedules:c}=t.l(r.I(i)?o:null),{loading:d,bookings:f,error:p}=t.s({members:o?[o]:[],includePast:!0}),[m,h]=(0,a.useState)({}),[g,_]=(0,a.useState)(``);return(0,a.useEffect)(()=>{let e=f.filter(e=>e.paymentSession&&m[e.paymentSession]===void 0);if(!e.length)return;let t=!1;return Promise.all(e.map(async e=>[e.paymentSession,(await r.x(e.paymentSession)).paid])).then(e=>{t||h(t=>({...t,...Object.fromEntries(e)}))}),()=>{t=!0}},[f,m]),r.I(i)?(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`My calendar`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/my-calendar`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/60 leading-relaxed px-1`,children:[`Every booking made with you, under every schedule of yours — shown in your time, `,n.ht(s),`. A time booked on one schedule is taken on all of them.`]}),(0,l.jsxs)(n.u,{icon:n.or,title:`Bookings`,description:`Pick a day to see who is coming.`,children:[d?(0,l.jsx)(`p`,{className:n.a,children:`Loading your bookings…`}):p?(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:p}):(0,l.jsx)(cc,{bookings:f,zone:s,paid:m,onCancel:async e=>{_(``);let n=await t.n(e);n&&_(n)}}),!!g&&(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1 mt-3`,children:g})]}),c.length>0&&(0,l.jsx)(n.u,{icon:n.Un,title:`Your booking links`,description:`Send one to anyone — they pick a free time and it lands here.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[c.map(e=>(0,l.jsx)(fs,{title:n.st(e),path:n.H(e.id)},e.id)),i===`admin`&&(0,l.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug px-1`,children:[`Change a schedule's hours, length or payment on the `,(0,l.jsx)(u.Link,{to:`/schedule`,className:`text-accent font-bold hover:underline`,children:`Schedule screen`}),`.`]})]})})]})})]})]}):(0,l.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,l.jsx)(br,{})})}var uc=/^[^\s@,;]+@[^\s@,;.]+(\.[^\s@,;.]+)*\.[a-z]{2,}$/i,dc=`booking`;function fc(e){if(!e||e.kind!==`once`)return null;let t=Nr(e),n=t.reduce((e,t)=>e+(Pr(t.amount)||0),0),r=e.name.trim()||t.map(e=>e.name.trim()).filter(Boolean).join(` and `)||Gr(e);return n>0?{amount:n,name:r}:null}var pc=(e,t=`usd`)=>{try{return new Intl.NumberFormat(void 0,{style:`currency`,currency:t.toUpperCase()}).format(e)}catch{return`${e} ${t.toUpperCase()}`}};function mc(e){let[t,r]=(0,a.useState)({id:``,product:null});return(0,a.useEffect)(()=>{if(!e)return;let t=!1;return(0,o.getDoc)((0,o.doc)(n.Sr,Dr,e)).then(n=>{t||r({id:e,product:n.exists()?zr(n.id,n.data()):null})}).catch(()=>{t||r({id:e,product:null})}),()=>{t=!0}},[e]),e?t.id===e?{loading:!1,product:t.product}:{loading:!0,product:null}:{loading:!1,product:null}}function hc({children:e}){return(0,l.jsx)(`main`,{className:`flex-1 w-full max-w-5xl mx-auto px-4 pt-2 pb-16 md:pt-4 z-10 flex flex-col`,children:(0,l.jsx)(n.kt.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 gc({icon:e,title:t,children:n}){return(0,l.jsxs)(`div`,{className:`flex flex-col items-center text-center py-8 gap-4`,children:[(0,l.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,l.jsx)(e,{className:`w-7 h-7 text-accent`})}),(0,l.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold text-foreground tracking-tight`,children:t}),n&&(0,l.jsx)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed max-w-md`,children:n}),(0,l.jsx)(u.Link,{to:`/`,className:`text-[13px] font-bold text-accent hover:underline mt-2`,children:`Back to the site`})]})}function _c({sessionId:e,schedule:t}){let[i,o]=(0,a.useState)(null);if((0,a.useEffect)(()=>{let t=!1;return r.x(e).then(e=>{t||o(e)}),()=>{t=!0}},[e]),!i)return(0,l.jsx)(gc,{icon:n.yn,title:`Confirming your payment…`,children:`One moment — checking with the payment provider.`});let s=i.metadata?.when||``;return i.paid?(0,l.jsx)(gc,{icon:n.cr,title:`Booked and paid`,children:(0,l.jsxs)(`p`,{children:[s?`${s} — `:``,n.st(t),`.`,i.customerEmail?` A receipt is on its way to ${i.customerEmail}.`:``]})}):(0,l.jsx)(gc,{icon:n.Kn,title:`Not confirmed yet`,children:(0,l.jsx)(`p`,{children:i.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 vc(){let{id:e=``}=(0,u.useParams)(),[i]=(0,u.useSearchParams)(),{activeConfig:s}=t.y(),{loading:c,schedules:d}=t.c(),f=d.find(t=>t.id===e)||null,{loading:p,product:m}=mc(f?.paymentId||``),h=fc(m),g=r.D(),[_,v]=(0,a.useState)(()=>n.G()),[y]=(0,a.useState)(()=>new Date),b=t.u(f?[f.memberId]:[],y),x=(0,a.useMemo)(()=>f&&n.I(f)?[f]:[],[f]),[S,C]=(0,a.useState)(null),[w,T]=(0,a.useState)(()=>n.xr.currentUser?.displayName||``),[E,D]=(0,a.useState)(()=>n.xr.currentUser?.email||``),[O,k]=(0,a.useState)(``),[A,j]=(0,a.useState)({}),[M,N]=(0,a.useState)(!1),[P,F]=(0,a.useState)(``),[I,L]=(0,a.useState)(``),R=i.get(`session_id`)||``,z=i.get(`cancelled`)===`1`;if(c)return(0,l.jsx)(hc,{children:(0,l.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-16 text-foreground/50`,children:[(0,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin text-accent`}),(0,l.jsx)(`span`,{className:`text-[13px] font-medium`,children:`Loading…`})]})});if(!f)return(0,l.jsx)(hc,{children:(0,l.jsx)(gc,{icon:n.ar,title:`This booking link is no longer open`,children:`It may have been taken down. Ask whoever sent it for a new one.`})});if(R)return(0,l.jsx)(hc,{children:(0,l.jsx)(_c,{sessionId:R,schedule:f})});if(I)return(0,l.jsx)(hc,{children:(0,l.jsx)(gc,{icon:n.cr,title:`Booked`,children:(0,l.jsxs)(`p`,{children:[I,`. `,E?`We have your email as ${E}.`:``]})})});if(!n.I(f))return(0,l.jsx)(hc,{children:(0,l.jsx)(gc,{icon:n.ar,title:n.st(f),children:`This is not taking bookings at the moment.`})});let B=!!f.paymentId&&!p&&(!h||!g.loading&&!g.configured);return(0,l.jsxs)(hc,{children:[z&&(0,l.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,l.jsxs)(`div`,{className:`flex flex-col gap-1.5 mb-6`,children:[s?.appName&&(0,l.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-[0.2em] text-foreground/40`,children:s.appName}),(0,l.jsx)(`h1`,{className:`text-2xl sm:text-3xl md:text-4xl font-extrabold text-foreground tracking-tight`,children:f.name.trim()||`Book a time`}),(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-1 text-[13px] font-semibold text-foreground/60`,children:[(0,l.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,l.jsx)(n.Bt,{className:`w-3.5 h-3.5 text-accent`}),`with `,f.memberName]}),(0,l.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,l.jsx)(n.Kn,{className:`w-3.5 h-3.5 text-accent`}),n.pt(f.slotMinutes)]}),h&&(0,l.jsx)(`span`,{className:`inline-flex items-center gap-1.5 text-foreground`,children:pc(h.amount)})]}),f.description.trim()&&(0,l.jsx)(`p`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed mt-2 max-w-2xl whitespace-pre-line`,children:f.description.trim()})]}),B?(0,l.jsx)(`p`,{className:`text-[14px] font-medium text-foreground/60`,children:`This booking cannot be paid for right now — please try again later.`}):S?(0,l.jsxs)(`div`,{className:`flex flex-col gap-5 max-w-[520px]`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-xl px-4 py-3 glass-panel`,style:{borderRadius:`var(--input-radius, 0.75rem)`},children:[(0,l.jsx)(`span`,{className:`text-[14px] font-semibold text-foreground truncate`,children:n.U(S,f.memberName,_)}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>C(null),className:`text-[12.5px] font-bold text-accent hover:underline shrink-0 cursor-pointer`,children:`Change`})]}),(0,l.jsx)(t.g,{label:`Your name`,value:w,onChange:e=>T(e.target.value),error:A.name,placeholder:`Jane Doe`}),(0,l.jsx)(t.g,{label:`Your email`,type:`email`,value:E,onChange:e=>D(e.target.value),error:A.email,placeholder:`jane@example.com`}),(0,l.jsxs)(`div`,{className:`flex flex-col w-full`,children:[(0,l.jsxs)(`label`,{className:`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,children:[`Anything we should know? `,(0,l.jsx)(`span`,{className:`text-foreground/35`,children:`(optional)`})]}),(0,l.jsx)(`textarea`,{rows:3,value:O,onChange:e=>k(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 glass-panel min-h-[90px] resize-none`})]}),P&&(0,l.jsx)(`p`,{role:`alert`,className:`text-[13px] font-semibold text-red-500`,children:P}),(0,l.jsx)(t.h,{variant:`primary`,onClick:async()=>{if(!S||M)return;let e={};if(w.trim()||(e.name=`Your name, please.`),uc.test(E.trim())||(e.email=`That does not look like an email address — check for a typo, e.g. jane@example.com`),j(e),Object.keys(e).length)return;N(!0),F(``);let i=n.U(S,f.memberName,_),a=await t.r(S);if(a){F(a),C(null),N(!1);return}let s=``;try{let e=n.xr.currentUser;s=(await(0,o.addDoc)((0,o.collection)(n.Sr,`user_submissions`),{name:w.trim(),email:E.trim(),...O.trim()?{note:O.trim()}:{},...n.R(`time`,S,f.memberName,_),schedule:n.st(f),...e?{uid:e.uid,submitterName:e.displayName||``,submitterEmail:e.email||``,submitterAvatar:e.photoURL||``}:{uid:`guest`},formId:dc,submittedAt:(0,o.serverTimestamp)()})).id}catch(e){console.error(`Could not save the booking entry`,e),await t.i(S),F(`The booking could not be saved — check your connection and try again.`),N(!1);return}let c=null;if(h){let e=await r.S({amount:h.amount,productName:`${n.st(f)} — ${i}`,metadata:{bookingId:n.dt(S.memberId,S.start),scheduleId:f.id,page:n.H(f.id),when:i,emailReceipt:m?.emailReceipt===!1?`no`:`yes`,notifyOwner:m?.notifyOwner===!1?`no`:`yes`},successPath:n.H(f.id),cancelPath:`${n.H(f.id)}?cancelled=1`});if(typeof e==`string`){await t.i(S),F(e),N(!1);return}c=e}let l=await t.f(S,{memberName:f.memberName,scheduleId:f.id,scheduleName:f.name,paymentId:f.paymentId,paymentSession:c?.sessionId||``,timeZone:_,name:w.trim(),email:E.trim(),answers:O.trim()?{note:O.trim()}:{},formId:dc,entryId:s});if(l&&console.warn(l),c){r.b.goTo(c.url);return}ki(`heads_up`,{title:`New booking`,summary:`${w.trim()} booked ${n.st(f)} — ${i}`,details:{Name:w.trim(),Email:E.trim(),When:i,...O.trim()?{Note:O.trim()}:{}}}).catch(()=>{}),L(i),N(!1)},disabled:M||p,className:`w-full py-3 text-[14px] font-bold`,children:M?h?`Opening checkout…`:`Booking…`:h?`Book and pay ${pc(h.amount)}`:`Confirm booking`})]}):(0,l.jsxs)(l.Fragment,{children:[P&&(0,l.jsx)(`p`,{role:`alert`,className:`mb-3 text-[13px] font-semibold text-red-500`,children:P}),(0,l.jsx)(t.p,{members:x,value:S,onChange:C,taken:b,timeZone:_,onTimeZone:v})]})]})}function yc({children:e,className:n,variant:i=`primary`,pendingLabel:o=`Opening checkout…`,...s}){let{loading:c,configured:u}=r.D(),[d,f]=(0,a.useState)(!1),[p,m]=(0,a.useState)(null);return c||!u?null:(0,l.jsxs)(`span`,{className:`inline-flex flex-col items-stretch gap-2`,children:[(0,l.jsx)(t.h,{variant:i,className:n,onClick:async()=>{if(d)return;f(!0),m(null);let e=await r.T(s);e&&(m(e),f(!1))},disabled:d,children:d?o:e??`Pay`}),p&&(0,l.jsx)(`span`,{role:`alert`,className:`text-[13px] font-semibold text-red-400 leading-snug`,children:p})]})}function bc(){let{id:e=``}=(0,u.useParams)(),{activeConfig:i}=t.y(),s=r.D(),[c,d]=(0,a.useState)({loading:!0,product:null});(0,a.useEffect)(()=>{let t=!1;return(0,o.getDoc)((0,o.doc)(n.Sr,Dr,e)).then(e=>{t||d({loading:!1,product:e.exists()?zr(e.id,e.data()):null})}).catch(()=>{t||d({loading:!1,product:null})}),()=>{t=!0}},[e]);let f=c.product,p=f?.customPath.trim()||``;if(p)return(0,l.jsx)(u.Navigate,{to:p.startsWith(`/`)?p:`/${p}`,replace:!0});let m=f?Nr(f).filter(e=>Pr(e.amount)):[],h=f?.name.trim()||m[0]?.name.trim()||`Pay`;return(0,l.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,l.jsx)(n.kt.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:c.loading?(0,l.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-16 text-foreground/50`,children:[(0,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin text-accent`}),(0,l.jsx)(`span`,{className:`text-[13px] font-medium`,children:`Loading…`})]}):!f||f.kind!==`once`||!m.length?(0,l.jsxs)(`div`,{className:`flex flex-col items-center text-center py-8 gap-4`,children:[(0,l.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,l.jsx)(n.Zt,{className:`w-7 h-7 text-accent`})}),(0,l.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold text-foreground tracking-tight`,children:`This payment link is no longer open`}),(0,l.jsx)(`p`,{className:`text-[14px] text-foreground/60 max-w-md`,children:`Ask whoever sent it for a new one.`}),(0,l.jsx)(u.Link,{to:`/`,className:`text-[13px] font-bold text-accent hover:underline mt-2`,children:`Back to the site`})]}):(0,l.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[i?.appName&&(0,l.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-[0.2em] text-foreground/40`,children:i.appName}),(0,l.jsx)(`h1`,{className:`text-2xl sm:text-3xl md:text-4xl font-extrabold text-foreground tracking-tight`,children:h}),f.description.trim()&&(0,l.jsx)(`p`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed mt-1 max-w-2xl whitespace-pre-line`,children:f.description.trim()})]}),!s.loading&&!s.configured&&(0,l.jsx)(`p`,{className:`text-[14px] font-medium text-foreground/60`,children:`Payments are not open right now — please try again later.`}),(0,l.jsx)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60`,children:m.map((e,t)=>(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-4 px-4 py-3.5`,children:[(0,l.jsxs)(`div`,{className:`min-w-0 flex flex-col`,children:[(0,l.jsx)(`span`,{className:`text-[15px] font-semibold text-foreground truncate`,children:e.name.trim()||h}),(0,l.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/50`,children:pc(Pr(e.amount)||0)})]}),(0,l.jsxs)(yc,{amount:Pr(e.amount)||0,productName:e.name.trim()||h,metadata:{productId:f.id,page:n.et(f.id),emailReceipt:f.emailReceipt?`yes`:`no`,notifyOwner:f.notifyOwner?`yes`:`no`},successPath:`/payment-complete`,cancelPath:n.et(f.id),className:`px-5 py-2.5 text-[14px] font-bold`,children:[`Pay `,pc(Pr(e.amount)||0)]})]},t))})]})})})}var{collection:xc,doc:Sc}=Ds.email,Cc=(e,t)=>{let n=String(e||``).trim().toLowerCase(),r=String(t||``).trim().toLowerCase();return!!n&&n===r};function wc(){let[e,t]=(0,a.useState)({loading:!0,testedFrom:null});return(0,a.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(n.Sr,xc,Sc),e=>{let n=e.exists()?e.data()?.testedFrom:null;t({loading:!1,testedFrom:typeof n==`string`&&n.trim()?n:null})},()=>t({loading:!1,testedFrom:null})),[]),{loading:e.loading,testedFrom:e.testedFrom,mark:async e=>{if(e.trim()){t({loading:!1,testedFrom:e});try{await(0,o.setDoc)((0,o.doc)(n.Sr,xc,Sc),{testedFrom:e},{merge:!0})}catch(e){console.error(`Could not remember the test send`,e)}}}}}var Tc=e=>[{title:`Hear about what happens`,body:`A booking, a form entry, a new member — at your address the moment it happens.`,icon:n.lr,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:n.gn,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:n.on,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:n.tn,where:{path:`/pages`,label:`Pages screen`}}],Ec=e=>String(e||``).toLowerCase().endsWith(`@resend.dev`),Dc=e=>String(e||``).split(`@`)[1]||``,Oc=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 kc({children:e,tone:t=`quiet`}){return(0,l.jsx)(`p`,{className:`text-[12.5px] font-medium leading-relaxed px-1 ${t===`error`?`text-red-500`:`text-foreground/50`}`,children:e})}function Ac({from:e}){return(0,l.jsx)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60`,children:Tc(e).map(e=>{let t=e.icon;return(0,l.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,l.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,l.jsx)(t,{className:`w-4 h-4`})}),(0,l.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,l.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,l.jsxs)(u.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,l.jsx)(n.pr,{className:`w-3 h-3`})]})]},e.title)})})}function jc(){let[e,t]=(0,a.useState)(null),[i,o]=(0,a.useState)(``),s=ks(`email`),[c,d]=(0,a.useState)(``),f=wc();(0,a.useEffect)(()=>{let e=!1;return fetch(`/api/email/status`).then(e=>e.json()).then(n=>{e||t({configured:!!n?.configured,from:n?.from??null,adminCount:Number(n?.adminCount)||0})}).catch(()=>{e||o(`The server could not be reached.`)}),()=>{e=!0}},[]);let p=!!(e&&!e.configured),m=Ec(e?.from),h=Oc(s.on),g=!f.loading&&Cc(f.testedFrom,e?.from);return(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`Email`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/email`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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&&!i?(0,l.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,l.jsx)(n.yn,{className:`w-6 h-6 animate-spin text-accent`})}):p?(0,l.jsxs)(n.u,{icon:n.hn,title:`Connect email`,description:`This app is not sending email yet.`,collapsible:!1,children:[(0,l.jsx)(kc,{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,l.jsxs)(u.Link,{to:`/setup`,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]`,children:[`Set up email`,(0,l.jsx)(n.pr,{className:`w-3.5 h-3.5`})]})]}):(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsx)(n.p,{icon:n.sn,title:`Send email`,description:h.description,chip:h.chip,enabled:s.loading?null:s.on,onChange:async e=>d(await s.set(e)||``),children:c?(0,l.jsx)(kc,{tone:`error`,children:c}):null}),(0,l.jsx)(n.u,{icon:n.gn,title:`Connection`,description:g&&!i?`Mail goes out as ${e?.from}.`:`Whether this app can send email right now.`,defaultOpen:!g||!e?.adminCount,actions:i?(0,l.jsx)(n.f,{state:`error`,label:`Unreachable`}):(0,l.jsx)(n.f,{state:`saved`,label:`Connected`}),children:i?(0,l.jsx)(kc,{tone:`error`,children:i}):g?(0,l.jsxs)(`div`,{className:`flex items-center gap-2.5 px-1 flex-wrap`,children:[(0,l.jsx)(n.f,{state:e?.adminCount?`saved`:`off`,label:e?.adminCount?`Your mail reaches ${e.adminCount} address${e.adminCount===1?``:`es`}`:`No address for your mail`}),!e?.adminCount&&(0,l.jsxs)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Sale alerts and form alerts have nowhere to go —`,` `,(0,l.jsx)(u.Link,{to:`/setup`,className:`text-accent font-bold hover:underline`,children:`add ADMIN_EMAILS on the setup page`}),`.`]})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)(kc,{children:[`Mail goes out as `,(0,l.jsx)(`span`,{className:`font-bold text-foreground/70`,children:e?.from}),`.`,m?` That is Resend’s shared practice address — fine for testing, but it often lands in spam. Before launch, verify your own domain in Resend and add EMAIL_FROM on the setup page.`:` That only works if ${Dc(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.`]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2.5 px-1 flex-wrap`,children:[(0,l.jsx)(n.f,{state:e?.adminCount?`saved`:`off`,label:e?.adminCount?`Your mail reaches ${e.adminCount} address${e.adminCount===1?``:`es`}`:`No address for your mail`}),!e?.adminCount&&(0,l.jsxs)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Sale alerts and form alerts have nowhere to go —`,` `,(0,l.jsx)(u.Link,{to:`/setup`,className:`text-accent font-bold hover:underline`,children:`add ADMIN_EMAILS on the setup page`}),`.`]})]}),(0,l.jsx)(`div`,{className:`px-1`,children:(0,l.jsx)(r.c,{onSent:t=>f.mark(t||e?.from||``),trailing:(0,l.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,l.jsx)(n.Rn,{className:`w-3 h-3`})]})})})]})}),(0,l.jsx)(n.u,{icon:n.Xt,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,l.jsx)(Ac,{from:e?.from||``})})]})})]})]})}var Mc=`src/your-ai-workflow-firebase-os`;function Nc(){let e=new Set;for(let[t,n]of S()){let r=n?.config?.route,i=typeof r==`string`&&r.trim()?r.startsWith(`/`)?r:`/`+r:`/`+t.toLowerCase();e.add(i)}return[...e].sort()}var Pc=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``);function Fc(e){let t=e?.contentKey||e?.tabName||e?.pageName||e?.pageId||`Page`;return`${Mc}/microcomponents/${Pc(String(t))||`Page`}Content.tsx`}function Ic(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 ${Mc}/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. ${Mc}/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(`
|
|
27
|
-
`)}function
|
|
28
|
-
`)}function Rc({config:e,customContent:i}){let{config:o}=t.y(),{userRole:s}=r.j();return(0,a.useEffect)(()=>{document.title=e.pageName||e.pageTitle||o.appName||`Your AI Firebase`},[e.pageName,e.pageTitle,o.appName]),(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[(0,l.jsx)(Ne,{}),(0,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(r.y,{children:e.pageTitle||e.pageName||`New Page`}),e.route&&(0,l.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,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})]}),(0,l.jsx)(n.kt.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:i?(0,l.jsx)(`div`,{className:`fbos-content-slot flex-1 p-4 md:p-8`,children:(0,l.jsx)(i,{config:e})}):e.form?(0,l.jsx)(`div`,{className:`fbos-content-slot flex-1 flex flex-col items-center justify-start p-4 md:p-8`,children:(0,l.jsx)(t.t,{isInline:!0,formId:e.form})}):(0,l.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center m-4 md:m-8 gap-6`,children:[(0,l.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,l.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/70`,children:`This page is empty`}),(0,l.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.`})]}),r.L(s)&&(0,l.jsx)(`div`,{className:`w-full max-w-lg`,children:(0,l.jsx)(r.g,{compact:!0,title:`Already asked, and it is still empty? Paste this`,prompt:Ic(e.route||`/`,Fc(e))})})]})})]})}function zc({config:e,customContent:i}){let{user:s}=r.j(),{config:u}=t.y(),[f,p]=(0,a.useState)([]),[m,h]=(0,a.useState)(!0),[g,_]=(0,a.useState)(!1),[v,y]=(0,a.useState)(``),[b,x]=(0,a.useState)(``),[S,C]=(0,a.useState)(!1),[w,T]=(0,a.useState)(null),E=(0,a.useRef)(null),[D,O]=(0,a.useState)(!1),[k,A]=(0,a.useState)(null),[j,M]=(0,a.useState)(null),N=e=>{if(M(e),e){let t=e.fileType||``;I(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},P=j,[F,I]=(0,a.useState)(!0),[L,R]=(0,a.useState)(!1),[z,B]=(0,a.useState)(null),[V,H]=(0,a.useState)(``),[U,ee]=(0,a.useState)(``),[W,G]=(0,a.useState)([]),K=(0,a.useRef)(null),q=`user_${(e.tabName||e.pageId||`user_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`)}_records`;(0,a.useEffect)(()=>{document.title=e.tabTitle||e.tabName||u.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,u.appName]),(0,a.useEffect)(()=>{if(!s)return;try{let e=localStorage.getItem(`fbos_records_${q}`);e?(p(JSON.parse(e)),h(!1)):h(!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}}),t=(0,o.onSnapshot)((0,o.query)((0,o.collection)(n.Sr,q),(0,o.where)(`uid`,`==`,s.uid),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),p(n),h(!1),localStorage.setItem(`fbos_records_${q}`,JSON.stringify(n))},e=>{console.error(`Error fetching records:`,e),h(!1)});return()=>t()},[s,q]),(0,a.useEffect)(()=>{m||localStorage.setItem(`fbos_records_${q}`,JSON.stringify(f))},[f,m,q]);let J=async e=>{if(e.preventDefault(),!(!s||!v.trim())){C(!0);try{let e=await(0,o.addDoc)((0,o.collection)(n.Sr,q),{name:v.trim(),note:b.trim(),uid:s.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)()});p(t=>[{id:e.id,name:v.trim(),note:b.trim(),uid:s.uid,recordType:`record`,createdAt:Date.now()},...t]),y(``),x(``),_(!1)}catch(e){console.error(`Error saving record:`,e)}C(!1)}},Y=async e=>{let t=e.target.files?.[0];if(!t||!s)return;let r=await n.Tt(t);O(!0);try{let e=`user_files/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,t=(0,c.ref)(n.wr,e);await(0,c.uploadBytes)(t,r,{customMetadata:{ownerId:s.uid}});let i=await(0,c.getDownloadURL)(t);if(E.current)E.current(r,i,{uid:s.uid,storagePath:e});else{let e=await(0,o.addDoc)((0,o.collection)(n.Sr,q),{name:r.name,note:`${r.type||`File`} · ${_e(r.size)}`,uid:s.uid,recordType:`file`,fileName:r.name,fileType:r.type||`unknown`,fileSize:r.size,downloadURL:i,createdAt:(0,o.serverTimestamp)()});p(t=>[{id:e.id,name:r.name,note:`${r.type||`File`} · ${_e(r.size)}`,uid:s.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)}O(!1),K.current&&(K.current.value=``)},X=async()=>{if(k){R(!0);try{let e=f.find(e=>e.id===k);if(await(0,o.deleteDoc)((0,o.doc)(n.Sr,q,k)),e?.recordType===`file`&&e.downloadURL)try{let t=e.downloadURL.split(`user_files%2F`)[1]?.split(`?`)[0];t&&await(0,c.deleteObject)((0,c.ref)(n.wr,`user_files/${decodeURIComponent(t)}`)).catch(()=>{})}catch(e){console.error(`Error cleaning up user file:`,e)}p(e=>e.filter(e=>e.id!==k)),A(null)}catch(e){console.error(`Error deleting record:`,e)}R(!1)}},[te,ne]=(0,a.useState)(null),[re,ie]=(0,a.useState)(``),[ae,Z]=(0,a.useState)(!1),[oe,Q]=(0,a.useState)(null),ce=(0,a.useRef)([]),le=e=>{if(e.recordType===`file`){ne(e.id),ie(e.name);return}B(e.id),H(e.name),ee(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??``)}));G(n),ce.current=n.map(e=>e.key)},ue=async()=>{if(!te||!re.trim()){ne(null);return}let e=f.find(e=>e.id===te);if(e&&e.name===re.trim()){ne(null);return}Z(!0);try{await(0,o.updateDoc)((0,o.doc)(n.Sr,q,te),{name:re.trim()}),p(e=>e.map(e=>e.id===te?{...e,name:re.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}Z(!1),ne(null)},de=async()=>{await fe(),B(null)},fe=async()=>{if(!z||!V.trim())return;C(!0);let e={};W.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let t=W.map(e=>e.key.trim()).filter(Boolean),r=ce.current.filter(e=>!t.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(n.Sr,q,z),{name:V.trim(),note:U.trim(),...e}),p(e=>e.map(e=>{if(e.id!==z)return e;let t={...e,name:V.trim(),note:U.trim()};return r.forEach(e=>{delete t[e]}),W.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),ce.current=t}catch(e){console.error(`Error saving record:`,e)}C(!1)},pe=(e,t)=>e?e.startsWith(`image/`)?t?(0,l.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${t})`}}):(0,l.jsx)(n.An,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,l.jsx)(n.Lt,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,l.jsx)(n.Pn,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,l.jsx)(n._r,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,l.jsx)(n.Wn,{className:`w-4 h-4`}):(0,l.jsx)(n.Nn,{className:`w-4 h-4`}):(0,l.jsx)(n.Pn,{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-purple-500/10 text-purple-500`: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 t=(e.buttonStorageIcon||`upload`).trim(),r=t.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return n.jt[r]?n.jt[r]:n.jt[t]?n.jt[t]:n.Vt||n.cn})(),be=e.buttonStyle!==`secondary`,xe=e.buttonStorageStyle===`primary`;return(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:e.tabTitle||e.tabName||`User Page`}),e.route&&(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.jsxs)(n.kt.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,l.jsx)(`input`,{type:`file`,ref:K,onChange:Y,className:`hidden`}),!i&&(0,l.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,l.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,l.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:m?`Loading…`:`${f.length} ${f.length===1?`item`:`items`}`})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>K.current?.click(),disabled:D,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:[D?(0,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin`}):(0,l.jsx)(ye,{className:`w-4 h-4`}),e.buttonStorageText&&(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,l.jsx)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>_(!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,l.jsx)(n.cn,{className:`w-4 h-4`}):(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,l.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[m&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,l.jsx)(n.yn,{className:`w-8 h-8 text-accent animate-spin`})}),i?(0,l.jsx)(`div`,{className:`fbos-content-slot`,children:(0,l.jsx)(i,{config:e,actions:{records:f,loading:m,collection:q,user:s,saveRecord:async e=>{let t=(0,o.doc)((0,o.collection)(n.Sr,q)),r={id:t.id,uid:s.uid,recordType:`record`,createdAt:Date.now(),...e};p(e=>[r,...e]),await(0,o.setDoc)(t,{uid:s.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,t)=>{p(n=>n.map(n=>n.id===e?{...n,...t}:n)),await(0,o.updateDoc)((0,o.doc)(n.Sr,q,e),t)},deleteRecord:async e=>{await(0,o.deleteDoc)((0,o.doc)(n.Sr,q,e))},startEdit:e=>le(e),confirmDelete:e=>A(e),uploadFile:()=>K.current?.click(),openAddForm:()=>_(!0),setAddForm:e=>T(()=>e),setFileHandler:e=>{E.current=e}}})}):(0,l.jsxs)(l.Fragment,{children:[!m&&f.length===0&&(0,l.jsxs)(n.kt.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,l.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,l.jsx)(n.cn,{className:`w-6 h-6 text-accent/40`})}),(0,l.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,l.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`})]}),!m&&f.length>0&&(0,l.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,l.jsx)(n.At,{children:f.map((e,t)=>{let r=z===e.id;return(0,l.jsxs)(n.kt.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},transition:{delay:t*.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,l.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,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),Q(e.id),setTimeout(()=>Q(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,l.jsx)(n.nr,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-3.5 h-3.5`})}),(0,l.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,l.jsx)(n.Bn,{className:`w-3.5 h-3.5`})})]}),(0,l.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,l.jsx)(n.un,{className:`w-3.5 h-3.5`})}),(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),A(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,l.jsx)(n.Gt,{className:`w-3.5 h-3.5`})})]}),(0,l.jsxs)(`div`,{className:`flex items-start gap-3 mb-3`,children:[(0,l.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&N(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`?pe(e.fileType,e.downloadURL):(0,l.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,l.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[te===e.id?(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,value:re,onChange:e=>ie(e.target.value),onBlur:()=>ue(),onKeyDown:e=>{e.key===`Enter`&&ue(),e.key===`Escape`&&ne(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,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>N(e)}),(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:ve(e.createdAt)})]})]}),e.note&&(0,l.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,l.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,l.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e))]},e.id)})})})]})]})]})]}),(0,l.jsx)(n.At,{children:g&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>!S&&_(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,l.jsx)(n.kt.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:w?a.default.createElement(w,{onSave:async e=>{C(!0);try{await(0,o.addDoc)((0,o.collection)(n.Sr,q),{uid:s.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)(),...e}),_(!1)}catch(e){console.error(`Error saving record:`,e)}C(!1)},onClose:()=>!S&&_(!1),saving:S}):(0,l.jsxs)(`form`,{onSubmit:J,className:`p-5 flex flex-col gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>!S&&_(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:v,onChange:e=>y(e.target.value),placeholder:`Name *`,disabled:S,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,l.jsx)(`textarea`,{value:b,onChange:e=>x(e.target.value),placeholder:`Note (optional)`,disabled:S,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,l.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,l.jsx)(t.h,{type:`submit`,isLoading:S,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:S?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,d.createPortal)((0,l.jsx)(n.At,{children:P&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>N(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,l.jsx)(`button`,{onClick:()=>N(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,l.jsx)(n.Pt,{className:`w-5 h-5`})}),(0,l.jsxs)(n.kt.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,l.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,l.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,l.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:P.fileName||P.name}),(0,l.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[ge(P.fileType),` • `,_e(P.fileSize||0)]})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,l.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(P.downloadURL),Q(`preview`),setTimeout(()=>Q(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,l.jsx)(n.nr,{className:`w-4 h-4 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),ne(P.id),ie(P.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,l.jsx)(n.un,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),A(P.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,l.jsx)(n.Gt,{className:`w-4 h-4`})}),(0,l.jsx)(`a`,{href:P.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,l.jsx)(n.Bn,{className:`w-4 h-4`})})]})]}),(0,l.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>N(null),children:(0,l.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[F&&(0,l.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,l.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,l.jsx)(n.yn,{className:`w-5 h-5 text-accent animate-spin`})})}),P.fileType?.startsWith(`image/`)?(0,l.jsx)(`img`,{onLoad:()=>I(!1),onError:()=>I(!1),src:P.downloadURL,alt:P.fileName||P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType?.startsWith(`video/`)?(0,l.jsx)(`video`,{onLoadedData:()=>I(!1),onError:()=>I(!1),src:P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType===`application/pdf`?(0,l.jsx)(`iframe`,{onLoad:()=>I(!1),src:P.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${F?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,l.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(),I(!1)},children:[(0,l.jsx)(n.Pn,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,l.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,l.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,l.jsx)(n.At,{children:z&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.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,l.jsx)(n.kt.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,l.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),S&&(0,l.jsx)(n.yn,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>de(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`input`,{autoFocus:!0,required:!0,value:V,onChange:e=>H(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:U,onChange:e=>{ee(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),W.map((e,t)=>(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let n=[...W];n[t].key=e.target.value,G(n)},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,l.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let n=[...W];n[t].value=e.target.value,G(n)},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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>G(W.filter((e,n)=>n!==t)),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,l.jsx)(n.Pt,{className:`w-3 h-3`})})]},t)),(0,l.jsxs)(`button`,{type:`button`,onClick:()=>G([...W,{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,l.jsx)(n.cn,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,l.jsx)(me,{isOpen:!!k,onCancel:()=>A(null),onConfirm:X,title:`Delete Record`,message:(0,l.jsxs)(l.Fragment,{children:[`Are you sure you want to delete `,(0,l.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:f.find(e=>e.id===k)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:L})]})}function Bc({config:e,customContent:i}){let{user:s}=r.j(),{config:u}=t.y(),[f,p]=(0,a.useState)([]),[m,h]=(0,a.useState)(!0),[g,_]=(0,a.useState)(!1),[v,y]=(0,a.useState)(``),[b,x]=(0,a.useState)(``),[S,C]=(0,a.useState)(!1),[w,T]=(0,a.useState)(null),E=(0,a.useRef)(null),[D,O]=(0,a.useState)(!1),[k,A]=(0,a.useState)(null),[j,M]=(0,a.useState)(null),N=e=>{if(M(e),e){let t=e.fileType||``;I(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},P=j,[F,I]=(0,a.useState)(!0),[L,R]=(0,a.useState)(!1),[z,B]=(0,a.useState)(null),[V,H]=(0,a.useState)(``),[U,ee]=(0,a.useState)(``),[W,G]=(0,a.useState)([]),K=(0,a.useRef)(null),[q,J]=(0,a.useState)(null),Y=(0,a.useRef)([]),X=`admin_${(e.tabName||e.pageId||`admin_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`)}_records`;(0,a.useEffect)(()=>{document.title=e.tabTitle||e.tabName||u.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,u.appName]);let te=()=>({name:s.displayName||s.email?.split(`@`)[0]||`Admin`,email:s.email||``,avatar:s.photoURL||``});(0,a.useEffect)(()=>{if(!s)return;try{let e=localStorage.getItem(`fbos_records_${X}`);e?(p(JSON.parse(e)),h(!1)):h(!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}}),t=(0,o.onSnapshot)((0,o.query)((0,o.collection)(n.Sr,X),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(150)),t=>{let n=e(t.docs);p(n),h(!1),localStorage.setItem(`fbos_records_${X}`,JSON.stringify(n))},t=>{console.error(`Error listening to admin records:`,t);let r=(0,o.onSnapshot)((0,o.query)((0,o.collection)(n.Sr,X),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),p(n),h(!1),localStorage.setItem(`fbos_records_${X}`,JSON.stringify(n))});return()=>r()});return()=>t()},[s,X]);let ne=async e=>{if(e.preventDefault(),!(!s||!v.trim())){C(!0);try{let e=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{name:v.trim(),note:b.trim(),uid:s.uid,recordType:`record`,creatorName:e.name,creatorEmail:e.email,creatorAvatar:e.avatar,createdAt:(0,o.serverTimestamp)()}),y(``),x(``),_(!1)}catch(e){console.error(`Error saving admin record:`,e)}C(!1)}},re=async e=>{let t=e.target.files?.[0];if(!t||!s)return;let r=await n.Tt(t);O(!0);try{let e=`admin_files/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,t=(0,c.ref)(n.wr,e);await(0,c.uploadBytes)(t,r,{customMetadata:{ownerId:s.uid}});let i=await(0,c.getDownloadURL)(t);if(E.current)E.current(r,i,{uid:s.uid,storagePath:e});else{let e=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{name:r.name,note:`${r.type||`File`} · ${ve(r.size)}`,uid:s.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)}O(!1),K.current&&(K.current.value=``)},ie=async()=>{if(k){R(!0);try{let e=f.find(e=>e.id===k);if(await(0,o.deleteDoc)((0,o.doc)(n.Sr,X,k)),e?.recordType===`file`&&e.downloadURL)try{let t=e.downloadURL.split(`admin_files%2F`)[1]?.split(`?`)[0];t&&await(0,c.deleteObject)((0,c.ref)(n.wr,`admin_files/${decodeURIComponent(t)}`)).catch(()=>{})}catch(e){console.error(`Error cleaning up admin file:`,e)}A(null)}catch(e){console.error(`Error deleting admin record:`,e)}R(!1)}},[ae,Z]=(0,a.useState)(null),[oe,Q]=(0,a.useState)(``),[ce,le]=(0,a.useState)(!1),ue=e=>{if(e.recordType===`file`){Z(e.id),Q(e.name);return}B(e.id),H(e.name),ee(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??``)}));G(n),Y.current=n.map(e=>e.key)},de=async()=>{if(!ae||!oe.trim()){Z(null);return}let e=f.find(e=>e.id===ae);if(e&&e.name===oe.trim()){Z(null);return}le(!0);try{await(0,o.updateDoc)((0,o.doc)(n.Sr,X,ae),{name:oe.trim()}),p(e=>e.map(e=>e.id===ae?{...e,name:oe.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}le(!1),Z(null)},fe=async()=>{if(!z||!V.trim()){B(null);return}C(!0);let e={};W.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let t=W.map(e=>e.key.trim()).filter(Boolean),r=Y.current.filter(e=>!t.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(n.Sr,X,z),{name:V.trim(),note:U.trim(),...e}),p(e=>e.map(e=>{if(e.id!==z)return e;let t={...e,name:V.trim(),note:U.trim()};return r.forEach(e=>{delete t[e]}),W.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),Y.current=t}catch(e){console.error(`Error updating record:`,e)}C(!1),B(null)},pe=async()=>{if(!z||!V.trim())return;let e={};W.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let t=W.map(e=>e.key.trim()).filter(Boolean),r=Y.current.filter(e=>!t.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(n.Sr,X,z),{name:V.trim(),note:U.trim(),...e}),p(e=>e.map(e=>{if(e.id!==z)return e;let t={...e,name:V.trim(),note:U.trim()};return r.forEach(e=>{delete t[e]}),W.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),Y.current=t}catch(e){console.error(`Error silently saving record:`,e)}},he=(e,t)=>e?e.startsWith(`image/`)?t?(0,l.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${t})`}}):(0,l.jsx)(n.An,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,l.jsx)(n.Lt,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,l.jsx)(n.Pn,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,l.jsx)(n._r,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,l.jsx)(n.Wn,{className:`w-4 h-4`}):(0,l.jsx)(n.Nn,{className:`w-4 h-4`}):(0,l.jsx)(n.Pn,{className:`w-4 h-4`}),ge=e=>e?e.startsWith(`image/`)?`bg-emerald-500/10 text-emerald-500`:e.startsWith(`video/`)||e.startsWith(`audio/`)?`bg-purple-500/10 text-purple-500`: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`,_e=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)},ve=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]},ye=e=>{if(!e)return``;let t=e.toMillis?e.toMillis():e;return new Date(t).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})},be=(()=>{let t=(e.buttonStorageIcon||`upload`).trim(),r=t.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return n.jt[r]?n.jt[r]:n.jt[t]?n.jt[t]:n.Vt||n.cn})(),xe=e.buttonStyle!==`secondary`,Se=e.buttonStorageStyle===`primary`,Ce=e=>e.uid===s?.uid,we=({record:e})=>{let t=e.creatorName||e.creatorEmail?.split(`@`)[0]||`Admin`,n=e.creatorEmail||``,r=e.creatorAvatar||``,i=t.split(` `).map(e=>e[0]).join(``).toUpperCase().slice(0,2);return(0,l.jsxs)(`div`,{className:`flex items-center gap-2 mt-2 pt-2 border-t border-[var(--panel-border)]/30`,children:[r?(0,l.jsx)(`img`,{src:r,alt:``,className:`w-5 h-5 rounded-full object-cover shrink-0`}):(0,l.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:i}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 flex-1`,children:[(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 truncate`,children:t}),n&&(0,l.jsxs)(`span`,{className:`text-[10px] text-foreground/25 truncate`,children:[`· `,n]})]})]})};return(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:e.tabTitle||e.tabName||`Admin Page`}),e.route&&(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.jsxs)(n.kt.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,l.jsx)(`input`,{type:`file`,ref:K,onChange:re,className:`hidden`}),!i&&(0,l.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,l.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,l.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:m?`Loading…`:`${f.length} ${f.length===1?`item`:`items`}`})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>K.current?.click(),disabled:D,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`} ${Se?`btn-primary`:`btn-secondary`}`,children:[D?(0,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin`}):(0,l.jsx)(be,{className:`w-4 h-4`}),e.buttonStorageText&&(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,l.jsx)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>_(!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`} ${xe?`btn-primary`:`btn-secondary`}`,children:e.buttonText===`+`||!e.buttonText?(0,l.jsx)(n.cn,{className:`w-4 h-4`}):(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,l.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[m&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,l.jsx)(n.yn,{className:`w-8 h-8 text-accent animate-spin`})}),i?(0,l.jsx)(`div`,{className:`fbos-content-slot`,children:(0,l.jsx)(i,{config:e,actions:{records:f,loading:m,collection:X,user:s,saveRecord:async e=>{let t=(0,o.doc)((0,o.collection)(n.Sr,X)),r=te(),i={id:t.id,uid:s.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:Date.now(),...e};p(e=>[i,...e]),await(0,o.setDoc)(t,{uid:s.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,t)=>{p(n=>n.map(n=>n.id===e?{...n,...t}:n)),await(0,o.updateDoc)((0,o.doc)(n.Sr,X,e),t)},deleteRecord:async e=>{await(0,o.deleteDoc)((0,o.doc)(n.Sr,X,e))},startEdit:e=>ue(e),confirmDelete:e=>A(e),uploadFile:()=>K.current?.click(),openAddForm:()=>_(!0),setAddForm:e=>T(()=>e),setFileHandler:e=>{E.current=e}}})}):(0,l.jsxs)(l.Fragment,{children:[!m&&f.length===0&&(0,l.jsxs)(n.kt.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,l.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,l.jsx)(n.cn,{className:`w-6 h-6 text-accent/40`})}),(0,l.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,l.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.`})]}),!m&&f.length>0&&(0,l.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,l.jsx)(n.At,{children:f.map((e,t)=>{let r=z===e.id,i=Ce(e);return(0,l.jsxs)(n.kt.div,{initial:!1,animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},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,l.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,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),J(e.id),setTimeout(()=>J(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:q===e.id?(0,l.jsx)(n.nr,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-3.5 h-3.5`})}),(0,l.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,l.jsx)(n.Bn,{className:`w-3.5 h-3.5`})})]}),i&&(0,l.jsxs)(l.Fragment,{children:[(0,l.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,l.jsx)(n.un,{className:`w-3.5 h-3.5`})}),(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),A(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,l.jsx)(n.Gt,{className:`w-3.5 h-3.5`})})]})]}),(0,l.jsxs)(`div`,{className:`flex items-start gap-3 mb-2`,children:[(0,l.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&N(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 ${ge(e.fileType)}`:`bg-accent/10 text-accent`}`,children:e.recordType===`file`?he(e.fileType,e.downloadURL):(0,l.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,l.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[ae===e.id?(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,value:oe,onChange:e=>Q(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,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>N(e)}),(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:ye(e.createdAt)})]})]}),e.note&&(0,l.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,l.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,l.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e)),(0,l.jsx)(we,{record:e})]},e.id)})})})]})]})]})]}),(0,l.jsx)(n.At,{children:g&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>!S&&_(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,l.jsx)(n.kt.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:w?a.default.createElement(w,{onSave:async e=>{C(!0);try{let t=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{uid:s.uid,recordType:`record`,creatorName:t.name,creatorEmail:t.email,creatorAvatar:t.avatar,createdAt:(0,o.serverTimestamp)(),...e}),_(!1)}catch(e){console.error(`Error saving record:`,e)}C(!1)},onClose:()=>!S&&_(!1),saving:S}):(0,l.jsxs)(`form`,{onSubmit:ne,className:`p-5 flex flex-col gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>!S&&_(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:v,onChange:e=>y(e.target.value),placeholder:`Name *`,disabled:S,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,l.jsx)(`textarea`,{value:b,onChange:e=>x(e.target.value),placeholder:`Note (optional)`,disabled:S,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,l.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,l.jsx)(t.h,{type:`submit`,isLoading:S,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:S?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,d.createPortal)((0,l.jsx)(n.At,{children:P&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>N(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,l.jsx)(`button`,{onClick:()=>N(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,l.jsx)(n.Pt,{className:`w-5 h-5`})}),(0,l.jsxs)(n.kt.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,l.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,l.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,l.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:P.fileName||P.name}),(0,l.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[_e(P.fileType),` • `,ve(P.fileSize||0)]})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,l.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(P.downloadURL),J(`preview`),setTimeout(()=>J(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:q===`preview`?(0,l.jsx)(n.nr,{className:`w-4 h-4 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),Z(P.id),Q(P.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,l.jsx)(n.un,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),A(P.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,l.jsx)(n.Gt,{className:`w-4 h-4`})}),(0,l.jsx)(`a`,{href:P.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,l.jsx)(n.Bn,{className:`w-4 h-4`})})]})]}),(0,l.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>N(null),children:(0,l.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[F&&(0,l.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,l.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,l.jsx)(n.yn,{className:`w-5 h-5 text-accent animate-spin`})})}),P.fileType?.startsWith(`image/`)?(0,l.jsx)(`img`,{onLoad:()=>I(!1),onError:()=>I(!1),src:P.downloadURL,alt:P.fileName||P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType?.startsWith(`video/`)?(0,l.jsx)(`video`,{onLoadedData:()=>I(!1),onError:()=>I(!1),src:P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType===`application/pdf`?(0,l.jsx)(`iframe`,{onLoad:()=>I(!1),src:P.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${F?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,l.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(),I(!1)},children:[(0,l.jsx)(n.Pn,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,l.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,l.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,l.jsx)(n.At,{children:z&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.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,l.jsx)(n.kt.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,l.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),S&&(0,l.jsx)(n.yn,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>fe(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`input`,{autoFocus:!0,required:!0,value:V,onChange:e=>H(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:U,onChange:e=>{ee(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),W.map((e,t)=>(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let n=[...W];n[t].key=e.target.value,G(n)},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,l.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let n=[...W];n[t].value=e.target.value,G(n)},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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>G(W.filter((e,n)=>n!==t)),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,l.jsx)(n.Pt,{className:`w-3 h-3`})})]},t)),(0,l.jsxs)(`button`,{type:`button`,onClick:()=>G([...W,{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,l.jsx)(n.cn,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,l.jsx)(me,{isOpen:!!k,onCancel:()=>A(null),onConfirm:ie,title:`Delete Record`,message:(0,l.jsxs)(l.Fragment,{children:[`Are you sure you want to delete `,(0,l.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:f.find(e=>e.id===k)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:L})]})}function Vc({config:e,customContent:i}){let{user:s}=r.j(),{config:u}=t.y(),[f,p]=(0,a.useState)([]),[m,h]=(0,a.useState)(!0),[g,_]=(0,a.useState)(!1),[v,y]=(0,a.useState)(``),[b,x]=(0,a.useState)(``),[S,C]=(0,a.useState)(!1),[w,T]=(0,a.useState)(null),E=(0,a.useRef)(null),[D,O]=(0,a.useState)(!1),[k,A]=(0,a.useState)(null),[j,M]=(0,a.useState)(null),N=e=>{if(M(e),e){let t=e.fileType||``;I(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},P=j,[F,I]=(0,a.useState)(!0),[L,R]=(0,a.useState)(!1),[z,B]=(0,a.useState)(null),[V,H]=(0,a.useState)(``),[U,ee]=(0,a.useState)(``),[W,G]=(0,a.useState)([]),K=(0,a.useRef)(null),[q,J]=(0,a.useState)(null),Y=(0,a.useRef)([]),X=`mem_${(e.tabName||e.pageId||`internal_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`)}_records`;(0,a.useEffect)(()=>{document.title=e.tabTitle||e.tabName||u.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,u.appName]),(0,a.useEffect)(()=>{if(!s)return;try{let e=localStorage.getItem(`fbos_records_${X}`);e?(p(JSON.parse(e)),h(!1)):h(!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}}),t=(0,o.onSnapshot)((0,o.query)((0,o.collection)(n.Sr,X),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(150)),t=>{let n=e(t.docs);p(n),h(!1),localStorage.setItem(`fbos_records_${X}`,JSON.stringify(n))},t=>{console.error(`Error listening to shared records:`,t);let r=(0,o.onSnapshot)((0,o.query)((0,o.collection)(n.Sr,X),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),p(n),h(!1),localStorage.setItem(`fbos_records_${X}`,JSON.stringify(n))});return()=>r()});return()=>t()},[s,X]);let te=()=>({name:s.displayName||s.email?.split(`@`)[0]||`Member`,email:s.email||``,avatar:s.photoURL||``}),ne=async e=>{if(e.preventDefault(),!(!s||!v.trim())){C(!0);try{let e=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{name:v.trim(),note:b.trim(),uid:s.uid,recordType:`record`,creatorName:e.name,creatorEmail:e.email,creatorAvatar:e.avatar,createdAt:(0,o.serverTimestamp)()}),y(``),x(``),_(!1)}catch(e){console.error(`Error saving shared record:`,e)}C(!1)}},re=async e=>{let t=e.target.files?.[0];if(!t||!s)return;let r=await n.Tt(t);O(!0);try{let e=`mem_files/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,t=(0,c.ref)(n.wr,e);await(0,c.uploadBytes)(t,r,{customMetadata:{ownerId:s.uid}});let i=await(0,c.getDownloadURL)(t);if(E.current)E.current(r,i,{uid:s.uid,storagePath:e});else{let e=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{name:r.name,note:`${r.type||`File`} · ${ve(r.size)}`,uid:s.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)}O(!1),K.current&&(K.current.value=``)},ie=async()=>{if(k){R(!0);try{let e=f.find(e=>e.id===k);if(await(0,o.deleteDoc)((0,o.doc)(n.Sr,X,k)),e?.recordType===`file`&&e.downloadURL)try{let t=e.downloadURL.split(`mem_files%2F`)[1]?.split(`?`)[0];t&&await(0,c.deleteObject)((0,c.ref)(n.wr,`mem_files/${decodeURIComponent(t)}`)).catch(()=>{})}catch(e){console.error(`Error cleaning up shared file:`,e)}A(null)}catch(e){console.error(`Error deleting shared record:`,e)}R(!1)}},[ae,Z]=(0,a.useState)(null),[oe,Q]=(0,a.useState)(``),[ce,le]=(0,a.useState)(!1),ue=e=>{if(e.recordType===`file`){Z(e.id),Q(e.name);return}B(e.id),H(e.name),ee(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??``)}));G(n),Y.current=n.map(e=>e.key)},de=async()=>{if(!ae||!oe.trim()){Z(null);return}let e=f.find(e=>e.id===ae);if(e&&e.name===oe.trim()){Z(null);return}le(!0);try{await(0,o.updateDoc)((0,o.doc)(n.Sr,X,ae),{name:oe.trim()}),p(e=>e.map(e=>e.id===ae?{...e,name:oe.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}le(!1),Z(null)},fe=async()=>{await pe(),B(null)},pe=async()=>{if(!z||!V.trim())return;C(!0);let e={};W.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let t=W.map(e=>e.key.trim()).filter(Boolean),r=Y.current.filter(e=>!t.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(n.Sr,X,z),{name:V.trim(),note:U.trim(),...e}),p(e=>e.map(e=>{if(e.id!==z)return e;let t={...e,name:V.trim(),note:U.trim()};return r.forEach(e=>{delete t[e]}),W.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),Y.current=t}catch(e){console.error(`Error saving record:`,e)}C(!1)},he=(e,t)=>e?e.startsWith(`image/`)?t?(0,l.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${t})`}}):(0,l.jsx)(n.An,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,l.jsx)(n.Lt,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,l.jsx)(n.Pn,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,l.jsx)(n._r,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,l.jsx)(n.Wn,{className:`w-4 h-4`}):(0,l.jsx)(n.Nn,{className:`w-4 h-4`}):(0,l.jsx)(n.Pn,{className:`w-4 h-4`}),ge=e=>e?e.startsWith(`image/`)?`bg-emerald-500/10 text-emerald-500`:e.startsWith(`video/`)||e.startsWith(`audio/`)?`bg-purple-500/10 text-purple-500`: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`,_e=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)},ve=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]},ye=e=>{if(!e)return``;let t=e.toMillis?e.toMillis():e;return new Date(t).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})},be=(()=>{let t=(e.buttonStorageIcon||`upload`).trim(),r=t.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return n.jt[r]?n.jt[r]:n.jt[t]?n.jt[t]:n.Vt||n.cn})(),xe=e.buttonStyle!==`secondary`,Se=e.buttonStorageStyle===`primary`,Ce=e=>e.uid===s?.uid,we=({record:e})=>{let t=e.creatorName||e.creatorEmail?.split(`@`)[0]||`Member`,n=e.creatorEmail||``,r=e.creatorAvatar||``,i=t.split(` `).map(e=>e[0]).join(``).toUpperCase().slice(0,2);return(0,l.jsxs)(`div`,{className:`flex items-center gap-2 mt-2 pt-2 border-t border-[var(--panel-border)]/30`,children:[r?(0,l.jsx)(`img`,{src:r,alt:``,className:`w-5 h-5 rounded-full object-cover shrink-0`}):(0,l.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:i}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 flex-1`,children:[(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 truncate`,children:t}),n&&(0,l.jsxs)(`span`,{className:`text-[10px] text-foreground/25 truncate`,children:[`· `,n]})]})]})};return(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:e.tabTitle||e.tabName||`Internal Page`}),e.route&&(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.jsxs)(n.kt.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,l.jsx)(`input`,{type:`file`,ref:K,onChange:re,className:`hidden`}),!i&&(0,l.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,l.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,l.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:m?`Loading…`:`${f.length} ${f.length===1?`item`:`items`} · Internal`})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>K.current?.click(),disabled:D,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`} ${Se?`btn-primary`:`btn-secondary`}`,children:[D?(0,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin`}):(0,l.jsx)(be,{className:`w-4 h-4`}),e.buttonStorageText&&(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,l.jsx)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>_(!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`} ${xe?`btn-primary`:`btn-secondary`}`,children:e.buttonText===`+`||!e.buttonText?(0,l.jsx)(n.cn,{className:`w-4 h-4`}):(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,l.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[m&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,l.jsx)(n.yn,{className:`w-8 h-8 text-accent animate-spin`})}),i?(0,l.jsx)(`div`,{className:`fbos-content-slot`,children:(0,l.jsx)(i,{config:e,actions:{records:f,loading:m,collection:X,user:s,saveRecord:async e=>{let t=(0,o.doc)((0,o.collection)(n.Sr,X)),r=te(),i={id:t.id,uid:s.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:Date.now(),...e};p(e=>[i,...e]),await(0,o.setDoc)(t,{uid:s.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,t)=>{p(n=>n.map(n=>n.id===e?{...n,...t}:n)),await(0,o.updateDoc)((0,o.doc)(n.Sr,X,e),t)},deleteRecord:async e=>{await(0,o.deleteDoc)((0,o.doc)(n.Sr,X,e))},startEdit:e=>ue(e),confirmDelete:e=>A(e),uploadFile:()=>K.current?.click(),openAddForm:()=>_(!0),setAddForm:e=>T(()=>e),setFileHandler:e=>{E.current=e}}})}):(0,l.jsxs)(l.Fragment,{children:[!m&&f.length===0&&(0,l.jsxs)(n.kt.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,l.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,l.jsx)(n.cn,{className:`w-6 h-6 text-accent/40`})}),(0,l.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,l.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.`})]}),!m&&f.length>0&&(0,l.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,l.jsx)(n.At,{children:f.map(e=>{let t=z===e.id,r=Ce(e);return(0,l.jsxs)(n.kt.div,{initial:!1,animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},onClick:()=>r?ue(e):null,className:`group flex flex-col bg-background border rounded-2xl p-5 transition-all relative ${r?`cursor-pointer`:``} ${t?`border-accent/40 shadow-lg ring-1 ring-accent/20`:`border-[var(--panel-border)] hover:border-accent/30 hover:shadow-lg`}`,children:[(0,l.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,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),J(e.id),setTimeout(()=>J(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:q===e.id?(0,l.jsx)(n.nr,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-3.5 h-3.5`})}),(0,l.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,l.jsx)(n.Bn,{className:`w-3.5 h-3.5`})})]}),r&&(0,l.jsxs)(l.Fragment,{children:[(0,l.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,l.jsx)(n.un,{className:`w-3.5 h-3.5`})}),(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),A(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,l.jsx)(n.Gt,{className:`w-3.5 h-3.5`})})]})]}),(0,l.jsxs)(`div`,{className:`flex items-start gap-3 mb-2`,children:[(0,l.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&N(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 ${ge(e.fileType)}`:`bg-accent/10 text-accent`}`,children:e.recordType===`file`?he(e.fileType,e.downloadURL):(0,l.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,l.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[ae===e.id?(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,value:oe,onChange:e=>Q(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,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>N(e)}),(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:ye(e.createdAt)})]})]}),e.note&&(0,l.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,l.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,l.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e)),(0,l.jsx)(we,{record:e})]},e.id)})})})]})]})]})]}),(0,l.jsx)(n.At,{children:g&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>!S&&_(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,l.jsx)(n.kt.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:w?a.default.createElement(w,{onSave:async e=>{C(!0);try{let t=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{uid:s.uid,recordType:`record`,creatorName:t.name,creatorEmail:t.email,creatorAvatar:t.avatar,createdAt:(0,o.serverTimestamp)(),...e}),_(!1)}catch(e){console.error(`Error saving record:`,e)}C(!1)},onClose:()=>!S&&_(!1),saving:S}):(0,l.jsxs)(`form`,{onSubmit:ne,className:`p-5 flex flex-col gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>!S&&_(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:v,onChange:e=>y(e.target.value),placeholder:`Name *`,disabled:S,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,l.jsx)(`textarea`,{value:b,onChange:e=>x(e.target.value),placeholder:`Note (optional)`,disabled:S,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,l.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,l.jsx)(t.h,{type:`submit`,isLoading:S,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:S?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,d.createPortal)((0,l.jsx)(n.At,{children:P&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>N(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,l.jsx)(`button`,{onClick:()=>N(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,l.jsx)(n.Pt,{className:`w-5 h-5`})}),(0,l.jsxs)(n.kt.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,l.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,l.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,l.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:P.fileName||P.name}),(0,l.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[_e(P.fileType),` • `,ve(P.fileSize||0)]})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,l.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(P.downloadURL),J(`preview`),setTimeout(()=>J(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:q===`preview`?(0,l.jsx)(n.nr,{className:`w-4 h-4 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),Z(P.id),Q(P.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,l.jsx)(n.un,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),A(P.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,l.jsx)(n.Gt,{className:`w-4 h-4`})}),(0,l.jsx)(`a`,{href:P.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,l.jsx)(n.Bn,{className:`w-4 h-4`})})]})]}),(0,l.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>N(null),children:(0,l.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[F&&(0,l.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,l.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,l.jsx)(n.yn,{className:`w-5 h-5 text-accent animate-spin`})})}),P.fileType?.startsWith(`image/`)?(0,l.jsx)(`img`,{onLoad:()=>I(!1),onError:()=>I(!1),src:P.downloadURL,alt:P.fileName||P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType?.startsWith(`video/`)?(0,l.jsx)(`video`,{onLoadedData:()=>I(!1),onError:()=>I(!1),src:P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType===`application/pdf`?(0,l.jsx)(`iframe`,{onLoad:()=>I(!1),src:P.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${F?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,l.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(),I(!1)},children:[(0,l.jsx)(n.Pn,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,l.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,l.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,l.jsx)(n.At,{children:z&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.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,l.jsx)(n.kt.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,l.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),S&&(0,l.jsx)(n.yn,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>fe(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`input`,{autoFocus:!0,required:!0,value:V,onChange:e=>H(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:U,onChange:e=>{ee(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),W.map((e,t)=>(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let n=[...W];n[t].key=e.target.value,G(n)},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,l.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let n=[...W];n[t].value=e.target.value,G(n)},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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>G(W.filter((e,n)=>n!==t)),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,l.jsx)(n.Pt,{className:`w-3 h-3`})})]},t)),(0,l.jsxs)(`button`,{type:`button`,onClick:()=>G([...W,{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,l.jsx)(n.cn,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,l.jsx)(me,{isOpen:!!k,onCancel:()=>A(null),onConfirm:ie,title:`Delete Record`,message:(0,l.jsxs)(l.Fragment,{children:[`Are you sure you want to delete `,(0,l.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:f.find(e=>e.id===k)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:L})]})}var Hc=[`board`,`table`,`calendar`,`drive`],Uc=[`inline_form`,`popup_form`],Wc=e=>typeof e!=`string`||e===``||e===`none`||e===`custom`||![...Hc,...Uc].includes(e),Gc=(e,t)=>Wc(e)||t&&!Kc(e),Kc=e=>typeof e==`string`&&Hc.includes(e),qc=`/src/your-ai-workflow-firebase-os/microcomponents`,Jc=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``),Yc=e=>{let t=e.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();return[t,t.replace(/_/g,``)]},Xc=e=>{let t=[e?.contentKey,e?.tabName,e?.pageId,e?.pageName].filter(e=>typeof e==`string`&&e.trim()).map(e=>Jc(e)).filter(Boolean);return[...new Set(t)].map(e=>`${e}Content.tsx`)},Zc=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)])},Qc=new Map,$c=e=>{let t=Qc.get(e);return t||(t=import(`${qc}/${e}`).then(e=>typeof e?.default==`function`||typeof e?.default==`object`?e.default:null).catch(()=>null),Qc.set(e,t)),t};async function el(e){if(typeof window>`u`||Zc(e))return null;for(let t of Xc(e)){let e=await $c(t);if(!e)continue;let[n,r]=Yc(t.replace(/Content\.tsx$/,``)),i=window.__FBOS_MICROCOMPONENTS__||{};return window.__FBOS_MICROCOMPONENTS__={[n]:e,[r]:e,...i},e}return null}var tl=(e,t)=>{let n=t?r.V(e.pageType):`public`;return{...e,pageType:n,isPrivate:t,isAdmin:n===`admin`,isInternal:n===`internal`,isShared:n===`internal`}};function nl(){let e=(0,u.useLocation)(),{user:i,userRole:s,loading:c,roleResolved:d}=r.j(),f=n.br(),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 tl(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 tl({...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.S}:e===`/support`?{route:`/support`,template:`popup_form`,form:`support`,pageId:`support`,contentKey:`support`,pageName:`Support`,formConfigOverride:f.defaultConfigs?.supportForm||t.b}:null},[m,h]=(0,a.useState)(()=>p(e.pathname)),[g,_]=(0,a.useState)(()=>!p(e.pathname));(0,a.useEffect)(()=>{let r=!0,i=p(e.pathname);if(i){h(i),_(!1);let e=i.pageName||i.tabName||i.title;e&&(document.title=e)}return(async()=>{try{let i=e.pathname;i.startsWith(`/`)&&(i=i.substring(1));let[a,s,c,l,u,d]=await Promise.allSettled([(0,o.getDoc)((0,o.doc)(n.Sr,`sys_pages`,i)),(0,o.getDoc)((0,o.doc)(n.Sr,`sys_tabs`,i)),(0,o.getDocs)((0,o.query)((0,o.collection)(n.Sr,`sys_pages`),(0,o.where)(`route`,`==`,e.pathname),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(n.Sr,`sys_pages`),(0,o.where)(`route`,`==`,i),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(n.Sr,`sys_tabs`),(0,o.where)(`route`,`==`,e.pathname),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(n.Sr,`sys_tabs`),(0,o.where)(`route`,`==`,i),(0,o.limit)(1)))]),p=null,m=null,g=(e,t)=>{p||e.status===`fulfilled`&&(e.value.exists&&e.value.exists()?(p=tl(e.value.data(),t),m=e.value.id):e.value.docs&&e.value.docs.length>0&&(p=tl(e.value.docs[0].data(),t),m=e.value.docs[0].id))};if(g(a,!1),g(c,!1),g(l,!1),g(s,!0),g(u,!0),g(d,!0),!p){let t=(typeof window<`u`?window.__FBOS_PAGES__:null)||{};for(let[n,r]of Object.entries(t)){let t=r.config,a=r.isPublic,o=t.route||`/`+n;if(o===e.pathname||n===i){p=tl({...t,route:o,contentKey:t.pageId||n,pageId:n},!a),m=n;break}}}if(p||(e.pathname===`/contact`?(p={route:`/contact`,template:`popup_form`,form:`contact`,pageName:`Contact`},m=`contact`):e.pathname===`/support`&&(p={route:`/support`,template:`popup_form`,form:`support`,pageName:`Support`},m=`support`)),!r)return;if(p){if((m===`contact`||m===`support`)&&!p.form&&(p.form=m),p.contentKey||=p.pageId||m,p.pageId=m,localStorage.setItem(`fbos_route_${e.pathname}`,JSON.stringify(p)),p.form){let e=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},i=n=>f.defaultConfigs?.[n]||f.defaultConfigs?.[`${n}Form`]||e[n]||(n===`contact`?t.S:n===`support`?t.b:null);if(localStorage.getItem(`fbos_custom_form_${p.form}`)){try{let e=localStorage.getItem(`fbos_form_${p.form}`);e&&(p.formConfigOverride=JSON.parse(e))}catch{}(0,o.getDoc)((0,o.doc)(n.Sr,`sys_forms`,p.form)).then(async e=>{if(r)if(e.exists()){let t={...e.data(),id:e.id};h(e=>({...e,formConfigOverride:t})),localStorage.setItem(`fbos_form_${p.form}`,JSON.stringify(t))}else{let e=i(p.form);e&&(h(t=>({...t,formConfigOverride:e})),localStorage.setItem(`fbos_form_${p.form}`,JSON.stringify(e)),localStorage.removeItem(`fbos_custom_form_${p.form}`))}})}else{let e=i(p.form);e&&(p.formConfigOverride=e)}}let i=p.pageName||p.tabName||p.title;i&&(document.title=i),h(p),_(!1)}else h(`not-found`),_(!1),localStorage.removeItem(`fbos_route_${e.pathname}`)}catch{r&&g&&(h(`not-found`),_(!1))}})(),()=>{r=!1}},[e.pathname]);let[v,y]=(0,a.useState)(!1),[b,x]=(0,a.useState)(null),[S,C]=(0,a.useState)(!1),w=m&&m!==`not-found`&&typeof m==`object`?[m.contentKey,m.tabName,m.pageId,m.pageName].filter(Boolean).join(`|`):``;if((0,a.useEffect)(()=>{if(x(null),!w||Zc(m)){C(!1);return}let e=!1;C(!0),el(m).then(t=>{e||(t&&x(()=>t),C(!1))});let t=setTimeout(()=>{e||C(!1)},4e3);return()=>{e=!0,clearTimeout(t)}},[w]),(0,a.useEffect)(()=>{let e;return g||c||!d||S?e=setTimeout(()=>y(!0),150):y(!1),()=>clearTimeout(e)},[g,c,d,S]),g||c||!d||S)return v?i?(0,l.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,l.jsxs)(`div`,{className:`mb-6`,children:[(0,l.jsx)(`div`,{className:`h-10 w-56 rounded-xl bg-foreground/5 animate-pulse mt-1`}),(0,l.jsx)(`div`,{className:`h-3 w-24 rounded bg-foreground/5 animate-pulse mt-3`})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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,l.jsx)(n.yn,{className:`w-6 h-6 animate-spin text-accent`})})]})]}):(0,l.jsx)(`div`,{className:`flex-1 flex items-center justify-center min-h-[40vh] z-10`,children:(0,l.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,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin text-accent`}),(0,l.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/60 tracking-wide`,children:`Loading page...`})]})}):null;if(m===`not-found`)return(0,l.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,l.jsxs)(`div`,{className:`flex flex-col items-center justify-center flex-1 text-center`,children:[(0,l.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,l.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,l.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,l.jsx)(`line`,{x1:`12`,y1:`8`,x2:`12`,y2:`12`}),(0,l.jsx)(`line`,{x1:`12`,y1:`16`,x2:`12.01`,y2:`16`})]})}),(0,l.jsx)(`h2`,{className:`text-2xl sm:text-3xl font-bold mb-3 text-foreground`,children:`Page Not Found`}),(0,l.jsx)(`p`,{className:`text-foreground/60 max-w-md`,children:`The route you are looking for does not exist or has been removed.`}),r.L(s)&&(()=>{let t=Nc();return(0,l.jsxs)(`div`,{className:`mt-8 w-full max-w-lg text-left flex flex-col gap-4`,children:[(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)] px-5 py-4`,children:[(0,l.jsx)(`p`,{className:`text-[12px] font-extrabold tracking-tight text-gradient mb-1.5`,children:`Pages the app can see`}),(0,l.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,l.jsx)(r.g,{title:`If your assistant just made this page, paste this`,prompt:Lc(e.pathname)})]})})()]})});if((m.pageId===`support`||m.isPrivate)&&!i)return(0,l.jsx)(u.Navigate,{to:`/login`,state:{from:e}});if(!r.F(s,m.isPrivate?m.pageType:`public`))return m.isAdmin?(0,l.jsx)(Sr,{}):(0,l.jsx)(xr,{});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=f.microcomponents||(typeof window<`u`?window.__FBOS_MICROCOMPONENTS__:void 0),k=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`_`).replace(/^_|_$/g,``),A=[m.contentKey,m.tabName,m.pageId,m.pageName,m.pageName?.replace(/\s+/g,`_`)].filter(Boolean).map(e=>k(e)).reduce((e,t)=>e||O?.[t],void 0),j=T||A||b||void 0,M=m.route||m.pageId||`custom`;if(Gc(m.template,!!j))return m.isAdmin?(0,l.jsx)(Bc,{config:m,customContent:j},M):m.isInternal?(0,l.jsx)(Vc,{config:m,customContent:j},M):m.isPrivate?(0,l.jsx)(zc,{config:m,customContent:j},M):(0,l.jsx)(Rc,{config:m,customContent:j},M);if(m.template===`board`){let e=m.isAdmin?`admin_${m.pageId||E}`:m.isInternal?`mem_${m.pageId||E}`:m.isPrivate?`user_${m.pageId||E}`:D;return(0,l.jsx)(f.components?.TemplateBoard||it,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Board`,subtitle:m.route,tasksCollection:`${e}_tasks`,categoriesCollection:`${e}_categories`,config:m,customContent:j},M)}if(m.template===`table`){let e=m.isAdmin?`admin_${m.pageId||E}`:m.isInternal?`mem_${m.pageId||E}`:m.isPrivate?`user_${m.pageId||E}`:D;return(0,l.jsx)(f.components?.TemplateTable||Pn,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Table`,subtitle:m.route,tableCollection:`${e}_table`,config:m,customContent:j},M)}if(m.template===`calendar`){let e=m.isAdmin?`admin_${m.pageId||E}`:m.isInternal?`mem_${m.pageId||E}`:m.isPrivate?`user_${m.pageId||E}`:D;return(0,l.jsx)(f.components?.TemplateCalendar||Ln,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Calendar`,subtitle:m.route,eventsCollection:`${e}_events`,defaultTimeFormat:m.defaultTimeFormat||m.defaulttimeformat||`12h`,config:m,customContent:j},M)}if(m.template===`drive`){let e=m.isAdmin?`admin_${m.pageId||E}`:m.isInternal?`mem_${m.pageId||E}`:m.isPrivate?`user_${m.pageId||E}`:D;return(0,l.jsx)(f.components?.TemplateDrive||Fe,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Drive`,subtitle:m.route,filesCollection:`${e}_files`,config:m,customContent:j},M)}return m.template===`inline_form`?(0,l.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-start mt-8 relative z-10 w-full min-h-[60vh]`,children:(0,l.jsx)(t.t,{isInline:!0,formId:m.form,formConfig:m.formConfigOverride})}):(0,l.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-center relative z-10 w-full min-h-[60vh]`,children:(0,l.jsx)(t.t,{formId:m.form,formConfig:m.formConfigOverride,onClose:()=>window.history.back()})})}var rl=e=>e.error?`error`:e.paid?`paid`:`unpaid`,il={checking:{icon:n.Kn,tint:`text-accent`,title:`Checking your payment…`},paid:{icon:n.Xn,tint:`text-emerald-400`,title:`Thank you — payment received`},unpaid:{icon:n.Kn,tint:`text-amber-400`,title:`Not confirmed yet`},error:{icon:n.Zn,tint:`text-red-400`,title:`We could not confirm this payment`},cancelled:{icon:n.qn,tint:`text-foreground/50`,title:`Payment cancelled`}};function al({cancelled:e=!1}){let[i]=(0,u.useSearchParams)(),o=i.get(`session_id`)||``,[s,c]=(0,a.useState)(`checking`),[d,f]=(0,a.useState)(null);(0,a.useEffect)(()=>{if(e)return;let t=!1;return r.x(o).then(e=>{t||(f(e),c(rl(e)))}),()=>{t=!0}},[e,o]);let p=async()=>{c(`checking`);let e=await r.x(o);f(e),c(rl(e))},m=il[e?`cancelled`:s],h=m.icon;return(0,l.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mb-16`,children:(0,l.jsxs)(n.kt.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,l.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,l.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,l.jsx)(h,{className:`w-7 h-7 md:w-8 md:h-8 ${m.tint} ${!e&&s===`checking`?`animate-pulse`:``}`})}),(0,l.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold mb-3 text-foreground tracking-tight`,children:m.title}),(0,l.jsxs)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/60 mb-6 md:mb-8 leading-[1.6] tracking-wide`,children:[e&&(0,l.jsx)(`p`,{children:`Nothing was charged. You can try again whenever you like.`}),!e&&s===`checking`&&(0,l.jsx)(`p`,{children:`One moment — confirming with the payment provider.`}),!e&&s===`paid`&&(0,l.jsxs)(`p`,{children:[d?.amountTotal!=null&&d?.currency?`Your payment of ${d.amountTotal} ${d.currency.toUpperCase()} went through.`:`Your payment went through.`,d?.customerEmail?` A receipt is on its way to ${d.customerEmail}.`:``]}),!e&&s===`unpaid`&&(0,l.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&&s===`error`&&(0,l.jsxs)(`p`,{children:[d?.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,l.jsxs)(`div`,{className:`flex flex-col gap-3 max-w-[360px] mx-auto`,children:[!e&&(s===`unpaid`||s===`error`)&&(0,l.jsx)(t.h,{variant:`primary`,onClick:p,className:`w-full py-2.5 md:py-3 text-[14px] font-bold tracking-wide rounded-xl`,children:`Check again`}),(0,l.jsx)(u.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 ol({children:e,className:n,variant:i=`secondary`}){let{loading:o,configured:s}=r.D(),[c,u]=(0,a.useState)(!1),[d,f]=(0,a.useState)(null);return o||!s?null:(0,l.jsxs)(`span`,{className:`inline-flex flex-col items-stretch gap-2`,children:[(0,l.jsx)(t.h,{variant:i,className:n,onClick:async()=>{if(c)return;u(!0),f(null);let e=await r.C();e&&(f(e),u(!1))},disabled:c,children:c?`Opening…`:e??`Manage plan`}),d&&(0,l.jsx)(`span`,{role:`alert`,className:`text-[13px] font-semibold text-red-400 leading-snug`,children:d})]})}function sl(e){return e.status===`past_due`?{label:`Past due`,tone:`bad`}:e.active?{label:`Active`,tone:`good`}:{label:`Cancelled`,tone:`quiet`}}function cl(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}`}var ll=e=>e?new Date(e*1e3).toLocaleDateString(void 0,{day:`numeric`,month:`short`,year:`numeric`}):``;function ul({label:e,tone:t}){return(0,l.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 dl({payment:e}){let t=As({kind:`charge`,email:null,name:null,...e});return(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.description||`One-off payment`}),(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/45 font-medium truncate`,children:ll(e.created)})]}),(0,l.jsx)(`span`,{className:`text-[12.5px] font-semibold text-foreground/70 whitespace-nowrap shrink-0`,children:js(e.amount,e.currency)}),(0,l.jsx)(ul,{label:t.label,tone:t.tone})]})}function fl({sub:e}){let t=sl(e),r=cl(e);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-3 px-3.5 py-3 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.productName||`Subscription`}),(0,l.jsxs)(`span`,{className:`text-[11px] text-foreground/45 font-medium truncate`,children:[js(e.amount,e.currency),e.interval?` / ${e.interval}`:``,r?` — ${r}`:``]})]}),(0,l.jsx)(ul,{label:t.label,tone:t.tone})]}),(0,l.jsx)(ol,{className:`self-start`})]})}function pl(){let{user:e}=r.j(),{loading:t,subscriptions:i,payments:a,error:o}=r.E(),s=!t&&!o&&i.length===0&&a.length===0;return(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`Billing`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/billing`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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:t?(0,l.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,l.jsx)(n.yn,{className:`w-6 h-6 animate-spin text-accent`})}):o?(0,l.jsx)(`p`,{className:`text-[12.5px] font-medium leading-relaxed px-1 text-red-500`,children:o}):s?(0,l.jsx)(n.u,{icon:n.on,title:`Nothing here yet`,description:`No payments have been made on this account.`,collapsible:!1,children:(0,l.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,l.jsxs)(l.Fragment,{children:[` (`,(0,l.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,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[i.length>0&&(0,l.jsx)(n.u,{icon:n.Hn,title:i.length===1?`Your subscription`:`Your subscriptions`,description:`Manage plan opens Stripe's own portal — cancel, switch, card, invoices.`,collapsible:!1,children:(0,l.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:i.map(e=>(0,l.jsx)(fl,{sub:e},e.id))})}),a.length>0&&(0,l.jsx)(n.u,{icon:n.on,title:`Your payments`,description:`Every payment on this account, straight from Stripe.`,collapsible:!1,children:(0,l.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:a.map(e=>(0,l.jsx)(dl,{payment:e},e.id))})})]})})]})]})}var ml={contentKey:`dashboard`};function hl(){let{user:e}=r.j(),t=n.br(),[i,o]=(0,a.useState)(null),[s,c]=(0,a.useState)(()=>typeof window<`u`&&!Zc(ml));(0,a.useEffect)(()=>{if(Zc(ml))return;let e=!1;el(ml).then(t=>{e||(t&&o(()=>t),c(!1))});let t=setTimeout(()=>{e||c(!1)},4e3);return()=>{e=!0,clearTimeout(t)}},[]);let u=t.microcomponents?.dashboard||(typeof window<`u`?window.__FBOS_MICROCOMPONENTS__?.dashboard:void 0)||i||void 0,d=(e?.displayName||e?.email?.split(`@`)[0]||`there`).split(` `)[0],f=d.charAt(0).toUpperCase()+d.slice(1);return(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-8`,children:[(0,l.jsxs)(r.y,{children:[`Welcome back, `,f,`.`]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/dashboard`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 flex-1 min-h-[500px]`,children:[(0,l.jsx)(`div`,{className:`flex justify-start`,children:(0,l.jsx)(se,{})}),(0,l.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)] ${u?`p-6 md:p-8`:`p-8 md:p-12 flex items-center justify-center`}`,children:[(0,l.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`}),u?(0,l.jsx)(`div`,{className:`fbos-content-slot relative z-10`,children:(0,l.jsx)(u,{})}):s?(0,l.jsx)(n.yn,{className:`w-6 h-6 text-accent animate-spin relative z-10`}):(0,l.jsx)(n.At,{mode:`wait`,children:(0,l.jsxs)(n.kt.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,l.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,l.jsx)(n.Vn,{className:`w-6 h-6`})}),(0,l.jsx)(`h2`,{className:`text-2xl font-extrabold text-foreground mb-2`,children:`No data added here yet`}),(0,l.jsx)(`p`,{className:`text-foreground/40 font-medium`,children:`Keep moving forward, your data will appear here.`})]})})]})]})]})}var gl=()=>(0,l.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,l.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,l.jsx)(n.Vn,{className:`w-6 h-6 text-accent animate-pulse`})}),(0,l.jsxs)(`div`,{className:`flex items-center gap-3 glass-panel px-5 py-2.5 rounded-full border border-[var(--panel-border)]`,children:[(0,l.jsx)(`div`,{className:`w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin`}),(0,l.jsx)(`span`,{className:`text-[13px] font-bold tracking-widest uppercase text-foreground/70`,children:`Connecting`})]})]});function _l({level:e,children:t}){let{user:n,userRole:i,loading:a,userInactive:o,signOut:s,roleResolved:c}=r.j(),d=(0,u.useLocation)();return a||!c?(0,l.jsx)(gl,{}):n?o?(0,l.jsx)(gr,{tone:`red`,title:`Access Denied`,message:`You don't have access to this app. Please contact the administrator.`,action:(0,l.jsx)(`button`,{onClick:()=>s(),className:_r,children:`Sign Out`})}):n.emailVerified?e===`admin`&&!r.L(i)?(0,l.jsx)(Sr,{}):e===`internal`&&!r.I(i)?(0,l.jsx)(xr,{}):(0,l.jsx)(l.Fragment,{children:t}):(0,l.jsx)(u.Navigate,{to:`/verify`}):(0,l.jsx)(u.Navigate,{to:`/login?from=${encodeURIComponent(d.pathname)}`})}var vl=({children:e})=>(0,l.jsx)(_l,{level:`signed-in`,children:e}),yl=({children:e})=>(0,l.jsx)(_l,{level:`admin`,children:e}),bl=({children:e})=>(0,l.jsx)(_l,{level:`internal`,children:e});function xl({children:e}){let{user:t,loading:n,roleResolved:i}=r.j(),[a]=(0,u.useSearchParams)();return n||!i?(0,l.jsx)(gl,{}):t&&t.emailVerified?(0,l.jsx)(u.Navigate,{to:a.get(`from`)||`/dashboard`,replace:!0}):(0,l.jsx)(l.Fragment,{children:e})}function Sl({children:e}){let{user:t,loading:n,roleResolved:i}=r.j();return n||!i?(0,l.jsx)(gl,{}):t?t.emailVerified?(0,l.jsx)(u.Navigate,{to:`/dashboard`}):(0,l.jsx)(l.Fragment,{children:e}):(0,l.jsx)(u.Navigate,{to:`/`})}function Cl(){return(0,l.jsxs)(`div`,{className:`fixed top-0 left-0 w-full h-full pointer-events-none -z-0 overflow-hidden`,children:[(0,l.jsx)(n.kt.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,l.jsx)(n.kt.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 wl(){let e=n.br().components?.Home||L;return(0,l.jsx)(r.A,{children:(0,l.jsxs)(`div`,{className:`min-h-screen relative flex flex-col overflow-x-hidden`,children:[(0,l.jsx)(I,{}),(0,l.jsxs)(u.Routes,{children:[(0,l.jsx)(u.Route,{path:`/`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(`div`,{className:`fbos-home-slot contents`,children:(0,l.jsx)(e,{})})})}),(0,l.jsx)(u.Route,{path:`/register`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(G,{})})}),(0,l.jsx)(u.Route,{path:`/login`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(K,{})})}),(0,l.jsx)(u.Route,{path:`/reset-password`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(le,{})})}),(0,l.jsx)(u.Route,{path:`/verify`,element:(0,l.jsx)(Sl,{children:(0,l.jsx)(q,{})})}),(0,l.jsx)(u.Route,{path:`/book/:id`,element:(0,l.jsx)(vc,{})}),(0,l.jsx)(u.Route,{path:`/pay/:id`,element:(0,l.jsx)(bc,{})}),(0,l.jsx)(u.Route,{path:`/payment-complete`,element:(0,l.jsx)(al,{})}),(0,l.jsx)(u.Route,{path:`/payment-cancelled`,element:(0,l.jsx)(al,{cancelled:!0})}),(0,l.jsx)(u.Route,{path:`/guide`,element:(0,l.jsx)(et,{})}),(0,l.jsx)(u.Route,{path:`/templates`,element:(0,l.jsx)(Be,{})}),(0,l.jsx)(u.Route,{path:`/board`,element:(0,l.jsx)(it,{})}),(0,l.jsx)(u.Route,{path:`/table`,element:(0,l.jsx)(Pn,{})}),(0,l.jsx)(u.Route,{path:`/calendar`,element:(0,l.jsx)(Ln,{})}),(0,l.jsx)(u.Route,{path:`/drive`,element:(0,l.jsx)(Fe,{})}),(0,l.jsx)(u.Route,{path:`/inline_form`,element:(0,l.jsx)(tt,{})}),(0,l.jsx)(u.Route,{path:`/popup_form`,element:(0,l.jsx)(nt,{})}),(0,l.jsx)(u.Route,{path:`/users`,element:(0,l.jsx)(yl,{children:(0,l.jsx)(pe,{})})}),(0,l.jsx)(u.Route,{path:`/users/:id`,element:(0,l.jsx)(yl,{children:(0,l.jsx)(pe,{})})}),(0,l.jsx)(u.Route,{path:`/inbox`,element:(0,l.jsx)(yl,{children:(0,l.jsx)(je,{})})}),(0,l.jsx)(u.Route,{path:`/payments`,element:(0,l.jsx)(yl,{children:(0,l.jsx)(Is,{})})}),(0,l.jsx)(u.Route,{path:`/schedule`,element:(0,l.jsx)(yl,{children:(0,l.jsx)(ec,{})})}),(0,l.jsx)(u.Route,{path:`/my-calendar`,element:(0,l.jsx)(bl,{children:(0,l.jsx)(lc,{})})}),(0,l.jsx)(u.Route,{path:`/email`,element:(0,l.jsx)(yl,{children:(0,l.jsx)(jc,{})})}),(0,l.jsx)(u.Route,{path:`/submissions`,element:(0,l.jsx)(u.Navigate,{to:`/inbox`,replace:!0})}),(0,l.jsx)(u.Route,{path:`/requests`,element:(0,l.jsx)(u.Navigate,{to:`/inbox`,replace:!0})}),(0,l.jsx)(u.Route,{path:`/assets`,element:(0,l.jsx)(yl,{children:(0,l.jsx)(ze,{})})}),(0,l.jsx)(u.Route,{path:`/drive/:rest`,element:(0,l.jsx)(u.Navigate,{to:`/assets`,replace:!0})}),(0,l.jsx)(u.Route,{path:`/theme`,element:(0,l.jsx)(yl,{children:(0,l.jsx)(hr,{})})}),(0,l.jsx)(u.Route,{path:`/pages/*`,element:(0,l.jsx)(yl,{children:(0,l.jsx)(Po,{})})}),(0,l.jsx)(u.Route,{path:`/forms/*`,element:(0,l.jsx)(yl,{children:(0,l.jsx)(Qo,{})})}),(0,l.jsx)(u.Route,{path:`/settings`,element:(0,l.jsx)(u.Navigate,{to:`/pages`,replace:!0})}),(0,l.jsx)(u.Route,{path:`/profile`,element:(0,l.jsx)(vl,{children:(0,l.jsx)(ce,{})})}),(0,l.jsx)(u.Route,{path:`/billing`,element:(0,l.jsx)(vl,{children:(0,l.jsx)(pl,{})})}),(0,l.jsx)(u.Route,{path:`/dashboard`,element:(0,l.jsx)(vl,{children:(0,l.jsx)(hl,{})})}),(0,l.jsx)(u.Route,{path:`/setup`,element:(0,l.jsx)(r.u,{})}),(0,l.jsx)(u.Route,{path:`/setup/payments`,element:(0,l.jsx)(r.n,{})}),(0,l.jsx)(u.Route,{path:`*`,element:(0,l.jsx)(nl,{})})]}),(0,l.jsx)(Cl,{})]})})}function Tl(){return(0,l.jsx)(u.BrowserRouter,{children:(0,l.jsx)(El,{})})}function El(){let e=n.br();return e.firebaseConfig&&e.firebaseConfig.apiKey&&e.firebaseConfig.apiKey.trim()!==``&&e.firebaseConfig.projectId&&e.firebaseConfig.projectId.trim()!==``||r.d()?(0,l.jsx)(wl,{}):(0,l.jsxs)(`div`,{className:`min-h-screen relative flex flex-col overflow-x-hidden`,children:[(0,l.jsx)(I,{standalone:!0}),(0,l.jsx)(r.u,{standalone:!0}),(0,l.jsx)(Cl,{})]})}function Dl(e){b();let r=e.firebaseConfig;return r&&r.apiKey&&r.apiKey.trim()!==``&&r.projectId&&r.projectId.trim()!==``&&n.Cr(r),(0,l.jsx)(n.yr,{config:{firebaseConfig:e.firebaseConfig,adminEmails:e.adminEmails,basename:e.basename,onAuthChange:e.onAuthChange,themeConfig:e.themeConfig,components:e.components,customRoutes:e.customRoutes,microcomponents:e.microcomponents,defaultConfigs:e.defaultConfigs},children:(0,l.jsx)(t.v,{children:(0,l.jsx)(`div`,{className:`firebase-os flex-1 flex flex-col min-h-screen`,style:{background:`var(--bg-gradient)`,color:`var(--fg-color)`},children:(0,l.jsx)(Tl,{})})})})}var Ol=Object.assign({}),kl={};for(let e in Ol){let t=Ol[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();kl[r]=t.default,kl[r.replace(/_/g,``)]=t.default}if(typeof window<`u`){let e=window.__FBOS_MICROCOMPONENTS__||{};window.__FBOS_MICROCOMPONENTS__={...kl,...e}}var Al=(e,t)=>{let n=e.toLowerCase().replace(/[^a-z0-9]+/g,`_`),r=n.replace(/_/g,``);if(kl[n]=t,kl[r]=t,typeof window<`u`){let e=window.__FBOS_MICROCOMPONENTS__||{};window.__FBOS_MICROCOMPONENTS__={...e,[n]:t,[r]:t}}};function jl(...e){return n.Dt(n.Ot(e))}var Ml=({title:e,className:t,children:n,...r})=>(0,l.jsxs)(`div`,{className:jl(`border border-[var(--panel-border)] bg-[var(--panel-bg)] px-5 py-4`,t),style:{borderRadius:`var(--card-radius, 1rem)`},...r,children:[e?(0,l.jsx)(`p`,{className:`text-[12px] font-extrabold tracking-tight text-gradient mb-1.5`,children:e}):null,n]});Ml.displayName=`Card`;function Nl(...e){return n.Dt(n.Ot(e))}var Pl=({sub:e,className:t,children:n,...r})=>(0,l.jsxs)(`div`,{className:Nl(`mb-4`,t),children:[(0,l.jsx)(`h2`,{className:`text-xl md:text-2xl font-extrabold tracking-tight text-foreground`,...r,children:n}),e?(0,l.jsx)(`p`,{className:`text-[13px] text-foreground/60 font-medium leading-relaxed mt-1`,children:e}):null]});Pl.displayName=`SectionHeading`,exports.AdminNotifications=T,exports.Button=t.h,exports.Card=Ml,exports.ConfirmModal=me,exports.ContactPopup=t.t,exports.CustomSelect=n.Et,exports.DashboardNav=se,exports.FirebaseOS=Dl,exports.Input=t.g,exports.ManagePlanButton=ol,exports.Navbar=I,exports.PayButton=yc,exports.PhoneInputField=i.t,exports.SectionHeading=Pl,Object.defineProperty(exports,`auth`,{enumerable:!0,get:function(){return n.xr}}),exports.bookingPath=n.H,exports.cancelBooking=t.n,exports.confirmPayment=r.x,Object.defineProperty(exports,`db`,{enumerable:!0,get:function(){return n.Sr}}),exports.emailAnyone=ji,exports.emailOwner=ki,exports.emailPerson=Ai,exports.emailStatus=Ni,exports.notify=w,exports.openBillingPortal=r.C,exports.payPath=n.et,exports.registerMicrocomponent=Al,exports.startCheckout=r.T,Object.defineProperty(exports,`storage`,{enumerable:!0,get:function(){return n.wr}}),exports.useAuth=r.j,exports.useBookings=t.s,exports.useConfig=n.br,exports.useMyPayments=r.E,exports.usePaymentsEnabled=r.D,exports.useSales=r.O,exports.useTheme=t.y;
|
|
14
|
+
`}),(0,l.jsxs)(`div`,{className:`relative group/date flex flex-col w-full`,children:[(0,l.jsx)(t.g,{type:`date`,label:`Date`,required:!0,value:R.dateStr,onChange:e=>z({...R,dateStr:e.target.value}),className:`pr-10`}),(0,l.jsx)(`div`,{className:`absolute right-4 bottom-4 pointer-events-none group-focus-within/date:text-accent text-foreground/40 transition-colors`,children:(0,l.jsx)(n.ir,{className:`w-4 h-4`})})]}),(0,l.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-4`,children:[J?(0,l.jsx)(t.g,{type:`time`,label:`Time`,value:R.time,onChange:e=>z({...R,time:e.target.value}),required:!0}):(()=>{let{h:e,m:t,ampm:n}=Q(R.time);return(0,l.jsxs)(`div`,{className:`flex flex-col w-full`,children:[(0,l.jsx)(`label`,{className:`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,children:`Time`}),(0,l.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,l.jsx)(`input`,{type:`number`,min:1,max:12,value:e,onChange:e=>z({...R,time:ce(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,l.jsx)(`span`,{className:`text-foreground/40 font-bold text-[15px] select-none`,children:`:`}),(0,l.jsx)(`input`,{type:`number`,min:0,max:59,value:t.toString().padStart(2,`0`),onChange:t=>z({...R,time:ce(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,l.jsx)(`button`,{type:`button`,onClick:()=>z({...R,time:ce(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,l.jsx)(t.g,{type:`number`,min:`1`,max:`1440`,label:`Duration (min)`,value:R.duration,onChange:e=>z({...R,duration:e.target.value}),placeholder:`60`,required:!0})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,l.jsx)(`label`,{className:`text-[11px] font-bold text-foreground/50 uppercase tracking-widest mt-1`,children:`Event Color`}),(0,l.jsx)(`div`,{className:`flex gap-2 items-center relative z-10 w-full h-[46px]`,children:Fn.map(e=>(0,l.jsx)(`button`,{type:`button`,onClick:()=>z({...R,color:R.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:R.color===e.text&&(0,l.jsx)(`div`,{className:`w-2.5 h-2.5 rounded-full bg-background`})},e.name))})]}),(0,l.jsx)(`div`,{className:`pt-2`,children:(0,l.jsx)(t.h,{type:`submit`,isLoading:M,className:`w-full py-3`,children:R.id?`Save Changes`:`Create Event`})})]})]})]},`edit-modal`),(0,l.jsx)(me,{isOpen:!!I,title:`Confirm Deletion`,message:(0,l.jsxs)(l.Fragment,{children:[`Are you sure you want to delete `,(0,l.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:I?.title}),` This action is permanent.`]}),onConfirm:Ce,onCancel:()=>{L(null)},isProcessing:P,confirmText:`Yes, Delete`})]});return h?(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:p?.tabTitle||p?.tabName||e}),i&&(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),i]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.jsxs)(n.kt.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:[Oe(),Ae()]})]}),je()]}):(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[c&&(0,l.jsx)(Ne,{to:c}),(0,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(r.y,{children:e}),i&&(0,l.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,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),i]})]})]}),(0,l.jsx)(`div`,{className:`flex flex-col gap-6 flex-1 min-h-0 pb-16`,children:(0,l.jsxs)(n.kt.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,l.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`}),Oe(),Ae()]})}),je()]})}var Rn=[{name:`Purple Standard`,preview:[`#2e1065`,`#cdc1ff`],dark:{buttonText:`#ffffff`,background:`#07070f`,backgroundSecondary:`#0a0a18`,accent:`#a78bfa`,gradient:[`#6d28d9`,`#a78bfa`],text:[`#f0eeff`,`#c4b5fd`,`#a78bfa`]},light:{buttonText:`#ffffff`,background:`#fcfaff`,backgroundSecondary:`#f7f3ff`,accent:`#7c3aed`,gradient:[`#5b21b6`,`#a78bfa`],text:[`#2e1065`,`#6d28d9`,`#cdc1ff`]}},{name:`Royal Navy`,preview:[`#1e3a8a`,`#60a5fa`],dark:{buttonText:`#ffffff`,background:`#050b14`,backgroundSecondary:`#0a192f`,accent:`#60a5fa`,gradient:[`#1d4ed8`,`#60a5fa`],text:[`#dbeafe`,`#93c5fd`,`#60a5fa`]},light:{buttonText:`#ffffff`,background:`#f8fafc`,backgroundSecondary:`#f1f5f9`,accent:`#2563eb`,gradient:[`#1e3a8a`,`#60a5fa`],text:[`#1e3a8a`,`#2563eb`,`#60a5fa`]}},{name:`Emerald Green`,preview:[`#064e3b`,`#10b981`],dark:{buttonText:`#ffffff`,background:`#050806`,backgroundSecondary:`#0a2218`,accent:`#34d399`,gradient:[`#047857`,`#34d399`],text:[`#d1fae5`,`#6ee7b7`,`#34d399`]},light:{buttonText:`#ffffff`,background:`#f6fbf8`,backgroundSecondary:`#eff7f2`,accent:`#059669`,gradient:[`#064e3b`,`#10b981`],text:[`#064e3b`,`#059669`,`#10b981`]}},{name:`Gold`,preview:[`#854d0e`,`#eab308`],dark:{buttonText:`#000000`,background:`#0f0905`,backgroundSecondary:`#1c1208`,accent:`#fcd34d`,gradient:[`#ca8a04`,`#facc15`],text:[`#fefce8`,`#fef08a`,`#facc15`]},light:{buttonText:`#ffffff`,background:`#fbfaf6`,backgroundSecondary:`#f5f2eb`,accent:`#d97706`,gradient:[`#854d0e`,`#eab308`],text:[`#854d0e`,`#ca8a04`,`#eab308`]}},{name:`Silver`,preview:[`#1e293b`,`#94a3b8`],dark:{buttonText:`#ffffff`,background:`#090e17`,backgroundSecondary:`#101725`,accent:`#cbd5e1`,gradient:[`#475569`,`#94a3b8`],text:[`#e2e8f0`,`#94a3b8`,`#cbd5e1`]},light:{buttonText:`#ffffff`,background:`#f8fafc`,backgroundSecondary:`#e2e8f0`,accent:`#64748b`,gradient:[`#1e293b`,`#94a3b8`],text:[`#1e293b`,`#475569`,`#94a3b8`]}},{name:`Barbie Pink`,preview:[`#d946ef`,`#f472b6`],dark:{buttonText:`#ffffff`,background:`#0c030a`,backgroundSecondary:`#1a0515`,accent:`#ff80ff`,gradient:[`#c026d3`,`#f472b6`],text:[`#ffeeff`,`#ffb3ff`,`#ff80ff`]},light:{buttonText:`#ffffff`,background:`#fcf5fa`,backgroundSecondary:`#f5ebf2`,accent:`#d946ef`,gradient:[`#c026d3`,`#ec4899`],text:[`#a21caf`,`#c026d3`,`#ec4899`]}},{name:`Orange`,preview:[`#7c2d12`,`#f97316`],dark:{buttonText:`#ffffff`,background:`#0a0200`,backgroundSecondary:`#1c0b05`,accent:`#fb923c`,gradient:[`#c2410c`,`#fb923c`],text:[`#fff7ed`,`#fdba74`,`#fb923c`]},light:{buttonText:`#ffffff`,background:`#fdf6f2`,backgroundSecondary:`#f5ebe4`,accent:`#ea580c`,gradient:[`#7c2d12`,`#f97316`],text:[`#7c2d12`,`#ea580c`,`#f97316`]}},{name:`Red`,preview:[`#7f1d1d`,`#ef4444`],dark:{buttonText:`#ffffff`,background:`#0a0000`,backgroundSecondary:`#2e0a0a`,accent:`#ef4444`,gradient:[`#b91c1c`,`#f87171`],text:[`#fef2f2`,`#fecaca`,`#f87171`]},light:{buttonText:`#ffffff`,background:`#fdf5f5`,backgroundSecondary:`#f5ebeb`,accent:`#dc2626`,gradient:[`#7f1d1d`,`#ef4444`],text:[`#7f1d1d`,`#dc2626`,`#ef4444`]}},{name:`Black & White`,preview:[`#ffffff`,`#000000`],dark:{buttonText:`#000000`,background:`#000000`,backgroundSecondary:`#111111`,accent:`#ffffff`,gradient:[`#ffffff`,`#e5e7eb`],text:[`#ffffff`,`#f3f4f6`,`#ffffff`]},light:{buttonText:`#ffffff`,background:`#ffffff`,backgroundSecondary:`#f3f4f6`,accent:`#000000`,gradient:[`#000000`,`#1f2937`],text:[`#000000`,`#1f2937`,`#374151`]}}],zn=[{key:`light`,label:`Light mode`,icon:n.Jt,description:`How the site looks for someone with light mode on.`},{key:`dark`,label:`Dark mode`,icon:n.pn,description:`How the site looks for someone with dark mode on.`}],Bn=n.o,Vn=`flex items-center gap-2 w-full h-10 px-1.5 rounded-[var(--input-radius,0.75rem)] border border-[var(--panel-border)] bg-[var(--panel-bg)] transition-all focus-within:border-accent hover:border-accent/40`,Hn=`outline outline-1 outline-[var(--panel-border)]`,Un=e=>JSON.parse(JSON.stringify(e)),Wn=(e,t)=>{if(typeof e!=`object`||!e||Array.isArray(e)||typeof t!=`object`||!t||Array.isArray(t))return JSON.stringify(e)===JSON.stringify(t)?void 0:e;let n={};for(let r of Object.keys(e)){let i=Wn(e[r],t[r]);i!==void 0&&(n[r]=i)}return Object.keys(n).length?n:void 0},Gn=e=>{let t=(e||``).replace(`#`,``).trim();return t.length===3?[0,1,2].map(e=>parseInt(t[e]+t[e],16)):t.length===6?[0,2,4].map(e=>parseInt(t.substring(e,e+2),16)):null},Kn=(e,t,n)=>{let r=e=>Math.max(0,Math.min(255,Math.round(e)));return`#${[e,t,n].map(e=>r(e).toString(16).padStart(2,`0`)).join(``)}`},qn=e=>{let t=(e||``).trim();if(t.startsWith(`#`)){let e=Gn(t);return e?Kn(e[0],e[1],e[2]):null}let n=t.match(/^rgba?\(\s*([\d.]+)[\s,]+([\d.]+)[\s,]+([\d.]+)/i);return n?Kn(parseFloat(n[1]),parseFloat(n[2]),parseFloat(n[3])):null},Jn=(e,t)=>{let n=Gn(e);return n?Kn(n[0]*t,n[1]*t,n[2]*t):e},Yn=e=>e?Array.isArray(e)?e.length===1?e[0]:`linear-gradient(135deg, ${e.join(`, `)})`:e:``,Xn=(e,t)=>{let n=Gn(qn(t)||t);if(!n)return{};let r=e=>`rgba(${n[0]}, ${n[1]}, ${n[2]}, ${e})`;return{panelBg:e===`dark`?r(`0.05`):`rgba(255, 255, 255, 0.70)`,panelBorder:r(e===`dark`?`0.15`:`0.08`),glowColor:r(e===`dark`?`0.40`:`0.30`),selectionBg:r(e===`dark`?`0.40`:`0.30`)}};function Zn({label:e,hint:t,value:r,over:i,onChange:a}){let o=qn(r)||`#7c3aed`;return(0,l.jsxs)(`div`,{className:`flex flex-col gap-1.5 p-3.5 sm:p-4 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,l.jsx)(`label`,{className:`text-[12.5px] font-bold text-foreground truncate`,children:e}),(0,l.jsxs)(`label`,{className:`relative w-7 h-7 rounded-lg cursor-pointer shrink-0 transition-all hover:scale-105 active:scale-95 flex items-center justify-center focus-within:ring-2 focus-within:ring-accent ${Hn}`,title:`Pick a colour for ${e}`,children:[(0,l.jsx)(`span`,{"aria-hidden":!0,className:`absolute inset-0 rounded-[inherit]`,style:{backgroundColor:i||`transparent`}}),(0,l.jsx)(`span`,{"aria-hidden":!0,"data-testid":`color-swatch`,className:`absolute inset-0 rounded-[inherit]`,style:{backgroundColor:r||`transparent`}}),(0,l.jsx)(`input`,{type:`color`,"aria-label":`${e} colour picker`,value:o,onChange:e=>a(e.target.value),className:`absolute inset-0 w-full h-full opacity-0 cursor-pointer p-0 border-0`})]})]}),t&&(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/45 font-medium leading-snug`,children:t}),(0,l.jsx)(`input`,{type:`text`,"aria-label":e,value:r??``,onChange:e=>a(e.target.value),className:Bn})]})}function Qn({label:e,hint:t,value:r,onChange:i}){let a=Array.isArray(r)&&r.length?r:[`#7c3aed`,`#6d28d9`],o=(e,t)=>{let n=[...a];n[e]=t,i(n)};return(0,l.jsxs)(`div`,{className:`flex flex-col gap-2.5 p-3.5 sm:p-4 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,l.jsx)(`label`,{className:`text-[12.5px] font-bold text-foreground truncate`,children:e}),(0,l.jsx)(`div`,{"data-testid":`gradient-preview`,className:`w-16 h-5 rounded-lg shrink-0 ${Hn}`,style:{background:Yn(a)}})]}),t&&(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/45 font-medium leading-snug`,children:t}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-2 pt-1.5`,children:[a.map((t,r)=>(0,l.jsxs)(`div`,{className:Vn,children:[(0,l.jsx)(`label`,{className:`relative w-6 h-6 rounded-md cursor-pointer shrink-0 transition-all hover:scale-105 active:scale-95 flex items-center justify-center ${Hn}`,style:{backgroundColor:t||`transparent`},title:`Pick colour ${r+1} for ${e}`,children:(0,l.jsx)(`input`,{type:`color`,"aria-label":`${e} colour ${r+1} picker`,value:qn(t)||`#7c3aed`,onChange:e=>o(r,e.target.value),className:`absolute inset-0 w-full h-full opacity-0 cursor-pointer p-0 border-0`})}),(0,l.jsx)(`input`,{type:`text`,"aria-label":`${e} colour ${r+1}`,value:t,onChange:e=>o(r,e.target.value),className:`flex-1 min-w-0 h-full bg-transparent border-0 px-0 text-[12px] font-semibold text-foreground outline-none`}),a.length>2&&(0,l.jsx)(`button`,{type:`button`,onClick:()=>i(a.filter((e,t)=>t!==r)),"aria-label":`Remove colour ${r+1} from ${e}`,className:`w-6 h-6 rounded-md flex items-center justify-center text-foreground/35 hover:text-red-500 hover:bg-red-500/10 transition-colors cursor-pointer shrink-0`,children:(0,l.jsx)(n.Pt,{className:`w-3.5 h-3.5`})})]},r)),a.length<6&&(0,l.jsxs)(`button`,{type:`button`,onClick:()=>i([...a,Jn(a[a.length-1]||`#6d28d9`,.9)]),className:`w-full h-9 px-3 rounded-lg border border-dashed border-accent/40 hover:border-accent bg-accent/[0.03] hover:bg-accent/10 text-accent text-[11.5px] font-bold flex items-center justify-center gap-1.5 transition-all active:scale-[0.99] cursor-pointer shadow-2xs mt-0.5`,children:[(0,l.jsx)(n.cn,{className:`w-3.5 h-3.5`}),`Add another colour`]})]})]})}function $n({label:e,hint:t,value:r,onChange:i}){let a=Number.isFinite(r)?r:0;return(0,l.jsx)(n.r,{label:e,hint:t,action:(0,l.jsxs)(`span`,{className:`text-[11px] font-bold text-foreground/50 tabular-nums shrink-0`,children:[Math.round(a*16),`px`]}),children:(0,l.jsx)(`input`,{type:`range`,min:0,max:3,step:.125,value:a,"aria-label":e,onChange:e=>i(parseFloat(e.target.value)),className:`w-full accent-accent cursor-pointer`})})}function er({title:e,onReset:t}){return(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3 pt-2 first:pt-0`,children:[(0,l.jsx)(`span`,{className:`text-[11px] font-black uppercase tracking-wider text-foreground/40`,children:e}),(0,l.jsx)(n.i,{icon:n.rn,compact:!0,title:`Reset ${e.toLowerCase()}`,onClick:t,children:`Reset`})]})}var tr=[`accent`,`foreground`,`background`,`backgroundSecondary`,`textGradient`,`notificationIconColor`],nr=[`buttonGradient`,`buttonHoverGradient`,`buttonText`,`secondaryButton`],rr=[`panelBg`,`panelBorder`,`glowColor`,`selectionBg`,`selectionText`],ir=`fbos_theme_ai_draft`,ar=()=>{try{return JSON.parse(localStorage.getItem(ir)||`{}`)}catch{return{}}},or=`Every mode needs these five: background, backgroundSecondary, foreground, accent and buttonText. Set any other colour I have actually named as well — the button fades, the quiet button, panel fill and edge, the highlight, the focus glow, the notification dot, the heading gradient — using my exact values where I gave them. Any colour I have NOT named, delete from the file rather than leaving it there: the app works those out from the five, and a colour left over from the look before is what makes a new theme come out wrong. Never copy a colour from another theme or an example.`,sr=`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.`,cr=`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.`,lr=e=>[...[`Design the look of my whole app. Here is what I am after: ${String(e?.brief||``).trim()||`___`}`,...String(e?.logoUrl||``).trim()?[sr]:[],`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.`,`Set the dark colours and the light colours both, so my site reads well either way. 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.`,or,...fr(e),cr],...pr].join(`
|
|
15
|
+
`),ur=e=>[...[`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.`,or,`Here is what I would like changed: ${String(e?.changes||``).trim()||`___`}`,...fr(e)],...pr].join(`
|
|
16
|
+
`),dr=e=>{let t=String(e?.defaultTheme||``).trim();return t===`light`?`In that same file, set defaultTheme to 'light' so my site always opens in light mode.`:t===`dark`?`In that same file, set defaultTheme to 'dark' so my site always opens in dark mode.`:t===`system`?`In that same file, set defaultTheme to 'system' so my site opens in whichever mode the visitor's device already uses.`:`Leave defaultTheme exactly as it is — how my site opens is not part of this job, and changing it is not a redesign.`},fr=e=>{let t=String(e?.appName||``).trim(),n=String(e?.logoUrl||``).trim(),r=String(e?.faviconUrl||``).trim(),i=[dr(e)];return t&&i.push(`In that same file, set appName to exactly: ${t}`),n&&i.push(`In that same file, set logoUrl to exactly this link: ${n} — 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.`),r&&i.push(r===n?`Set faviconUrl to that same link — it is my browser tab icon too.`:`In that same file, set faviconUrl to exactly this link: ${r} — that is my browser tab icon. Use my link character for character.`),!n&&!r?i.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.`):n?r||i.push(`Leave faviconUrl exactly as it is — my browser tab icon is mine, and my Theme screen is the only place it changes.`):i.push(`Leave logoUrl exactly as it is — my logo is mine, and my Theme screen is the only place it changes.`),i},pr=[`Tell me what you picked and why, in one short paragraph.`,`If nothing changes on my site after you edit that file, say so — a look I have saved in the app wins over the file, and I can undo that with Start again on my Theme screen.`],mr=(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.`,hr=[`appName`,`defaultTheme`,`showThemeToggle`],gr=[`cornerRounding`,`cornerRadii`];function _r(){let{activeConfig:e,theme:i}=t.y(),s=n.br(),c=(0,a.useMemo)(()=>Un(s?.themeConfig||n.Tr),[s]),[d,f]=(0,a.useState)(null),[p,m]=(0,a.useState)(ar),[h,g]=(0,a.useState)(()=>ar().mode===`change`?`change`:`design`),_=e=>{g(e),m(t=>{let n={...t};e===`change`?n.mode=`change`:delete n.mode;try{localStorage.setItem(ir,JSON.stringify(n))}catch{}return n})},v=(e,t)=>m(n=>{let r={...n,[e]:t};try{localStorage.setItem(ir,JSON.stringify(r))}catch{}return r}),[y,b]=(0,a.useState)(!1),[x,S]=(0,a.useState)(null),[C,w]=(0,a.useState)(!1),[T,E]=(0,a.useState)(null),D=a.default.useRef(null);(0,a.useEffect)(()=>{if(!e)return;let t=JSON.stringify(Un(e)),n=d?JSON.stringify(d):null;n!==t&&(n&&n!==D.current||(D.current=t,f(JSON.parse(t))))},[e,d]),(0,a.useEffect)(()=>{try{let e=sessionStorage.getItem(`fbos_theme_scrollY`);e&&requestAnimationFrame(()=>window.scrollTo(0,parseInt(e,10)))}catch{}let e=()=>{try{sessionStorage.setItem(`fbos_theme_scrollY`,String(window.scrollY))}catch{}};return window.addEventListener(`scroll`,e,{passive:!0}),()=>window.removeEventListener(`scroll`,e)},[]),(0,a.useEffect)(()=>{if(!d)return;let e=JSON.stringify(d);if(e===D.current)return;let t=setTimeout(async()=>{b(!0);try{let t=Wn(d,c);t?await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,`theme`),t):(await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_configs`,`theme`)),localStorage.removeItem(`theme_config_cache`)),D.current=e,S(Date.now())}catch(e){console.error(`Auto-save failed`,e)}b(!1)},300);return()=>clearTimeout(t)},[d,c]);let O=(e,t)=>f(n=>({...n,[e]:t})),k=(e,t)=>f(n=>({...n,colors:{...n.colors,[e]:{...n.colors?.[e]||{},...t}}})),A=(e,t)=>f(n=>({...n,colors:{...n.colors,[e]:{...n.colors?.[e]||{},secondaryButton:{...n.colors?.[e]?.secondaryButton||{},...t}}}})),j=(e,t)=>f(n=>{let r={...n?.colors?.[e]||{}};return delete r.notificationIconColor,{...n,colors:{...n?.colors,[e]:{...r,accent:t,...Xn(e,t)}}}}),M=(e,t,n,r)=>E({title:e,message:t,apply:n,confirmText:r}),N=e=>f(t=>{let n=Un(t);return e.forEach(e=>{c[e]===void 0?delete n[e]:n[e]=Un(c[e])}),n}),P=(e,t)=>f(n=>{let r=Un(n),i=c.colors?.[e]||{};return r.colors=r.colors||{},r.colors[e]=r.colors[e]||{},t.forEach(t=>{i[t]===void 0?delete r.colors[e][t]:r.colors[e][t]=Un(i[t])}),r}),F=e=>{if(!d)return;let t=Un(d);t.colors=t.colors||{},[`dark`,`light`].forEach(n=>{let r=e[n],i=t.colors[n]||{};t.colors[n]={...i,accent:r.accent,buttonGradient:[...r.gradient],buttonHoverGradient:[...r.gradient],buttonText:r.buttonText,notificationIconColor:r.accent,textGradient:[...r.text],foreground:r.text[0],background:r.background,backgroundSecondary:r.backgroundSecondary,...Xn(n,r.accent),...i.secondaryButton?{secondaryButton:{...i.secondaryButton,text:r.text[0]}}:{}}}),f(t)},I=!!(d&&Wn(d,c)?.colors),L=()=>f(e=>({...e,colors:Un(c.colors)})),R=async()=>{w(!0);try{let e=Un(c);await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_configs`,`theme`)),localStorage.removeItem(`theme_config_cache`),localStorage.removeItem(`theme-mode`),localStorage.removeItem(`last-seen-default-theme`),localStorage.removeItem(ir),m({}),_(`design`),D.current=JSON.stringify(e),f(e)}catch{}setTimeout(()=>w(!1),600)},z=e=>{let t=zn.find(t=>t.key===e),r=d?.colors?.[e]||{},a=c.colors?.[e]||{},o=r.background||a.background||`#ffffff`;return(0,l.jsxs)(n.u,{icon:t.icon,title:t.label,description:t.description,defaultOpen:i===e,actions:(0,l.jsx)(n.i,{icon:n.rn,compact:!0,title:`Reset ${t.label.toLowerCase()}`,onClick:n=>{n.stopPropagation(),M(`Reset ${t.label.toLowerCase()}?`,`Every colour in ${t.label.toLowerCase()} — the brand colours, the buttons and the panels — goes back to how it started. The other mode is left alone.`,()=>P(e,[...tr,...nr,...rr]))},children:`Reset`}),children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-3 p-3.5 sm:p-4 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,l.jsx)(`span`,{className:`text-[12.5px] font-bold text-foreground`,children:`Ready-made colour sets`}),(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/45 font-medium leading-snug`,children:`One click repaints light and dark together.`})]}),(0,l.jsx)(`div`,{className:`flex items-center gap-3 overflow-x-auto no-scrollbar py-2.5 px-2.5 -mx-2.5`,children:Rn.map(t=>{let n=r.accent===t[e].accent&&d?.colors?.[e]?.buttonGradient?.[0]===t[e].gradient[0],i=t.name===`Black & White`;return(0,l.jsx)(`button`,{type:`button`,onClick:()=>F(t),"aria-label":t.name,title:t.name,className:`w-9 h-9 rounded-full shrink-0 transition-all relative cursor-pointer outline-offset-2 ${n?`outline-2 outline-accent scale-110 z-10`:`opacity-80 outline-0 hover:opacity-100 hover:outline-2 hover:outline-foreground/25 hover:scale-105`}`,style:i?{background:`linear-gradient(135deg, #ffffff 0%, #ffffff 50%, #000000 50%, #000000 100%)`}:{backgroundImage:`linear-gradient(135deg, ${t.preview[0]}, ${t.preview[1]})`}},t.name)})})]}),(0,l.jsx)(er,{title:`Brand and colours`,onReset:()=>M(`Reset the colours?`,`The brand colour, the text and the two backgrounds in ${t.label.toLowerCase()} go back to how they started. Nothing else changes.`,()=>P(e,tr))}),(0,l.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 items-start`,children:[(0,l.jsx)(Zn,{over:o,label:`Brand colour`,hint:`Links, highlights and the main buttons. Panels follow it too.`,value:r.accent||a.accent||`#7c3aed`,onChange:t=>j(e,t)}),(0,l.jsx)(Zn,{over:o,label:`Text colour`,hint:`Primary typography colour used across the app.`,value:r.foreground||a.foreground||`#111827`,onChange:t=>k(e,{foreground:t})}),(0,l.jsx)(Zn,{over:o,label:`Page background`,hint:`Main background canvas colour under all content.`,value:r.background||a.background||`#ffffff`,onChange:t=>k(e,{background:t})}),(0,l.jsx)(Zn,{over:o,label:`Second background`,hint:`The colour the page background fades into.`,value:r.backgroundSecondary||a.backgroundSecondary||`#f9fafb`,onChange:t=>k(e,{backgroundSecondary:t})}),(0,l.jsx)(Zn,{over:o,label:`Notification dot`,hint:`Colour applied to notification badging.`,value:r.notificationIconColor||r.accent||a.notificationIconColor||`#7c3aed`,onChange:t=>k(e,{notificationIconColor:t})}),(0,l.jsx)(Qn,{label:`Heading colours`,hint:`The colours big headings fade through.`,value:r.textGradient||a.textGradient,onChange:t=>k(e,{textGradient:t})})]}),(0,l.jsx)(er,{title:`Buttons`,onReset:()=>M(`Reset the buttons?`,`Every button colour in ${t.label.toLowerCase()} goes back to how it started. Nothing else changes.`,()=>P(e,nr))}),(0,l.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-3 gap-3 items-start`,children:[(0,l.jsx)(Qn,{label:`Button colours`,hint:`The colours your main buttons fade through.`,value:r.buttonGradient||a.buttonGradient,onChange:t=>k(e,{buttonGradient:t})}),(0,l.jsx)(Qn,{label:`Button colours on hover`,hint:`How a main button looks under the pointer.`,value:r.buttonHoverGradient||a.buttonHoverGradient,onChange:t=>k(e,{buttonHoverGradient:t})}),(0,l.jsx)(Zn,{over:o,label:`Button text`,hint:`The writing on your main buttons.`,value:r.buttonText||a.buttonText||`#ffffff`,onChange:t=>k(e,{buttonText:t})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-2 mt-1`,children:[(0,l.jsx)(`span`,{className:`text-[10px] font-extrabold uppercase tracking-wider text-foreground/40`,children:`Quieter buttons`}),(0,l.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-3 gap-3 items-start`,children:[(0,l.jsx)(Zn,{over:o,label:`Quiet button fill`,value:r.secondaryButton?.bg||a.secondaryButton?.bg||`rgba(0, 0, 0, 0.03)`,onChange:t=>A(e,{bg:t})}),(0,l.jsx)(Zn,{over:o,label:`Quiet button edge`,value:r.secondaryButton?.border||a.secondaryButton?.border||`rgba(0, 0, 0, 0.06)`,onChange:t=>A(e,{border:t})}),(0,l.jsx)(Zn,{over:o,label:`Quiet button text`,value:r.secondaryButton?.text||a.secondaryButton?.text||`#111827`,onChange:t=>A(e,{text:t})})]})]}),(0,l.jsx)(er,{title:`Panels and highlights`,onReset:()=>M(`Reset the panels?`,`Panels, edges, the focus glow and text highlighting in ${t.label.toLowerCase()} go back to how they started. Nothing else changes.`,()=>P(e,rr))}),(0,l.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 items-start`,children:[(0,l.jsx)(Zn,{over:o,label:`Panel fill`,hint:`Background colour of cards and panels.`,value:r.panelBg||a.panelBg||`rgba(255, 255, 255, 0.70)`,onChange:t=>k(e,{panelBg:t})}),(0,l.jsx)(Zn,{over:o,label:`Panel edge`,hint:`Borders of panels, inputs and dropdowns.`,value:r.panelBorder||a.panelBorder||`rgba(0, 0, 0, 0.08)`,onChange:t=>k(e,{panelBorder:t})}),(0,l.jsx)(Zn,{over:o,label:`Focus glow`,hint:`The glow around the box someone is typing in.`,value:r.glowColor||a.glowColor||`rgba(124, 58, 237, 0.30)`,onChange:t=>k(e,{glowColor:t})}),(0,l.jsx)(Zn,{over:o,label:`Highlight`,hint:`The colour behind text someone has selected.`,value:r.selectionBg||a.selectionBg||`rgba(124, 58, 237, 0.30)`,onChange:t=>k(e,{selectionBg:t})}),(0,l.jsx)(Zn,{over:o,label:`Highlighted text`,hint:`The colour of the selected text itself.`,value:r.selectionText||a.selectionText||`#ffffff`,onChange:t=>k(e,{selectionText:t})})]})]},e)};return(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`Theme`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/theme`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.jsxs)(`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,l.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[(0,l.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-extrabold text-foreground tracking-tight`,children:h===`change`?`Change it with your assistant`:`Design it with your assistant`}),(0,l.jsxs)(`p`,{className:`text-[12.5px] sm:text-[13.5px] font-medium text-foreground/55 mt-1 sm:mt-1.5`,children:[(0,l.jsx)(`span`,{className:`sm:hidden`,children:`Fill these in for your assistant.`}),(0,l.jsx)(`span`,{className:`max-sm:hidden`,children:h===`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.`})]})]}),(0,l.jsx)(`div`,{className:`shrink-0 flex items-center gap-2`,children:(0,l.jsx)(n.i,{icon:n.rn,tone:`danger`,compact:!0,busy:C,title:`Start the whole look again`,onClick:()=>M(`Start the whole look again?`,`Every colour and every corner goes back to how it was the day you installed, and your answers in the assistant section above clear too. This cannot be undone.`,R),children:`Start again`})})]}),(0,l.jsx)(r.h,{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:p.logoUrl||``,onChange:e=>v(`logoUrl`,e),tips:r.m}),(0,l.jsx)(r.h,{label:`Browser tab icon`,hint:`The tiny picture on the browser tab.`,value:p.faviconUrl||``,onChange:e=>v(`faviconUrl`,e),tips:r.f}),(0,l.jsx)(n.h,{label:`App name`,hint:`It goes in the top bar and on the browser tab.`,value:p.appName||``,onChange:e=>v(`appName`,e),placeholder:`Bright Studio`}),(0,l.jsx)(n.d,{label:`How the site opens`,hint:`Only if you want it changed. Light, dark, or whichever one the visitor already uses on their device.`,value:p.defaultTheme||``,onChange:e=>v(`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`}]}),h===`change`?(0,l.jsx)(n.m,{label:`What would you like changed?`,hint:`Name just the parts you want moved. Everything else stays as it is.`,value:p.changes||``,onChange:e=>v(`changes`,e),placeholder:`Make the buttons a softer green, and warm up the page background a little. Leave the cards as they are.`}):(0,l.jsx)(n.m,{label:`What look would you like?`,hint:`What you do, who it is for, and the feeling you are after.`,value:p.brief||``,onChange:e=>v(`brief`,e),placeholder:`A calm, modern look for a small physiotherapy clinic. Soft greens, lots of white space, nothing shouty. Rounded corners.`}),I&&(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)] transition-colors hover:border-accent/40 p-3.5 sm:p-4 flex items-start sm:items-center justify-between gap-3 flex-col sm:flex-row`,children:[(0,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(`p`,{className:`text-[13px] font-bold text-foreground`,children:`Colours saved here are covering the file`}),(0,l.jsx)(`p`,{className:`text-[12px] font-medium text-foreground/55 leading-snug mt-0.5`,children:`You have colours saved on this screen, and they win over anything your assistant writes. Clear them and your new look will show. Nothing else on this screen changes.`})]}),(0,l.jsx)(n.i,{icon:n.rn,compact:!0,className:`shrink-0 max-sm:self-end`,title:`Clear the colours saved on this screen`,onClick:()=>M(`Clear the saved colours?`,`Every colour goes back to the one in your theme file, so the look your assistant writes there is the one you see. Your app name, logo, browser tab icon and corners are not touched.`,L,`Clear them`),children:`Clear saved colours`})]}),(0,l.jsx)(r.g,{title:`Copy this to your assistant`,prompt:h===`change`?ur(p):lr(p),locked:!!mr(p,h),onCopied:h===`change`?void 0:()=>_(`change`)}),(0,l.jsxs)(`p`,{className:`text-[11.5px] text-foreground/45 font-medium leading-snug px-1`,children:[`Uploads are kept on your`,` `,(0,l.jsx)(u.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,l.jsxs)(`div`,{className:`mt-10 pt-8 border-t border-[var(--panel-border)]/50 mb-5 flex items-start justify-between gap-3`,children:[(0,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-[17px] sm:text-xl font-extrabold text-foreground tracking-tight`,children:`Change it by hand`}),(0,l.jsx)(`p`,{className:`text-[12.5px] sm:text-[13.5px] font-medium text-foreground/55 mt-1 sm:mt-1.5`,children:`One setting at a time. Changes show up straight away and save themselves.`})]}),(0,l.jsx)(`div`,{className:`shrink-0 flex items-center gap-2 pt-1`,children:(0,l.jsx)(n.l,{saving:y,savedAt:x})})]}),d?(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsxs)(n.u,{icon:n.vr,title:`Name and how it opens`,description:`What your site is called, and whether it opens light or dark.`,defaultOpen:!1,actions:(0,l.jsx)(n.i,{icon:n.rn,compact:!0,title:`Reset the name and how it opens`,onClick:()=>M(`Reset the name?`,`The name and the opening mode go back to how they started. Your logo and your browser tab icon are left alone.`,()=>N(hr)),children:`Reset`}),children:[(0,l.jsx)(n.h,{label:`Site name`,hint:`The name people see in the top bar and on the browser tab.`,value:d.appName||``,onChange:e=>O(`appName`,e),placeholder:`Your AI Firebase`}),(0,l.jsx)(r.h,{label:`Logo`,hint:`The picture in the top bar — changes straight away.`,value:d.logoUrl||``,onChange:e=>O(`logoUrl`,e),tips:r.m,action:(d.logoUrl||``)===(c.logoUrl||``)?void 0:(0,l.jsx)(n.i,{icon:n.rn,onClick:()=>O(`logoUrl`,c.logoUrl||``),children:`Put the original back`})}),(0,l.jsx)(r.h,{label:`Browser tab icon`,hint:`The tiny picture on the browser tab — changes straight away.`,value:d.faviconUrl||``,onChange:e=>O(`faviconUrl`,e),tips:r.f,action:(d.faviconUrl||``)===(c.faviconUrl||``)?void 0:(0,l.jsx)(n.i,{icon:n.rn,onClick:()=>O(`faviconUrl`,c.faviconUrl||``),children:`Put the original back`})}),(0,l.jsx)(n.d,{label:`How the site opens`,hint:`Light, dark, or whichever one the visitor already uses on their device.`,value:d.defaultTheme||`system`,onChange:e=>O(`defaultTheme`,e||`system`),allowEmpty:!1,options:[{value:`system`,label:`Whatever their device uses`},{value:`light`,label:`Always light`},{value:`dark`,label:`Always dark`}]}),(d.defaultTheme||`system`)===`system`&&(0,l.jsx)(n._,{label:`Let visitors switch it themselves`,hint:`Shows the sun and moon button in the top bar.`,enabled:d.showThemeToggle!==!1,onChange:e=>O(`showThemeToggle`,e)})]}),zn.map(e=>z(e.key)),(0,l.jsxs)(n.u,{icon:n.Yt,title:`Corners`,description:`How rounded everything looks.`,defaultOpen:!1,actions:(0,l.jsx)(n.i,{icon:n.rn,compact:!0,title:`Reset the corners`,onClick:()=>M(`Reset the corners?`,`Every corner goes back to how it started.`,()=>N(gr)),children:`Reset`}),children:[(0,l.jsx)(n.d,{label:`Rounding`,hint:`Keep the rounding we ship with, or set each corner yourself.`,value:d.cornerRounding||`default`,onChange:e=>O(`cornerRounding`,e||`default`),allowEmpty:!1,options:[{value:`default`,label:`Standard rounding`},{value:`custom`,label:`Set them myself`}]}),d.cornerRounding===`custom`&&(0,l.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-3`,children:[(0,l.jsx)($n,{label:`Buttons`,hint:`How round every button is.`,value:d.cornerRadii?.buttonRadius??.75,onChange:e=>O(`cornerRadii`,{...d.cornerRadii||{},buttonRadius:e})}),(0,l.jsx)($n,{label:`Boxes people type in`,hint:`Form fields and search boxes.`,value:d.cornerRadii?.inputRadius??.75,onChange:e=>O(`cornerRadii`,{...d.cornerRadii||{},inputRadius:e})}),(0,l.jsx)($n,{label:`Cards`,hint:`The panels your content sits on.`,value:d.cornerRadii?.cardRadius??1.5,onChange:e=>O(`cornerRadii`,{...d.cornerRadii||{},cardRadius:e})}),(0,l.jsx)($n,{label:`Pop-ups`,hint:`Dialogs and confirmation boxes.`,value:d.cornerRadii?.modalRadius??2.5,onChange:e=>O(`cornerRadii`,{...d.cornerRadii||{},modalRadius:e})})]})]})]}):(0,l.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,l.jsx)(n.yn,{className:`w-6 h-6 animate-spin text-accent`})})]})]}),(0,l.jsx)(me,{isOpen:!!T,title:T?.title||``,message:T?.message||``,confirmText:T?.confirmText||`Reset`,cancelText:`Keep it`,isProcessing:C,onCancel:()=>E(null),onConfirm:()=>{T?.apply(),E(null)}})]})}function vr({tone:e,title:t,message:n,action:r}){let i=e===`red`?`border-red-500/20`:`border-amber-500/25`,a=e===`red`?`bg-red-500/5`:`bg-amber-500/5`,o=e===`red`?`text-red-500`:`text-amber-500`;return(0,l.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,l.jsxs)(`div`,{className:`glass-panel p-8 md:p-10 rounded-3xl border ${i} text-center shadow-xl max-w-sm w-full relative overflow-hidden`,children:[(0,l.jsx)(`div`,{className:`absolute inset-0 ${a}`}),(0,l.jsx)(`h2`,{className:`text-2xl font-black ${o} mb-3 relative z-10 tracking-tight`,children:t}),(0,l.jsx)(`p`,{className:`text-[14px] text-foreground/70 font-medium leading-relaxed relative z-10 mb-6`,children:n}),(0,l.jsx)(`div`,{className:`relative z-10`,children:r})]})})}var yr=`w-full block py-2.5 bg-foreground/5 hover:bg-foreground/10 text-foreground text-[14px] font-bold rounded-xl transition-colors`,br=`No access`,xr=`You do not have access to view this page. If you think you should, ask whoever runs this app.`,Sr=()=>(0,l.jsx)(vr,{tone:`amber`,title:br,message:xr,action:(0,l.jsx)(u.Link,{to:`/dashboard`,className:yr,children:`Back to dashboard`})}),Cr=Sr,wr=Sr,Tr={route:`/page_1`,pageName:`New Page`,pageTitle:`My New Page`,template:`none`,form:``},Er={tabName:`New Page`,iconName:``,route:`/new-page`,tabTitle:`Your Page`,template:`none`,form:``},Dr={tabName:`New Admin Page`,iconName:``,route:`/new-admin-page`,tabTitle:`Admin Page`,template:`none`,form:``},Or={tabName:`New Team Page`,iconName:``,route:`/new-team-page`,tabTitle:`Team Page`,template:`none`,form:``},kr=`sys_payments`,Ar=`_settings`,jr=()=>({on:!1,amount:``,priceId:``,livePriceId:``}),Mr=()=>({name:``,description:``,monthly:{...jr(),on:!0},yearly:jr()}),Nr=()=>({name:``,amount:``}),Pr=e=>({id:e,name:``,description:``,kind:``,amount:``,items:[],plans:[],how:``,emailReceipt:!0,notifyOwner:!0,pageIds:[],pagesNote:``,customNote:``,customPath:``,createdAt:Date.now()}),Fr=e=>e.kind===`once`?e.items.length?e.items:e.name.trim()||e.amount.trim()?[{name:e.name,amount:e.amount}]:[]:[],Ir=e=>{let t=Number(String(e||``).trim().replace(/[^0-9.]/g,``));return Number.isFinite(t)&&t>0?t:null},Lr=e=>({on:!!e?.on,amount:String(e?.amount||``),priceId:String(e?.priceId||``),livePriceId:String(e?.livePriceId||``)}),Rr=e=>/^(no|none|nothing|n\/?a|nothing needed|nothing else|-)[.!]*$/i.test(e.trim()),zr=e=>/[.!?]$/.test(e)?e:`${e}.`,Br=e=>{let t=[],n=String(e?.how||``),r=String(e?.collect||``).trim();r&&!Rr(r)&&t.push(`Before paying, the buyer tells me: ${zr(r)}`);let i=String(e?.after||``).trim();if(i&&t.push(`After they pay: ${zr(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: ${zr(r)}`),i&&t.push(`Someone on ${e} sees: ${zr(i)}`)}return t.length?[...n.trim()?[zr(n.trim())]:[],...t].join(` `):n},Vr=(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:Lr(e?.monthly),yearly:Lr(e?.yearly)})):[],how:Br(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}},Hr=e=>/^price_[A-Za-z0-9]+$/.test(e.trim()),Ur=(e,t=Ei())=>t?e.livePriceId:e.priceId;function Wr(e,t=Ei()){if(!e.kind)return`Say how it is paid — once, or a subscription.`;if(e.kind===`once`){let t=Fr(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(Ir(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(Ir(i.amount)===null)return`Give ${e} its ${r} price — just a number.`;if(!Hr(Ur(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 Gr=(e,t=Ei())=>Wr(e,t)===``,Kr=e=>e.kind===`subscription`&&e.plans.length>0&&e.plans.every(e=>e.name.trim()!==``&&(e.monthly.on||e.yearly.on)&&(!e.monthly.on||Ir(e.monthly.amount)!==null)&&(!e.yearly.on||Ir(e.yearly.amount)!==null));function qr(e){let t=e.name.trim();if(t)return t;let n=Fr(e);return n.length===1&&n[0].name.trim()?n[0].name.trim():`this product`}function Jr(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=Fr(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 Yr(e,t,n=Ei()){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 Xr=e=>e.includes(`'`)?`"${e}"`:`'${e}'`,Zr=`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.`,Qr=(e,t=Ei())=>{let n=e.name.trim()||`this product`,r=e.description.trim();if(e.kind===`once`){let t=Fr(e),r=e=>`<PayButton amount={${Ir(e.amount)??0}} productName=${Xr(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='${Ur(n.monthly,t).trim()}' mode='subscription'>`),n.yearly.on&&a.push(`${n.yearly.amount.trim()} per year: <PayButton priceId='${Ur(n.yearly,t).trim()}' mode='subscription'>`),i.push(`${e}${r?` (${r})`:``} — ${a.join(`; `)}.`)}return i},$r=`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.`,ei=`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 ti(e,t=``,n=Ei()){let r=[...Qr(e,n)],i=e.how.trim();i&&r.push(`Here is how this payment should work, start to finish: ${i}`),r.push($r),e.kind===`subscription`&&r.push(ei),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 ni=e=>e===`internal`||e===`admin`,ri=()=>({name:``,address:``,type:`internal`,iconName:``,template:`none`,form:``,formFields:``,formButton:``,formSpot:``,about:``}),ii=e=>Array.isArray(e?.links)?e.links.map(e=>{let t={pageId:String(e?.pageId||``),how:String(e?.how||``)};if(e?.draft&&typeof e.draft==`object`){let n=e.draft,r=ri();t.draft={name:String(n.name??r.name),address:String(n.address??r.address),type:String(n.type||r.type),iconName:String(n.iconName??r.iconName),template:String(n.template||r.template),form:String(n.form??r.form),formFields:String(n.formFields??r.formFields),formButton:String(n.formButton??r.formButton),formSpot:String(n.formSpot??r.formSpot),about:String(n.about??r.about)}}return t}):[],ai=(e,t)=>t.find(t=>t.id===e)||t.find(t=>String(t.config?.contentKey||``).trim()===e),oi=(e,t)=>e===t.id||e===String(t.config?.contentKey||``).trim();function si(e){return e.how.trim()?``:`Describe how this payment will work.`}var ci=(e,t)=>t.filter(t=>e.pageIds.some(e=>oi(e,t))),li=(e,t)=>e.pageIds.some(e=>oi(e,t)),ui=(e,t)=>li(e,t)?e.pageIds.filter(e=>!oi(e,t)):[...e.pageIds,t.id],di=(e,t)=>ci(e,t).length||e.pagesNote.trim()?``:`Tick the pages it goes on, or describe a page to add.`;function fi(e,t,n=Ei()){if(!e.length)return`Describe what you sell first — the request is built from it.`;for(let t of e){let e=Jr(t).split(` — `)[0];if(!Gr(t,n))return`Finish ${e} under What you sell.`;if(si(t))return`Say how ${e} works under How your payments work.`}for(let n of e){let e=Jr(n).split(` — `)[0];if(di(n,t))return`Say where ${e} goes — tick its pages, or describe a page to add.`}return``}var pi={public:`anyone`,user:`signed-in users`,internal:`your team`,admin:`admins only`},mi=`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, CustomSelect } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button, and every dropdown is CustomSelect (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser's own <select>, which ignores my theme. The design should be minimal, modern and clean.`,hi=`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.`,gi="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.",_i=[`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.`],vi=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``);function yi(e){let t=e.audience||`public`,n=ni(t),r=pi[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 t=e.config||{},n=vi(String(t.contentKey||t.tabName||t.pageName||t.pageId||e.title||``))||`Page`,r=n.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/${n}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 ${n}Content from './${n}Content'; and registerMicrocomponent('${r}', ${n}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.`);let a=String(t.form||``).trim();a&&a!==`__new__`&&i.push(`The page already has a form, '${a}' — show it with <ContactPopup formId='${a}' /> 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(gi),i}var bi=e=>`${e.path}${e.title?` (${e.title})`:``}`;function xi(e,t,n=Ei()){let r=[`Build ${e.length===1?`my payment`:`my payments`} into my app. ${Zr}`],i=[],a=!1;for(let o of e){let e=ci(o,t);for(let t of e)i.includes(t)||i.push(t);let s=e.filter(e=>!ni(e.audience)),c=s.length===1?s[0].path:``;r.push(...ti(o,c,n));let l=qr(o);e.length&&r.push(`${l} goes on ${e.length===1?`this page`:`these pages`} of mine: ${e.map(bi).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(...yi(e))}return a?r.push(`If my words name a page that does not exist yet, add it. ${_i[0]}`,..._i.slice(1)):r.push(`If the payments need a page my words do not name, make it the app's way. ${_i[0]}`),r.push(mi,hi),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(`
|
|
17
|
+
`)}var Si=[],Ci=!1,wi=()=>Si,Ti=e=>{Ci=e},Ei=()=>Ci;function Di(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();Hr(o)&&Hr(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 Oi(e=wi()){let t=Di(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(`
|
|
18
|
+
`)}var ki=`Could not reach the server. Check your connection and try again.`;async function Ai(e,t){try{let n=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}),r=await n.json().catch(()=>({}));return!n.ok||r?.success===!1?typeof r?.error==`string`&&r.error||`The email could not be sent.`:null}catch{return ki}}function ji(e,t={}){return Ai(`/api/email/notify`,{template:e,data:t})}function Mi(e,t,n,r={}){return Pi(`/api/email/send`,{template:e,collection:t,docId:n,data:r})}function Ni(e,t,n,r={}){return Pi(`/api/email/compose`,{to:e,subject:t,message:n,...r})}async function Pi(e,t){try{let r=await n.xr?.currentUser?.getIdToken().catch(()=>null),i=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`,...r?{Authorization:`Bearer ${r}`}:{}},body:JSON.stringify(t)}),a=await i.json().catch(()=>({}));return!i.ok||a?.success===!1?typeof a?.error==`string`&&a.error||`The email could not be sent.`:null}catch{return ki}}async function Fi(){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:ki}}}var Ii=e=>`${n.st(e)} · ${n.pt(e.slotMinutes)}`;function Li({schedules:e,selected:t,onPick:r,placeholder:i=`Pick a schedule`}){let[o,s]=(0,a.useState)(!1);if(e.length===0)return(0,l.jsxs)(`p`,{className:n.a,children:[`No schedule yet — add one on the`,` `,(0,l.jsx)(u.Link,{to:`/schedule`,className:`text-accent font-bold hover:underline`,children:`Schedule screen`}),` first.`]});let c=t.map(t=>e.find(e=>e.id===t)).filter(e=>!!e);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[(0,l.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 ${o?`border-accent`:`border-[var(--panel-border)] hover:border-accent/40`}`,children:[(0,l.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-wrap items-center gap-1.5`,children:[c.length===0&&(0,l.jsx)(`button`,{type:`button`,onClick:()=>s(e=>!e),className:`text-[14px] text-foreground/35 text-left cursor-pointer`,children:i}),c.map(e=>(0,l.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,l.jsx)(`span`,{className:`truncate`,children:n.st(e)}),(0,l.jsx)(`button`,{type:`button`,"aria-label":`Remove ${n.st(e)}`,onClick:()=>r(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,l.jsx)(n.Pt,{className:`w-3 h-3`})})]},e.id))]}),(0,l.jsx)(`button`,{type:`button`,"aria-label":o?`Close the list of schedules`:`Open the list of schedules`,"aria-expanded":o,onClick:()=>s(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,l.jsx)(n.tr,{className:`w-4 h-4 transition-transform ${o?`rotate-180`:``}`})})]}),o&&(0,l.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 i=t.includes(e.id),a=e.enabled?n.it(e)?`Unfinished on the Schedule screen`:``:`Turned off on the Schedule screen`;return(0,l.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":i,"aria-label":n.st(e),onClick:()=>r(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 ${n.I(e)?``:`opacity-70`}`,children:[(0,l.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${i?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:i&&(0,l.jsx)(n.nr,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,l.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate min-w-0`,children:Ii(e)}),a&&(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 whitespace-nowrap shrink-0 max-sm:hidden`,children:a})]},e.id)})}),(0,l.jsx)(`span`,{className:n.a,children:`One schedule per person — picking a second one of theirs replaces the first.`})]})}var Ri=!1,zi=e=>{Ri=e},Bi=()=>Ri,Vi=[{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:`setup`,title:`Setup`,path:`/setup`,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}],Hi=new Set([`home`,`dashboard`,`profile`]),Ui=e=>[...e,...Vi.filter(t=>!e.some(e=>e.id===t.id))],Wi={public:`Anyone`,user:`Signed-in users`,internal:`Your team`,admin:`Admins only`},Gi=e=>e.draft?`draft`:e.hidden?`hidden`:`live`,Ki={draft:`Draft`,live:`Live`,hidden:`Hidden`},qi={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.`},Ji=e=>(e||``).trim().toLowerCase().replace(/\s+/g,`-`).replace(/[^a-z0-9_-]/g,``),Yi=e=>String(e||``).replace(/^\/+/,``).replace(/[^a-zA-Z0-9_-]/g,`_`).toLowerCase();function Xi(e){let t=Ji(e.address);if(!t)throw Error(`A page needs a web address.`);let n=Yi(`/`+t),r=e.type===`public`,i={form:e.form||``,formFields:e.formFields||``,formButton:e.formButton||``,formSpot:e.formSpot||``},a=r?{route:`/`+t,pageName:e.name,pageTitle:e.name,...i,brief:e.about,contentKey:n}:{route:`/`+t,tabName:e.name,tabTitle:e.name,iconName:e.iconName||``,template:ia.some(t=>t.value===e.template)?e.template:`none`,...i,brief:e.about,pageType:e.type,contentKey:n};return a.form===`__new__`&&(a.form=Qa(a),a.formIsNew=!0),{id:n,config:a,isPublic:r}}async function Zi(e){let{id:t,config:r,isPublic:i}=Xi(e);await(0,o.setDoc)((0,o.doc)(n.Sr,i?`sys_pages`:`sys_tabs`,t),r);let a=i?`page_order`:`tab_order`,s=await(0,o.getDoc)((0,o.doc)(n.Sr,`sys_configs`,a)),c=(s.exists()?s.data()?.order:null)||[];return c.some(e=>(typeof e==`string`?e:String(e?.id))===t)||await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,a),{order:[...c,{id:t,hidden:!1}]}),t}var Qi=(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},$i=()=>Object.fromEntries(S()),ea=(e,t=!1)=>{let n={};for(let[i,a]of Object.entries($i())){let o=!!a.isPublic;if(o!==e)continue;let s=a.config||{};!t&&s.enabled===!1||(n[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`:r.V(s.pageType),isSystem:!1,enabled:s.enabled!==!1,fromFile:!0})}return n};function ta({value:e,onChange:t,busy:i}){return(0,l.jsx)(`div`,{className:`shrink-0`,onClick:e=>e.stopPropagation(),children:(0,l.jsx)(n.Et,{compact:!0,portal:!0,direction:`auto`,className:`console-select`,ariaLabel:`Who can open this page`,value:e,disabled:i,onChange:e=>t(e),options:r.P.map(e=>({value:e,label:Wi[e]}))})})}var na=`Add it here — a name and what you would like to see on it — then copy the sentence for your assistant.`,ra=`Add it here, then copy the sentence for your assistant.`,ia=[{value:`none`,label:`From scratch`},{value:`board`,label:`Board`},{value:`table`,label:`Table`},{value:`calendar`,label:`Calendar`},{value:`drive`,label:`Files`}],aa=[`board`,`table`,`calendar`,`drive`],oa={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()`}},sa=e=>{let t=oa[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.`:``},ca=e=>r.v(e,1)[0]||``,la=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``),ua=(e,t)=>t?.contentKey||t?.tabName||t?.pageName||t?.pageId||e.title,da=(e,t)=>`src/your-ai-workflow-firebase-os/microcomponents/${la(ua(e,t))||`Page`}Content.tsx`,fa=(e,t)=>{let n=String(t?.route||``).trim();return n?n.startsWith(`/`)?n:`/`+n:e.path||``},pa=(e,t,r=[])=>fa(e,t).replace(/^\/+/,``)?String(t?.brief||``).trim()?$a(t)?`Say what the form should ask for, and this sentence is ready to copy.`:ao(t)||mo(t,r)||n.L(t,n.X()):`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.`,ma=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()}]:[]},ha=e=>Array.isArray(e?.images)?e.images.map(e=>({url:String(e?.url||``),where:String(e?.where||``)})):ma(e),ga=e=>String(e?.imageNotes||``).trim(),_a=e=>{let t=ma(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=ga(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.`]},va=e=>{let t=String(e?.pageWish||``).trim(),n=[];return t&&n.push(`Here is what I would like on the page: ${t}`),n.push(..._a(e)),n},ya=e=>va(e).length>0,ba=`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, CustomSelect } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button, and every dropdown is CustomSelect (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme — so nothing gets a look of its own. The design should be minimal, modern and clean and match the app.`,xa=(e,t,n=[])=>{let r=fa(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=la(ua(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: ${da(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.`,ba,`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.`,Sa];aa.includes(o)&&f.push(sa(o));let p=Na(t);return p?f.push(...Pa(t,l)):s?f.push(...Fa(t,s)):Oa(c)&&f.push(ka(t,l)),f.push(...Ia(t,p)),f.push(...ja(t,l)),f.push(...oo(t)),f.push(..._a(t)),f.push(`Here is what I would like on it: ${c||`___`}`),f.push(...bo(t,n)),f.join(`
|
|
19
|
+
`)},Sa=`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.`,Ca=/^\s*(name|page name|address|web address|route|url|heading|title|form)\s*(?::|\s[-–—]\s)\s*(.*)$/i,wa=/^(no|none|nothing|no form|no,? thanks)\.?$/i,Ta=e=>{let t=e.trim();return t.length>0&&t.length<=40&&!/[.!?:]/.test(t)},Ea=e=>{let t={name:``,address:``,heading:``,formWish:``,brief:``},n=[];for(let r of String(e||``).split(`
|
|
20
|
+
`)){let e=r.match(Ca);if(!e){n.push(r);continue}let i=e[1].toLowerCase(),a=e[2].trim();i===`name`||i===`page name`?t.name=a:i===`heading`||i===`title`?t.heading=a:i===`form`?t.formWish=wa.test(a)?``:a:t.address=a}if(!t.name){let e=n.findIndex(e=>e.trim());e>=0&&Ta(n[e])&&(t.name=n.splice(e,1)[0].trim())}return t.brief=n.join(`
|
|
21
|
+
`).trim(),t},Da=(e,t)=>(e?[`Name: Photos`,`Address: /photos`,`Heading: Our photos`,`What it is for: 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: name, email and what they need — after sending, thank them and say I answer within a day.`,`Pictures: 1 across the top behind the heading, 2 and 3 side by side under it.`,...t?[`Booking: a 30-minute intro call with me; they say what they need first.`]:[],`Links: a Pricing button that opens /pricing.`]:[`Name: Clients`,`Address: /clients`,`Heading: Our clients`,`What it is for: 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.`,`Form: a new client — their name, company and what they need. After sending, add them to the list.`,`Pictures: 1 small, next to the heading.`,...t?[`Booking: every booking as a row — who, with whom, when — soonest first.`]:[],`Links: an Invoices button on every client that opens /invoices.`]).join(`
|
|
22
|
+
`),Oa=e=>/\bforms?\b/i.test(e),ka=(e,t)=>{let n=Qa(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 name a form my app already has, show that one under its own id and do not make another. What it asks is in my words; where it goes and what its button says are yours to decide.`},Aa=e=>/\b(book|books|booking|bookings|appointment|appointments)\b/i.test(e),ja=(e,t)=>{if(!Aa(String(e?.brief||``))||wo(e).schedules.length>0)return[];let r=n.X().filter(n.I);if(!r.length)return[];let i=n.Q(r);if(co(e))return[`If my words below ask for bookings to be shown, this page is where my team follows the times people book with ${i}. ${n.j}`];let a=String(e?.form||``).trim()||Qa(e)||`page`,o=r.length>1;return[`If my words below ask for booking, people book ${n.ct(r)} on this page${o?` — 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. ${n.x}`,`The question goes in the page's form; if the page has none, create one as src/your-ai-workflow-firebase-os/configs/${a}Form.config.ts, the way my app's instructions describe a form, with systemName '${a}' and formType '${t}', asking their name and their email. Add exactly this question to it, copied as it is${o?`, keeping only the schedules my words name`:``}: ${n.at(r.map(e=>e.id))}`,n.b]},Ma=e=>String(e?.formWish||``).trim(),Na=e=>String(e?.form||``)===`__new__`||!!e?.formIsNew||!String(e?.form||``).trim()&&!!Ma(e),Pa=(e,t)=>{let n=String(e?.form||``),r=n!==`__new__`&&n||Qa(e)||`page`,i=Ma(e),a=String(e?.formFields||``).trim(),o=String(e?.formButton||``).trim(),s=String(e?.formSpot||``).trim();if(i)return[`The page needs a form. 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 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}', and show it on the page with <ContactPopup formId='${r}' /> — never build a form out of your own inputs. Where it goes on the page and what its button says are yours to decide.`,`Here is what the form 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},Fa=(e,t)=>{let n=[`Show my form ${Xa(t)} on it with <ContactPopup formId='${t}' /> — never write a form by hand.`],r=Ma(e),i=String(e?.formButton||``).trim(),a=String(e?.formSpot||``).trim();return r&&n.push(`Here is how the form should work on this page: ${r}`),i&&n.push(`The form opens from a button that says ${i} — make that button part of the page's design, not an afterthought.`),a&&n.push(`Where the form belongs on the page: ${a}`),n},Ia=(e,t)=>{let r=co(e),i=n.V(e,n.X(),r);if(!i.length||r)return i;let a=String(e?.form||``).trim();return Na(e)||t?i:a?[`The page's form is '${a}' — add the question to that form where it is defined, keeping its id exactly '${a}'.`,...i]:[...Pa({...e,form:Za,formFields:String(e?.formFields||``).trim()||`their name (text) and their email (email)`},e?.pageType?`private`:`public`),...i]},La=e=>String(e?.pageChange||``).trim()?``:`Say what you would like changed on this page, and this sentence is ready to copy.`,Ra=(e,t)=>{let n=fa(e,t),r=String(t?.tabName||t?.pageName||``).trim(),i=r===`New page`?``:r,a=String(t?.pageChange||``).trim(),o=[`My app already has a page${i?` called ${i}`:``} at ${n}, and the file it shows already exists: ${da(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.`,`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, CustomSelect } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button, and every dropdown is CustomSelect (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme.`,`Keep everything on the page that I have not asked you to change.`],s=sa(String(t?.template||``));return s&&o.push(s),o.push(`Here is what I would like changed: ${a||`___`}`),o.join(`
|
|
23
|
+
`)},za={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.`,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.`,`Keep its named export exactly as it is: export function Home. Making it a default export breaks my site.`,`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, CustomSelect } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button, and every dropdown is CustomSelect (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme.`,`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.`,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.`,`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.`,`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, CustomSelect } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button, and every dropdown is CustomSelect (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme.`,`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.`,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, and do not touch src/App.tsx.`,`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.`,`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, CustomSelect } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button, and every dropdown is CustomSelect (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme.`]},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.`,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.`,`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.`,`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, CustomSelect } from 'your-ai-workflow-firebase-os': section titles are SectionHeading, boxed sections are Card, buttons are Button, and every dropdown is CustomSelect (options as { value, label } pairs; onChange hands back the chosen value itself) — never the browser’s own <select>, which ignores my theme.`,`Keep everything on the page that I have not asked you to change.`]}},Ba=(e,t)=>{let n=za[e];if(!n)return``;let r=va(t);return[...n.lead,...r.length?r:[`Here is what I would like on the page: ___`]].join(`
|
|
24
|
+
`)},Va=(e,t)=>{let n=e=>{let{_uiKey:t,pageType:n,route:r,contentKey:i,...a}=e||{};return a},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},Ha=(e,t)=>{let n=$i(),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},Ua=(e,t)=>{let{_uiKey:n,...r}=e||{};return Object.keys(r).length>0?{...r,pageType:t}:{pageType:t}},Wa=`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`,Ga=`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`,Ka={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`},qa={draft:`bg-foreground/30`,live:`bg-emerald-500 shadow-[0_0_5px] shadow-emerald-500/60`,hidden:`bg-foreground/25`};function Ja({status:e}){return(0,l.jsxs)(`span`,{title:qi[e],className:`inline-flex items-center gap-1.5 text-[11px] font-semibold px-2.5 py-[3px] rounded-full border ${Ka[e]}`,children:[(0,l.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full shrink-0 ${qa[e]}`}),Ki[e]]})}var Ya=e=>{let t=typeof window<`u`?window.location.host:``;return t?`${t}${e}`:e},Xa=e=>e.replace(/[_-]+/g,` `).replace(/^./,e=>e.toUpperCase()),Za=`__new__`,Qa=e=>String(e?.contentKey||``).toLowerCase().replace(/-+/g,`_`),$a=e=>Na(e)&&!Ma(e)&&!String(e?.formFields||``).trim(),eo=[{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}],to=e=>eo.filter(t=>!t.team||ni(e)),no=[{value:`text`,label:`Simple text`},{value:`notification`,label:`Notification`}],ro=e=>e.look===`text`||e.look===`notification`?e.look:eo.find(t=>t.id===e.kind)?.look||`text`,io=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=>eo.some(t=>t.id===e.kind))},ao=e=>{if(!Bi())return``;for(let t of io(e))if(!t.what.trim())return`Say what the email should be about, and this sentence is ready to copy.`;return``},oo=e=>{if(!Bi())return[];let t=co(e),n=[];for(let r of io(e)){let e=r.what.trim();if(!e)continue;let i=ro(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},so=(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=la(ua(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: ${da(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||``);aa.includes(d)&&r.push(sa(d));let f=String(n.form||``).trim(),p=Na(n);return p?(Ma(n)||String(n.formFields||``).trim())&&r.push(...Pa(n,n.pageType?`private`:`public`)):f&&r.push(...Fa(n,f)),r.push(Sa),r.push(...oo(n)),r.push(..._a(n)),r.push(...Ia(n,p)),s()},co=e=>ni(r.V(e?.pageType)),lo=e=>!!String(e?.form||``).trim()||!!e?.formIsNew,uo=e=>`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.`,fo=(e,t)=>e.pageId?ai(e.pageId,t):void 0,po=(e,t)=>e.pageId?fo(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.`,mo=(e,t)=>{for(let n of ii(e)){let e=po(n,t);if(e)return e}return``},ho=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`}}},go={public:0,user:1,internal:2,admin:3},_o=e=>e?.pageType?r.V(e.pageType):`public`,vo=e=>({user:`user_`,internal:`mem_`,admin:`admin_`})[e]||`pub_`,yo=(e,t)=>{let n=_o(e),r=t.audience||`public`;if(go[n]===go[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=go[n]>go[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=vo(i.audience);return[`The two pages are for different people, so they cannot share one collection: a ${ho(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 ${ho(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 bo(e,t){let r=[],i=lo(e);for(let a of ii(e)){let o=fo(a,t),s=a.how.trim();if(!o||!s)continue;let c=o.audience===`admin`,l=ni(o.audience),u=ho(o.audience);r.push(`This page is linked to the ${u.kind} page at ${o.path}, which ${u.who} can open. Build both pages of the link in this one request — this page and the one at ${o.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.`),r.push(`Here is how the two pages are linked: ${s}`),r.push(...yo(e,o));let d=n.Z(o.path,o.config,n.X(),co(e));d&&r.push(d),i&&l&&!c&&r.push(`Entries from the form on this page land in the Inbox collections, which only admins may read. ${uo(o.path)}`),r.push(`For the page at ${o.path}:`),r.push(...so(o))}return r.length&&r.push(`Do not touch any page this request does not name.`),r}var xo=(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&&ii(r[t.id]).some(e=>e.pageId&&i.has(e.pageId))&&o.push(t.title);return o};function So({images:e,notes:t,onChange:i,onNotes:a,onBlur:o}){let s=e.filter(e=>e.url),c=e=>i(s.filter((t,n)=>n!==e));return(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[s.length>0&&(0,l.jsx)(`div`,{className:`flex flex-wrap gap-2.5`,"aria-label":`Your pictures`,children:s.map((e,t)=>(0,l.jsxs)(`div`,{className:`relative w-20 h-20 rounded-xl overflow-hidden border border-[var(--panel-border)] bg-[var(--panel-bg)]`,children:[(0,l.jsx)(`img`,{src:e.url,alt:`Picture ${t+1}`,className:`w-full h-full object-cover`}),(0,l.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:t+1}),(0,l.jsx)(`button`,{type:`button`,"aria-label":`Remove picture ${t+1}`,title:`Remove this picture`,onClick:()=>c(t),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,l.jsx)(n.Pt,{className:`w-3 h-3`})})]},`${e.url}-${t}`))}),(0,l.jsx)(r.h,{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&&i([...s,{url:e,where:``}])},tips:s.length?void 0:r.p}),s.length>0&&(0,l.jsx)(n.m,{label:`How should the pictures be used?`,hint:`Optional — say it by number. Anything you leave out, your assistant decides.`,value:t,onChange:a,onBlur:o,placeholder:`1 across the top behind the heading, 2 and 3 side by side under it`})]})}function Co({emails:e,audience:t,onChange:r,onBlur:i}){let o=to(t),s=o.map(e=>({value:e.id,label:e.label})),[c,u]=(0,a.useState)(!1),d=e.length?c?[...e,{kind:``,what:``}]:e:[{kind:``,what:``}],f=(e,t)=>{u(!1),r(d.map((n,r)=>r===e?{kind:t,what:n.what}:n).filter(e=>!!e.kind),!0)},p=(e,t)=>r(d.map((n,r)=>r===e?{...n,what:t}:n).filter(e=>!!e.kind),!1),m=(e,t)=>r(d.map((n,r)=>r===e?{...n,look:t}:n).filter(e=>!!e.kind),!0),h=!c&&e.length>0&&e.length<o.length;return(0,l.jsx)(n.r,{label:`Emails on this page`,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,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[d.map((e,t)=>{let r=o.find(t=>t.id===e.kind),a=s.filter(t=>t.value===e.kind||!d.some(e=>e.kind===t.value));return(0,l.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5`,children:[(0,l.jsx)(n.d,{label:t===0?`Would you like to add emails to this page?`:`Another email`,value:e.kind,onChange:e=>f(t,e),options:a,placeholder:`No`}),r&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.m,{label:r.ask,hint:r.hint,value:e.what,onChange:e=>p(t,e),onBlur:i,placeholder:r.placeholder}),(0,l.jsx)(n.d,{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:ro(e),onChange:e=>m(t,e),options:no,allowEmpty:!1})]})]},t)}),h&&(0,l.jsx)(`div`,{className:`flex`,children:(0,l.jsx)(n.i,{icon:n.cn,onClick:()=>u(!0),children:`Another email`})})]})})}var wo=e=>{let t=e?.booking&&typeof e.booking==`object`?e.booking:{};return{schedules:n.mt(t),how:String(t.how||``)}};function To({booking:e,audience:t,schedules:r,onChange:i,onHow:a,onBlur:o}){let s=ni(t),c=e.schedules.length>0;return(0,l.jsx)(n.r,{label:`Booking on this page`,hint:s?`Pick whose bookings your team follows here — every booking, who, when. Schedules are made on the Schedule screen.`:`Pick what can be booked on this page — a schedule from the Schedule screen, one per person. Its length, hours and price come with it.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,l.jsx)(Li,{schedules:r,selected:e.schedules,onPick:t=>i({...e,schedules:n.tt(e.schedules,t,r)})}),c&&(0,l.jsx)(n.m,{label:`How should booking work here?`,hint:s?`What your team sees here — every booking, who, when.`:`The length and the price are set by the schedule — say the rest: who this is for, what the visitor reads first, what they should tell you before they pick a time, and what happens after. Your assistant shapes the picker from this — a whole calendar when the page is about booking, one compact question when it is not.`,value:e.how,onChange:a,onBlur:o,placeholder:s?`Every booking as a row — who, with whom, when — soonest first.`:`For new clients. Explain what the session covers, ask what they need help with before they pick a time, and say I will confirm by email.`})]})})}var Eo=`__new_linked_page__`,Do=[{value:`public`,label:`Anyone`},{value:`user`,label:`Signed-in people`},{value:`internal`,label:`Your team`},{value:`admin`,label:`Admins only`}],Oo=e=>Ji(e.address)||Ji(e.name),ko=(e,t,n)=>{let r=Oo(e);return!(!e.name.trim()||!r||n(r)||!t.trim()||e.form===`__new__`&&!e.formFields.trim())},Ao=(e,t=``)=>{let n=Do.some(t=>t.value===e.type)?e.type:`internal`;return{name:e.name.trim(),address:Oo(e),type:n,about:e.about.trim()||t.trim(),iconName:e.iconName||(n===`public`?``:ca(e.name)),template:e.template,form:e.form,formFields:e.formFields.trim(),formButton:e.formButton.trim(),formSpot:e.formSpot.trim()}};function jo({draft:e,taken:t,onEdit:r,onSave:i,onBlur:o}){let[s,c]=(0,a.useState)(``),u=Oo(e),d=()=>e.name.trim()?!u||t(u)?(c(u?`Another page already lives at /${u}. Pick a different name.`:`Use a name with a letter or a number in it.`),!1):(c(``),!0):(c(`Give the new page a name, for example Bookings`),!1);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h,{label:`Name of the new page`,hint:u?`It will live at /${u} — its address, heading and icon can be changed in its settings later.`:`What it is called in the menu.`,value:e.name,onChange:e=>{r({name:e}),s&&c(``)},onBlur:()=>{d(),o()},error:s,placeholder:`Bookings`}),(0,l.jsx)(n.d,{label:`Who can open it`,hint:`Anyone is your public website. Your team is everyone you have marked internal, plus admins.`,value:e.type,onChange:e=>i({type:e}),options:Do,allowEmpty:!1})]})}function Mo({link:e,links:t,index:r,targets:i,self:o,onPatch:s,onBlur:c,onRemove:u,taken:d,onCreatePage:f}){let[p,m]=(0,a.useState)(!1),[h,g]=(0,a.useState)(``),_=fo(e,i),v=i.filter(e=>!oi(o.id,e)&&!(o.contentKey&&oi(o.contentKey,e))&&(e.id===_?.id||!t.some((t,n)=>n!==r&&fo(t,i)?.id===e.id))),y=e.pageId?_?.id||e.pageId:e.draft?Eo:``,b=e=>{s(e===`__new_linked_page__`?{pageId:``,draft:ri()}:{pageId:e,draft:void 0},!0)},x=async()=>{if(e.draft){m(!0),g(``);try{s({pageId:await f(Ao(e.draft,e.how)),draft:void 0},!0)}catch(e){console.error(`Failed to create the linked page:`,e),g(`The page could not be created. Check its web address and try again.`)}m(!1)}},S=!!e.draft&&ko(e.draft,e.how,d);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-4`,children:[(0,l.jsx)(n.d,{label:`Which page is it linked to?`,hint:y?void 0:`One of your pages — or a new one, made right here with its own settings.`,value:y,onChange:b,options:[{value:Eo,label:`+ A new page, made right here`},...v.map(e=>({value:e.id,label:`${e.title} — ${e.path}`}))],placeholder:`Pick a page`}),!!e.pageId&&!_&&(0,l.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,l.jsx)(jo,{draft:e.draft,taken:d,onEdit:t=>s({draft:{...e.draft,...t}},!1),onSave:t=>s({draft:{...e.draft,...t}},!0),onBlur:c}),(!!_||!!e.draft)&&(0,l.jsx)(n.m,{label:e.draft?`What is the new page, and how are the two linked?`:`How will the pages be linked?`,hint:e.draft?`In your own words — what the new page shows, and what made here should show up there. Your assistant decides the rest.`:`In your own words — what made here should show up there. It goes into the sentence below.`,value:e.how,onChange:e=>s({how:e},!1),onBlur:c,placeholder:e.draft?`A page for my team with every booking made here — who, when, what for — newest first.`:`Every booking made on this page appears there, newest first.`}),!!h&&(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500`,children:h}),(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 pt-1`,children:[e.draft?(0,l.jsx)(n.i,{icon:n.cn,busy:p,disabled:!S,onClick:x,children:`Create and link it`}):(0,l.jsx)(`span`,{}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Unlink`,onClick:u,children:`Unlink`})]})]})}function No({links:e,targets:t,self:r,onChange:i,onBlur:a,taken:o,onCreatePage:s}){let c=(t,n,r)=>i(e.map((e,r)=>{if(r!==t)return e;let i={...e,...n};return i.draft||delete i.draft,i}),r),u=t=>i(e.filter((e,n)=>n!==t),!0),d=()=>i([...e,{pageId:``,how:``}],!0),f=e.every(e=>!!fo(e,t));return e.length?(0,l.jsx)(n.r,{label:`Linked pages`,hint:`Another of your pages that shows what happens here, usually one only your team can open — and how the two connect. It rides the sentence below, so one copy builds both.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.map((n,i)=>(0,l.jsx)(Mo,{link:n,links:e,index:i,targets:t,self:r,onPatch:(e,t)=>c(i,e,t),onBlur:a,onRemove:()=>u(i),taken:o,onCreatePage:s},i)),f&&(0,l.jsx)(`div`,{className:`flex`,children:(0,l.jsx)(n.i,{icon:n.cn,onClick:d,children:`Link another page`})})]})}):(0,l.jsx)(`div`,{className:`flex`,children:(0,l.jsx)(n.i,{icon:n.cn,onClick:d,title:`Another of your pages that shows what happens here — usually one only your team can open`,children:`Link a page`})})}function Po({page:e,config:t,forms:i,saving:o,onSave:s,addressTaken:c,actions:u,footer:d,isNew:f,quick:p,editing:m,linkTargets:h,onCreateLinkedPage:g,emailOn:_}){let v=e.type===`public`,y=v?`pageName`:`tabName`,b=v?`pageTitle`:`tabTitle`,[x,S]=(0,a.useState)(()=>({...t||{}})),[C,w]=(0,a.useState)(``),[T,E]=(0,a.useState)(``),D=(e,t)=>S(n=>({...n,[e]:t})),O=e=>{S(t=>({...t,...e}));let n={...t||{},...x,...e};delete n._uiKey,s(n)},k=e=>{(t||{})[e]!==x[e]&&O({[e]:x[e]})},A=String(x.route??``).replace(/^\/+/,``),j=()=>{let n=Ji(A);if(!n){w(`Give this page a web address, for example pricing`);return}if(c(e.id,n)){w(`Another page already lives at this address. Pick a different one.`);return}w(``),n===String(t?.route??``).replace(/^\/+/,``)?D(`route`,`/`+n):O({route:`/`+n})},M=String(x.pageWords??``),N=Ea(M),P=Ji(N.address)||Ji(A)||Ji(N.name),F=()=>{if(!N.name){E(M.trim()?`Start with the page’s name on a line of its own — Name: Photos`:`Give the page a name — Name: Photos`);return}if(!P){E(`Use a name or an address with a letter or a number in it.`);return}let n=Ji(A);if(P!==n&&c(e.id,P)){E(`Another page already lives at /${P}. Pick a different name or address.`);return}E(``);let r={pageWords:M,[y]:N.name,brief:N.brief,formWish:N.formWish},i=String(x[b]??``).trim();N.heading?r[b]=N.heading:(!i||i===String(t?.[y]??``).trim())&&(r[b]=N.name),!v&&!String(x.iconName??``).trim()&&(r.iconName=ca(N.name)),P!==n&&(r.route=`/`+P),Object.keys(r).some(e=>(t||{})[e]!==r[e])?O(r):S(e=>({...e,...r}))},I=p?P:Ji(A),L={...t||{},...x,...p?{[y]:N.name,brief:N.brief,formWish:N.formWish,...N.heading?{[b]:N.heading}:{}}:{},route:I?`/`+I:``,contentKey:t?.contentKey||I||void 0},R=String(x.form??``),z=Na(x),B=(0,l.jsx)(So,{images:ha(x),notes:String(x.imageNotes??``),onChange:e=>O({images:e}),onNotes:e=>D(`imageNotes`,e),onBlur:()=>k(`imageNotes`)}),V=n.X().length>0&&(0,l.jsx)(To,{booking:wo(x),audience:e.type,schedules:n.X(),onChange:e=>O({booking:e}),onHow:e=>D(`booking`,{...wo(x),how:e}),onBlur:()=>k(`booking`)}),H=!!h&&!!g&&(e.type===`public`||e.type===`user`)&&(0,l.jsx)(No,{links:ii(x),targets:h,self:{id:e.id,contentKey:String(t?.contentKey||I||``)},taken:e=>c(`__new_linked_page__`,e),onCreatePage:g,onChange:(e,t)=>t?O({links:e}):D(`links`,e),onBlur:()=>k(`links`)}),U=(0,l.jsxs)(l.Fragment,{children:[d?.(L),(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 pt-2 border-t border-[var(--panel-border)]/60`,children:[(0,l.jsx)(n.l,{saving:o}),(0,l.jsx)(`div`,{className:`flex flex-wrap items-center gap-2 ml-auto`,children:u})]})]});if(m)return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-5`,children:[(0,l.jsx)(n.m,{label:`Describe what you would like to change`,hint:`In your own words. Anything you do not mention stays as it is.`,value:x.pageChange??``,onChange:e=>D(`pageChange`,e),onBlur:()=>k(`pageChange`),placeholder:`Show the albums three to a row, put a search box above them, and take the prices off.`}),U]});if(p){let e=Da(v,n.X().length>0);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-5`,children:[(0,l.jsx)(n.m,{label:`Describe the page`,hint:f?`One box for everything, a line each — its name first. The page is created as soon as you leave the box${P?` — it will live at /${P}`:``}. Whatever you skip, your assistant decides.`:`One box for everything, a line each — its name first${P?`; it lives at /${P}`:``}. Whatever you skip, your assistant decides. Open the row again for every setting.`,value:M,onChange:e=>{D(`pageWords`,e),T&&E(``)},onBlur:F,error:T,placeholder:e,rows:e.split(`
|
|
25
|
+
`).length}),B,U]})}return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-5`,children:[(0,l.jsx)(n.h,{label:`Web address`,hint:`Where this page lives, e.g. /photos`,prefix:`/`,value:A,onChange:e=>{D(`route`,e),C&&w(``)},onBlur:j,error:C,placeholder:`photos`}),(0,l.jsx)(n.h,{label:v?`Name in the menu`:`Name in the dashboard`,hint:v?`What visitors see in the site menu.`:`What people see in the dashboard menu.`,value:x[y]??``,onChange:e=>D(y,e),onBlur:()=>k(y),placeholder:`Photos`}),(0,l.jsx)(n.h,{label:`Page heading`,hint:`The big heading people read at the top of the page.`,value:x[b]??``,onChange:e=>D(b,e),onBlur:()=>k(b),placeholder:`Our photos`}),!v&&(0,l.jsx)(r._,{label:`Icon`,hint:`Shown next to the name in the dashboard menu.`,value:x.iconName??``,onChange:e=>O({iconName:e})}),!v&&(0,l.jsx)(n.d,{label:`Starting layout`,hint:`What the page starts as. Your assistant fills in the rest when you ask.`,value:ia.some(e=>e.value===x.template)?x.template:`none`,onChange:e=>O({template:e}),options:ia,allowEmpty:!1}),(0,l.jsx)(n.d,{label:`Form`,hint:`Answers arrive in your Inbox. Your assistant builds it with the page.`,value:z?Za:R,onChange:e=>O(e===`__new__`?{form:Za}:{form:e,formIsNew:!1}),options:[{value:Za,label:`A new form made for this page`},...i.map(e=>({value:e,label:Xa(e)}))],placeholder:`No form`}),(z||!!R)&&(0,l.jsx)(n.m,{label:z?`What should the form ask, and what happens after?`:`How should the form work on this page?`,hint:z?`The questions in your own words, and what the person sees once they have sent it. Where it goes and what its button says, your assistant decides.`:`Optional — where it belongs on the page and what happens after, in your own words.`,value:x.formWish??``,onChange:e=>D(`formWish`,e),onBlur:()=>k(`formWish`),placeholder:`Name, email and what they need. After sending, thank them and say I answer within a day.`}),(0,l.jsx)(n.m,{label:`What would you like to see on this page?`,hint:`What your assistant builds — it goes into the sentence below.`,value:x.brief??``,onChange:e=>D(`brief`,e),onBlur:()=>k(`brief`),placeholder:`A photo gallery where I can upload pictures, put them in albums and open one full screen.`}),B,V,_&&(0,l.jsx)(Co,{emails:io(x),audience:e.type,onChange:(e,t)=>t?O({emails:e}):D(`emails`,e),onBlur:()=>k(`emails`)}),H,U]})}function Fo({page:e,answers:t,saving:i,resetting:o,onSave:s,onReset:c,onCopied:u}){let[d,f]=(0,a.useState)(()=>({...t||{}})),p=(e,t)=>f(n=>({...n,[e]:t})),m=e=>{(t||{})[e]!==d[e]&&s({[e]:d[e]})},h={...t||{},...d},g=za[e.id],_=!ya(h);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 sm:gap-5`,children:[(0,l.jsx)(n.m,{label:g.ask,hint:`In your own words. Everything you do not mention stays as it is.`,value:d.pageWish??``,onChange:e=>p(`pageWish`,e),onBlur:()=>m(`pageWish`),placeholder:g.example}),e.type===`public`&&(0,l.jsx)(So,{images:ha(d),notes:String(d.imageNotes??``),onChange:e=>{p(`images`,e),s({images:e})},onNotes:e=>p(`imageNotes`,e),onBlur:()=>m(`imageNotes`)}),(0,l.jsx)(r.g,{compact:!0,title:g.title,prompt:Ba(e.id,h),locked:_,onCopied:u}),(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3 pt-1`,children:[(0,l.jsx)(`div`,{children:ya(h)&&c&&(0,l.jsx)(n.i,{icon:n.rn,tone:`danger`,compact:!0,title:`Start again`,busy:o,onClick:c,children:`Reset`})}),(0,l.jsx)(n.l,{saving:i})]})]})}function Io(){let{userRole:e}=r.j(),i=(0,u.useLocation)(),[s,c]=(0,a.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_pages`);if(e)return Ui(JSON.parse(e))}}catch{}return Vi}),[d,f]=(0,a.useState)(()=>{try{return sessionStorage.getItem(`fbos_pages_expandedId`)||null}catch{return null}}),p=(0,a.useRef)(d),[m,h]=(0,a.useState)(null),g=e=>{let t=typeof window<`u`?window.location.origin:``;navigator.clipboard?.writeText(`${t}${e.path}`),h(e.id),setTimeout(()=>h(null),2e3)},[_,v]=(0,a.useState)(null),[y,b]=(0,a.useState)(null),[x,S]=(0,a.useState)(!1),[C,w]=(0,a.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_page_configs`);if(e)return JSON.parse(e)}}catch{}return{}}),[T,E]=(0,a.useState)({}),[D,O]=(0,a.useState)(()=>{try{let e=localStorage.getItem(`fbos_swr_page_briefs`);if(e)return JSON.parse(e)}catch{}return{}}),k=(0,a.useRef)(D);(0,a.useEffect)(()=>{k.current=D},[D]),(0,a.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(n.Sr,`sys_configs`,`page_briefs`),e=>{let t=e.exists()?e.data():{};O(t);try{localStorage.setItem(`fbos_swr_page_briefs`,JSON.stringify(t))}catch{}},()=>{}),[]),t.c();let[A,j]=(0,a.useState)(!1);(0,a.useEffect)(()=>{let e=!1;return Fi().then(t=>{e||(zi(t.configured),j(t.configured))}),()=>{e=!0}},[]);let M=async(e,t)=>{let r={...k.current[e]||{},...t};O(t=>({...t,[e]:r})),E(t=>({...t,[e]:!0}));try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,`page_briefs`),{[e]:r},{merge:!0})}catch(e){console.error(`Could not save the page answers`,e)}E(t=>({...t,[e]:!1}))},[N,P]=(0,a.useState)({}),[F,I]=(0,a.useState)({}),[L,R]=(0,a.useState)(null),[z,B]=(0,a.useState)(null),[V,H]=(0,a.useState)(!1),U=(0,a.useRef)(null);(0,a.useEffect)(()=>{function e(e){U.current&&!U.current.contains(e.target)&&S(!1)}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let[ee,W]=(0,a.useState)(new Set),[G,K]=(0,a.useState)(new Set),[q,J]=(0,a.useState)([]),[Y,X]=(0,a.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,a.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.doc)(n.Sr,`sys_configs`,`page_order`),e=>{let t=te(e.exists()&&e.data().order||[]);J(t),W(new Set(t.filter(e=>e.hidden).map(e=>e.id)))}),t=(0,o.onSnapshot)((0,o.doc)(n.Sr,`sys_configs`,`tab_order`),e=>{let t=te(e.exists()&&e.data().order||[]);X(t),K(new Set(t.filter(e=>e.hidden).map(e=>e.id)))});return()=>{e(),t()}},[]),(0,a.useEffect)(()=>{let e=i.pathname.split(`/pages/`)[1]?.split(`/`)[0];e&&!d&&s.some(t=>t.id===e)&&f(e)},[i.pathname,s]),(0,a.useEffect)(()=>{p.current=d;try{d?sessionStorage.setItem(`fbos_pages_expandedId`,d):sessionStorage.removeItem(`fbos_pages_expandedId`)}catch{}},[d]);let ne=(0,a.useRef)(null);(0,a.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,a.useEffect)(()=>{(async()=>{try{let[e,t]=await Promise.all([(0,o.getDocs)((0,o.collection)(n.Sr,`sys_pages`)),(0,o.getDocs)((0,o.collection)(n.Sr,`sys_tabs`))]),i=[`home`,`drive`,`assets`,`contact`,`guide`,`templates`,`setup`,`support`,`theme`,`page_order`,`tab_order`],a=[],s={};e.forEach(e=>{if(!i.includes(e.id)){let t=e.data();a.push({id:e.id,title:t.pageName||t.title||e.id,path:t.route||`/`+e.id,type:`public`,isSystem:!1,enabled:t.enabled!==!1}),s[e.id]=t}}),t.forEach(e=>{if(!i.includes(e.id)){let t=e.data(),n=r.V(t.pageType);a.push({id:e.id,title:t.tabName||t.title||e.id,path:t.route||`/`+e.id,type:n,isSystem:!1,enabled:t.enabled!==!1}),s[e.id]=t}});let l=$i(),u={...ea(!0,!0),...ea(!1,!0)};for(let[e,t]of Object.entries(u)){if(s[e])continue;let n=a.find(e=>e.path===t.path);if(n){n.fromFile=!0;continue}a.push(t),s[e]=l[e]?.config||{}}c(e=>{let t=Ui(e.filter(e=>(e.isSystem||e.id.startsWith(`draft_`))&&e.id!==`drive`)),n=a.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}),w(e=>{let t={...e,...s};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,ie]=(0,a.useState)([`contact`]),[ae,Z]=(0,a.useState)([`support`]);(0,a.useEffect)(()=>{let e=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},r={...t._,...e},i=new Set([`contact`]),a=new Set([`support`]);Object.entries(r).forEach(([e,t])=>{t.formType===`private`?a.add(t.systemName||e):i.add(t.systemName||e)}),(0,o.getDocs)((0,o.collection)(n.Sr,`sys_forms`)).then(e=>{e.docs.forEach(e=>{e.data().formType===`private`?a.add(e.id):i.add(e.id)}),ie(Array.from(i)),Z(Array.from(a))}).catch(e=>{console.warn(`Failed fetching sys_forms in PagesAdmin:`,e),ie(Array.from(i)),Z(Array.from(a))})},[]);let oe=async(e,t,r)=>{if(t.route&&!t.route.startsWith(`/`)&&(t.route=`/`+t.route),!String(t.route||``).replace(/^\/+/,``).trim()){w(n=>({...n,[e]:t}));return}let i=s.find(t=>t.id===e),a=r||i?.type||t.pageType||(e.startsWith(`pub_`)?`public`:void 0),l=a===`public`?`sys_pages`:`sys_tabs`;a&&a!==`public`?t.pageType=a:delete t.pageType;let u=Object.fromEntries(Object.entries(t).filter(([e,t])=>t!==void 0)),d=t.route?Yi(t.route):e;u.contentKey||=d,t={...t,contentKey:u.contentKey},u.form===`__new__`&&(u.form=Qa(u),u.formIsNew=!0,t={...t,form:u.form,formIsNew:!0}),E(t=>({...t,[e]:!0,[d]:!0}));try{if(d!==e&&d.trim()!==``&&d!==`draft`){try{let{deleteDoc:t}=await import(`firebase/firestore`);await t((0,o.doc)(n.Sr,l,e))}catch{}await(0,o.setDoc)((0,o.doc)(n.Sr,l,d),u),c(n=>n.map(n=>n.id===e?{...n,id:d,_uiKey:n._uiKey||e,path:t.route,title:t.pageName||t.tabName||t.title||n.title}:n)),p.current===e&&(f(d),window.history.replaceState(null,``,`/pages/${d}`)),b(t=>t===e?d:t),w(n=>{let r={...n};return r[d]=t,delete r[e],r});let r=a===`public`,i=r?`page_order`:`tab_order`,s=r?q:Y;if(!s.some(e=>e.id===d)){let t=[...s.filter(t=>t.id!==e),{id:d,hidden:!1}];try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,i),{order:t})}catch(e){console.error(`Failed to update tab order:`,e)}}}else await(0,o.setDoc)((0,o.doc)(n.Sr,l,e),u),w(n=>({...n,[e]:t})),c(n=>n.map(n=>n.id===e?{...n,path:t.route||n.path,title:t.pageName||t.tabName||t.title||n.title}:n))}catch(t){console.error(`Failed to save ${e} config:`,t)}finally{setTimeout(()=>{E(t=>({...t,[e]:!1,[d]:!1}))},500)}},Q=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};c(e=>[...e,n]),w(e=>({...e,[t]:r})),f(t),b(t),S(!1),setTimeout(()=>{document.getElementById(`page-${t}`)?.scrollIntoView?.({behavior:`smooth`,block:`center`})},100)},ce=e=>e.id.startsWith(`draft_`);if(e!==`admin`)return(0,l.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,l.jsx)(Sr,{})});let le=async(e,t,r)=>{let i=r===`public`,a=i?`page_order`:`tab_order`,l=i?q:Y,u=(i?ee:G).has(e);c(s.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)(n.Sr,`sys_configs`,a),{order:d})},ue=e=>!!e.fromFile&&(e.type===`public`?q:Y).some(t=>t.id===e.id&&t.removed),de=async(e,t)=>{if(e.type===t)return;let r=e.type;c(n=>n.map(n=>n.id===e.id?{...n,type:t}:n)),E(t=>({...t,[e.id]:!0}));let i=Ua(C[e.id],t);try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_tabs`,e.id),i,{merge:!0}),w(n=>n[e.id]?{...n,[e.id]:{...n[e.id],pageType:t}}:n)}catch(t){console.error(`Failed to change the audience of ${e.id}:`,t),c(t=>t.map(t=>t.id===e.id?{...t,type:r}:t))}finally{E(t=>({...t,[e.id]:!1}))}},fe=(e,t)=>{if(!t){if(ce({id:e})){c(t=>t.filter(t=>t.id!==e)),w(t=>{let n={...t};return delete n[e],n}),d===e&&f(null),b(t=>t===e?null:t);return}R(e)}},pe=async()=>{if(L){H(!0);try{let{deleteDoc:e,collection:t,getDocs:r,doc:i,getDoc:a,query:o,where:l}=await import(`firebase/firestore`),{ref:u,deleteObject:p}=await import(`firebase/storage`),m=s.find(e=>e.id===L),h=m?.type===`public`?`sys_pages`:`sys_tabs`;if(h===`sys_tabs`&&m){let s=C[L];if(!s)try{let e=await a(i(n.Sr,`sys_tabs`,L));e.exists()&&(s=e.data())}catch{}let c=(s?.tabName||s?.pageId||L).toLowerCase().replace(/[^a-z0-9]+/g,`_`),d=[`admin_${c}_records`,`mem_${c}_records`,`user_${c}_records`],f={[`admin_${c}_records`]:{prefix:`admin_files`,driveCollection:`admin_files`},[`mem_${c}_records`]:{prefix:`mem_files`,driveCollection:`mem_files`},[`user_${c}_records`]:{prefix:`user_files`,driveCollection:`user_files`}},m=[];for(let i of d)m.push((async()=>{try{let a=await r(t(n.Sr,i)),s=f[i],c=[];for(let i of a.docs){let a=i.data();a.recordType===`file`&&a.downloadURL&&s&&c.push((async()=>{try{let i=`${s.prefix}%2F`,c=a.downloadURL.split(i)[1]?.split(`?`)[0];c&&await p(u(n.wr,`${s.prefix}/${decodeURIComponent(c)}`)).catch(()=>{});let d=await r(o(t(n.Sr,s.driveCollection),l(`downloadURL`,`==`,a.downloadURL)));await Promise.all(d.docs.map(t=>e(t.ref)))}catch(e){console.error(`Error deleting storage file:`,e)}})())}await Promise.all(c),await Promise.all(a.docs.map(t=>e(t.ref)));try{localStorage.removeItem(`fbos_records_${i}`)}catch{}}catch(e){console.error(`Error cleaning up collection ${i}:`,e)}})());for(let i of[`admin_files`,`mem_files`,`user_files`])m.push((async()=>{try{let a=await r(o(t(n.Sr,i),l(`sourceTab`,`==`,c)));await Promise.all(a.docs.map(async t=>{let r=t.data();if(r.downloadURL)try{let e=`${i}%2F`,t=r.downloadURL.split(e)[1]?.split(`?`)[0];t&&await p(u(n.wr,`${i}/${decodeURIComponent(t)}`)).catch(()=>{})}catch{}await e(t.ref)}))}catch{}})());await Promise.all(m)}await e(i(n.Sr,h,L));let g=h===`sys_pages`?`page_order`:`tab_order`,_=h===`sys_pages`?q:Y,{setDoc:v}=await import(`firebase/firestore`),y=m?.fromFile?[..._.filter(e=>e.id!==L),{id:L,hidden:!0,removed:!0}]:_.filter(e=>e.id!==L);await v(i(n.Sr,`sys_configs`,g),{order:y}),c(e=>e.filter(e=>e.id!==L)),d===L&&f(null)}catch(e){console.error(`Error deleting page:`,e)}H(!1),R(null)}},he=async(e,t)=>{if(e.isSystem)return;let r=e.type===`public`,i=r?`page_order`:`tab_order`,a=[...r?q:Y];s.filter(e=>e.type===`public`===r&&!e.isSystem&&!a.some(t=>t.id===e.id)).forEach(e=>a.push({id:e.id,hidden:!1}));let c=Qi(a,e.id,t,r?`home`:void 0);if(c){r?J(c):X(c);try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,i),{order:c})}catch(e){console.error(`Failed to reorder pages:`,e)}}},ge=(e,t)=>{let n=t.replace(/[^a-zA-Z0-9_-]/g,`_`).toLowerCase();return s.some(r=>{if(r.id===e)return!1;let i=String(C[r.id]?.route??r.path??``).replace(/^\/+/,``).toLowerCase();return i!==``&&i===t||r.id===n})},_e=e=>e===`admin`?Dr:e===`internal`?Or:e===`public`?Tr:Er,ve=async()=>{let e=s.find(e=>e.id===z);if(!e){B(null);return}I(t=>({...t,[e.id]:!0}));let t=C[e.id]||{};if(e.isSystem){try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_configs`,`page_briefs`),{[e.id]:(0,o.deleteField)()},{merge:!0}),O(t=>{let n={...t};return delete n[e.id],n}),P(t=>({...t,[e.id]:(t[e.id]||0)+1}))}catch(e){console.error(`Failed to clear the page answers`,e)}I(t=>({...t,[e.id]:!1})),B(null);return}let r=Ha(e,t);if(r)try{await(0,o.deleteDoc)((0,o.doc)(n.Sr,e.type===`public`?`sys_pages`:`sys_tabs`,e.id)),w(t=>({...t,[e.id]:r})),c(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 oe(e.id,{..._e(e.type),...t.contentKey?{contentKey:t.contentKey}:{}});I(t=>({...t,[e.id]:!1})),B(null)},ye=s.filter(e=>!e.isSystem&&!ce(e)&&!ue(e)).map(e=>({id:e.id,title:e.title,path:e.path,brief:String(C[e.id]?.brief||``),config:C[e.id],audience:e.type})),be=async e=>{let{id:t,config:n,isPublic:r}=Xi(e);return await Zi(e),c(r=>r.some(e=>e.id===t)?r:[...r,{id:t,title:e.name,path:n.route,type:e.type,isSystem:!1,enabled:!0}]),w(e=>({...e,[t]:n})),(r?J:X)(e=>e.some(e=>e.id===t)?e:[...e,{id:t,hidden:!1}]),t},xe=[{id:`public`,title:`Anyone`,icon:n.Mn,description:`On your website and in the site menu — open to everyone, signed in or not.`,filter:e=>e.type===`public`},{id:`user`,title:`Signed-in users`,icon:n.vn,description:`In the dashboard for every signed-in person — each sees only their own.`,filter:e=>e.type===`user`},{id:`internal`,title:`Your team`,icon:n.In,description:`In the dashboard for admins and your team — invisible to everyone else.`,filter:e=>e.type===`internal`},{id:`admin`,title:`Admins only`,icon:n.Qt,description:`In the dashboard, for admins alone.`,filter:e=>e.type===`admin`}];return(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:`Your Pages`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/pages`]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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,l.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,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(`div`,{className:`flex items-center min-h-[40px]`,children:(0,l.jsx)(`h2`,{className:`text-lg md:text-xl font-extrabold text-foreground tracking-tight leading-tight truncate`,children:`Your pages`})}),(0,l.jsxs)(`p`,{className:`text-[12.5px] md:text-[14px] font-medium text-foreground/60 leading-relaxed max-w-3xl`,children:[(0,l.jsx)(`span`,{className:`md:hidden`,children:`Add a page, say what goes on it, paste the sentence into your assistant.`}),(0,l.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,l.jsx)(`div`,{className:`relative z-50 shrink-0 flex items-center gap-1`,children:(0,l.jsxs)(`div`,{className:`relative`,children:[(0,l.jsx)(t.h,{variant:`secondary`,onClick:()=>S(!x),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,l.jsx)(n.cn,{className:`w-4 h-4 text-foreground/60 group-hover:text-foreground transition-colors`})}),(0,l.jsx)(n.At,{children:x&&(0,l.jsxs)(n.kt.div,{ref:U,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,l.jsx)(`span`,{className:`px-3 pt-1 pb-2 text-[10px] font-bold uppercase tracking-widest text-foreground/40`,children:`Add a page for`}),[`public`,`user`,`internal`,`admin`].map(e=>(0,l.jsx)(`button`,{onClick:()=>Q(e),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:Wi[e]},e))]})})]})})]}),(0,l.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:xe.map((e,t)=>{let i=s.filter(e.filter).filter(e=>!ue(e)),a=e.id===`public`?q:Y,o=i.sort((e,t)=>{if(e.id===`home`)return-1;if(t.id===`home`)return 1;let n=a.findIndex(t=>t.id===e.id),r=a.findIndex(e=>e.id===t.id);return n===-1&&r===-1?0:n===-1?1:r===-1?-1:n-r}),c=e.icon,p=e=>e.type===`public`?ee.has(e.id):G.has(e.id),h=o.filter(e=>!p(e)),x=o.filter(e=>p(e)),S=(t,i)=>{let a=t.isSystem?za[t.id]:void 0,o=d===t.id,c=ce(t),p=Gi({draft:c,hidden:i}),h=!t.isSystem||!!a,x=!t.isSystem&&!c,S=o&&_===t.id,w=t.isSystem?[]:xo(t,C[t.id],s,C),E=e=>{f(t.id),v(e===`edit`?t.id:null),window.history.replaceState(null,``,`/pages/${t.id}`)},O=()=>{f(null),v(null),b(null),window.history.replaceState(null,``,`/pages`)};return(0,l.jsxs)(`div`,{id:`page-${t.id}`,onClick:()=>{h&&(o?O():E(`settings`))},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`:``} ${i?`opacity-60 bg-foreground/[0.01] border-[var(--panel-border)]/50`:`border-transparent hover:border-[var(--panel-border)]`}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between w-full gap-2 sm:gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2 flex-1 min-w-0`,children:[!t.isSystem&&!c&&(0,l.jsxs)(`div`,{className:`max-sm:hidden sm:flex flex-col shrink-0`,onClick:e=>e.stopPropagation(),children:[(0,l.jsx)(`button`,{type:`button`,title:`Move up`,"aria-label":`Move ${t.title} up`,onClick:()=>he(t,`up`),className:Wa,children:(0,l.jsx)(n.Qn,{className:`w-3.5 h-3.5`})}),(0,l.jsx)(`button`,{type:`button`,title:`Move down`,"aria-label":`Move ${t.title} down`,onClick:()=>he(t,`down`),className:Wa,children:(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5`})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,l.jsx)(`h3`,{className:`text-[14.5px] font-bold text-foreground tracking-tight truncate`,children:t.title}),!t.isSystem&&(0,l.jsx)(Ja,{status:p}),t.fromFile&&(0,l.jsxs)(`span`,{className:Ga,title:`Your assistant wrote this one as a file. Delete hides it and gives you the sentence that removes its files.`,children:[(0,l.jsx)(n.Fn,{className:`w-3 h-3`}),` Written as a file`]}),w.length>0&&(0,l.jsxs)(`span`,{className:Ga,title:`This page shows what happens on ${w.join(`, `)}.`,children:[(0,l.jsx)(n.Sn,{className:`w-3 h-3`}),` Linked to `,w.join(`, `)]})]}),c&&(0,l.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 truncate`,children:`Not saved yet — give it a name`})]})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1 sm:gap-2 shrink-0`,children:[!t.isSystem&&t.type!==`public`&&!c&&(0,l.jsx)(`div`,{className:`max-sm:hidden`,children:(0,l.jsx)(ta,{value:t.type,busy:T[t.id],onChange:e=>de(t,e)})}),x&&(0,l.jsx)(n.i,{icon:n.It,compact:!0,title:`Edit this page with your assistant`,className:S?`text-accent border-accent/40 bg-accent/10 max-sm:border-transparent max-sm:bg-accent/10`:``,onClick:e=>{e.stopPropagation(),E(S?`settings`:`edit`)},children:`Edit with AI`}),!Hi.has(t.id)&&!c&&(0,l.jsx)(n.i,{icon:i?n.In:n.Ln,compact:!0,title:i?`Show this page`:`Hide this page`,onClick:e=>{e.stopPropagation(),le(t.id,t.isSystem,t.type)},children:i?`Show`:`Hide`}),h?(0,l.jsx)(`div`,{className:`p-1.5 transition-transform duration-300 text-foreground/40 shrink-0 ${o?`rotate-180`:``}`,children:(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5`})}):(0,l.jsx)(`div`,{className:`w-[24px] shrink-0`})]})]}),t.path&&o&&(0,l.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 mt-1.5`,onClick:e=>e.stopPropagation(),children:[(0,l.jsx)(u.Link,{to:t.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:Ya(t.path)}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>g(t),title:`Copy this link`,"aria-label":`Copy the link to ${t.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:m===t.id?(0,l.jsx)(n.nr,{className:`w-3.5 h-3.5 text-accent`}):(0,l.jsx)(n.Un,{className:`w-3.5 h-3.5`})})]}),(0,l.jsxs)(n.At,{children:[o&&a&&(0,l.jsx)(n.kt.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,l.jsx)(Fo,{page:t,answers:D[t.id],saving:T[t.id],resetting:F[t.id],onSave:e=>M(t.id,e),onReset:()=>B(t.id),onCopied:O},`${t.id}:${N[t.id]||0}`)}),o&&!t.isSystem&&C[t.id]&&(0,l.jsxs)(n.kt.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:[!c&&(0,l.jsxs)(`div`,{className:`sm:hidden flex items-center justify-between gap-3 mb-5`,children:[(0,l.jsx)(`span`,{className:`text-[12px] font-semibold text-foreground/55`,children:`Spot in the menu`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,l.jsx)(n.i,{icon:n.dr,title:`Move up`,onClick:()=>he(t,`up`),children:`Up`}),(0,l.jsx)(n.i,{icon:n.hr,title:`Move down`,onClick:()=>he(t,`down`),children:`Down`})]})]}),!t.isSystem&&t.type!==`public`&&!c&&(0,l.jsxs)(`div`,{className:`sm:hidden flex items-center justify-between gap-3 mb-5`,children:[(0,l.jsx)(`span`,{className:`text-[12px] font-semibold text-foreground/55`,children:`Who can open this page`}),(0,l.jsx)(ta,{value:t.type,busy:T[t.id],onChange:e=>de(t,e)})]}),(0,l.jsx)(Po,{page:t,config:C[t.id],forms:t.type===`public`?re:ae,saving:T[t.id],isNew:c,quick:y===t.id,editing:S,onSave:e=>oe(t.id,e),addressTaken:ge,linkTargets:ye,onCreateLinkedPage:be,emailOn:A,footer:e=>S?(0,l.jsx)(r.g,{compact:!0,title:`Copy this to change the page`,prompt:Ra(t,e),locked:!!La(e),onCopied:O}):(0,l.jsx)(r.g,{compact:!0,title:`Then copy this into your assistant’s chat`,description:x?`This one builds the page from scratch. If it has been built already, switch to Edit with AI so your assistant changes it instead of starting over.`:void 0,prompt:xa(t,e,ye),locked:!!pa(t,e,ye),onCopied:O}),actions:(0,l.jsxs)(l.Fragment,{children:[Va(C[t.id],Ha(t,C[t.id])??_e(t.type))&&(0,l.jsx)(n.i,{icon:n.rn,tone:`danger`,compact:!0,title:`Reset this page`,busy:F[t.id],onClick:()=>B(t.id),children:`Reset`}),!t.isSystem&&(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Delete this page`,onClick:()=>fe(t.id,t.isSystem),children:`Delete`})]})},t._uiKey||t.id)]})]})]},`${e.id}-${t._uiKey||t.id}`)};return(0,l.jsx)(n.kt.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},className:`flex flex-col relative`,children:(0,l.jsx)(n.u,{icon:c,title:e.title,description:e.description,children:o.length===0?(0,l.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,l.jsx)(n.i,{icon:n.cn,onClick:()=>Q(e.id),children:`Add a page`}),(0,l.jsxs)(`p`,{className:`text-[12.5px] text-foreground/55 font-medium leading-relaxed`,children:[(0,l.jsx)(`span`,{className:`sm:hidden`,children:ra}),(0,l.jsx)(`span`,{className:`max-sm:hidden`,children:na})]})]}):(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[h.map(e=>S(e,!1)),(0,l.jsx)(`div`,{className:`flex items-center rounded-2xl border border-dashed border-[var(--panel-border)] px-5 py-3`,children:(0,l.jsx)(n.i,{icon:n.cn,onClick:()=>Q(e.id),children:`Add a page`})}),x.length>0&&(0,l.jsxs)(`details`,{className:`mt-4 group/details`,children:[(0,l.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,l.jsx)(n.tr,{className:`w-3.5 h-3.5 group-open/details:-rotate-180 transition-transform`}),`Hidden pages (`,x.length,`)`]}),(0,l.jsx)(`div`,{className:`flex flex-col gap-4 mt-4`,children:x.map(e=>S(e,!0))})]})]})})},e.id)})})]})]}),(0,l.jsx)(me,{isOpen:!!L,onCancel:()=>R(null),onConfirm:pe,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:V}),(0,l.jsx)(me,{isOpen:!!z,onCancel:()=>B(null),onConfirm:ve,title:s.find(e=>e.id===z)?.isSystem?`Start this page again?`:`Reset this page?`,message:(()=>{let e=s.find(e=>e.id===z);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&&Ha(e,C[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:s.find(e=>e.id===z)?.isSystem?`Start again`:`Reset page`,isProcessing:!!z&&!!F[z]})]})}var Lo=new Set([`contact`,`support`]),Ro=[{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`}],zo={value:`schedule`,label:`A time to book`},Bo={age:`Age`},Vo=e=>[...Ro,zo].find(t=>t.value===e)?.label||Bo[e||``]||`Short text`,Ho=(e,t=!1)=>{let n=t||e===`schedule`?[...Ro,zo]:Ro;return n.some(t=>t.value===e)||!e?n:[...n,{value:e,label:Vo(e)}]},Uo=(e,t)=>{let r=n.mt(e).map(e=>{let r=t.find(t=>t.id===e);return r?n.st(r):``}).filter(Boolean);return r.length?r.join(`, `):`nothing picked yet`},Wo={public:`Anyone`,private:`Signed-in users`},Go=e=>(e||``).toLowerCase().trim().replace(/[^a-z0-9]+/g,`_`).replace(/^_+|_+$/g,``),Ko=(e,t)=>{if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}_${n}`);)n++;return`${e}_${n}`},qo=(e,t,n)=>{if(!(!e.name||e.name===Go(e.label||``)))return e.name;let r=Go(t);return r?Ko(r,n.filter(t=>t!==e).map(e=>e.name)):``},Jo=()=>({name:``,type:`text`,label:``,placeholder:``,required:!1}),Yo={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.`},Xo=`(max-width: 767px)`,Zo=()=>typeof window<`u`&&typeof window.matchMedia==`function`&&window.matchMedia(Xo).matches;function Qo(){let[e,t]=(0,a.useState)(Zo);return(0,a.useEffect)(()=>{if(typeof window>`u`||typeof window.matchMedia!=`function`)return;let e=window.matchMedia(Xo),n=()=>t(e.matches);return n(),e.addEventListener?.(`change`,n),()=>e.removeEventListener?.(`change`,n)},[]),e}function $o({choices:e,onChange:t}){return(0,l.jsx)(n.r,{label:`Choices`,hint:`The options people pick from.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.length===0&&(0,l.jsx)(`span`,{className:`text-[12px] text-foreground/40 font-medium px-1`,children:`No choices yet — add the first one.`}),e.map((r,i)=>(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`input`,{type:`text`,value:r,"aria-label":`Choice ${i+1}`,placeholder:`e.g. Under 1,000`,onChange:n=>t(e.map((e,t)=>t===i?n.target.value:e)),className:n.o}),(0,l.jsx)(n.i,{icon:n.Pt,tone:`danger`,title:`Remove choice ${i+1}`,onClick:()=>t(e.filter((e,t)=>t!==i)),children:`Remove`})]},i)),(0,l.jsx)(`div`,{children:(0,l.jsx)(n.i,{icon:n.cn,onClick:()=>t([...e,``]),children:`Add choice`})})]})})}function es(){let{userRole:e}=r.j(),i=(0,u.useNavigate)(),s=n.br(),c=()=>{let e=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},n={...t._,contact:s?.defaultConfigs?.contactForm||t._.contact,support:s?.defaultConfigs?.supportForm||t._.support};for(let[t,r]of Object.entries(e))n[t]=r;return n},[d,f]=(0,a.useState)(()=>{try{if(typeof window<`u`){let e=localStorage.getItem(`fbos_swr_forms`);if(e)return JSON.parse(e)}let e={...t._,contact:s?.defaultConfigs?.contactForm||t._.contact,support:s?.defaultConfigs?.supportForm||t._.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{}}}),[p,m]=(0,a.useState)(()=>!(typeof window<`u`&&localStorage.getItem(`fbos_swr_forms`))),[h,g]=(0,a.useState)({}),[_,v]=(0,a.useState)(null),[y,b]=(0,a.useState)(new Set),x=Qo(),{schedules:S}=t.c(),[C,w]=(0,a.useState)({}),[T,E]=(0,a.useState)(null),[D,O]=(0,a.useState)(!1),[k,A]=(0,a.useState)({}),j=(0,a.useRef)({}),M=(e,t)=>{j.current={...j.current,[e]:t},A(j.current)};(0,a.useEffect)(()=>{N()},[]);let N=async()=>{try{m(!0);let e=await(0,o.getDocs)((0,o.collection)(n.Sr,`sys_forms`)),t={},r=new Set;e.forEach(e=>{if(e.id!==`pubForm`&&e.id!==`userForm`){let n=e.data();n._uiKey=d[e.id]?._uiKey||n._uiKey||Math.random().toString(36).substring(7),t[e.id]=n,r.add(e.id)}}),b(r);try{await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_forms`,`pubForm`)),await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_forms`,`userForm`))}catch{}let i=c();for(let[e,n]of Object.entries(i))if(!t[e]){let r={...n};r._uiKey=d[e]?._uiKey||Math.random().toString(36).substring(7),t[e]=r}else if(t[e]._uiKey=d[e]?._uiKey||t[e]._uiKey||Math.random().toString(36).substring(7),!t[e].fields||t[e].fields.length===0){let n=i[e];t[e].fields=n.fields||[]}let a={};for(let e of Object.keys(i))t[e]&&(a[e]=t[e]);for(let e of Object.keys(t))a[e]||(a[e]=t[e]);let s=window.location.pathname.split(`/forms/`)[1]?.split(`/`)[0];s&&a[s]&&w({[s]:!0}),j.current={},A({}),f(a),typeof window<`u`&&localStorage.setItem(`fbos_swr_forms`,JSON.stringify(a))}catch(e){console.error(`Failed to load forms:`,e)}finally{m(!1)}},P=async(e,t)=>{let r={...t};d[e]?._uiKey&&(r._uiKey=d[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()!==``){f(t=>{let n={};for(let a of Object.keys(t))a===e?n[i]=r:n[a]=t[a];return n}),C[e]&&w(t=>{let n={};for(let r of Object.keys(t))r===e?n[i]=t[r]:n[r]=t[r];return n}),g(e=>({...e,[i]:!0}));try{await(0,o.setDoc)((0,o.doc)(n.Sr,`sys_forms`,i),r),await(0,o.deleteDoc)((0,o.doc)(n.Sr,`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(()=>{g(e=>({...e,[i]:!1}))},500)}}else{f(t=>({...t,[e]:r})),g(t=>({...t,[e]:!0}));try{await(0,o.setDoc)((0,o.doc)(n.Sr,`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(()=>{g(t=>({...t,[e]:!1}))},500)}}},F=(e,t,n)=>M(e,{...t,...n}),I=(e,t,n)=>{let r={...t,...n};M(e,r),P(e,r)},L=e=>{let t=j.current[e];t&&P(e,t)},R=(e,t,n)=>I(e,t,{fields:n}),z=async e=>{if(!Lo.has(e)){O(!0);try{await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_forms`,e)),f(t=>{let n={...t};return delete n[e],n}),i(`/forms`)}catch(e){console.error(`Failed to delete form`,e)}finally{O(!1),E(null)}}},B=async e=>{if(!y.has(e)){E(null);return}O(!0);let t=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},r=Lo.has(e)||!!t[e]||!!s?.defaultConfigs?.[e]||!!s?.defaultConfigs?.[`${e}Form`];try{r?(g(t=>({...t,[e]:!0})),await(0,o.deleteDoc)((0,o.doc)(n.Sr,`sys_forms`,e)),localStorage.removeItem(`fbos_form_${e}`),localStorage.removeItem(`fbos_custom_form_${e}`),await N(),setTimeout(()=>g(t=>({...t,[e]:!1})),500)):await P(e,c().contact||c().support)}catch(e){console.error(`Reset failed:`,e)}finally{O(!1),E(null)}};if(e!==`admin`)return(0,l.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,l.jsx)(Sr,{})});let V=e=>{w(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})},H=Object.keys(C).find(e=>C[e]),U=(e,t,r,i,a)=>{let o=(n,r)=>{let o=a.map((e,t)=>t===i?{...e,...n}:e);r?R(e,t,o):F(e,t,{fields:o})},s=n=>{let o=n===`schedule`?{type:n,look:`compact`,schedules:[]}:n===`select`?{type:n,options:r.options||[]}:{type:n};R(e,t,a.map((e,t)=>{if(t!==i)return e;let r={...e,...o};return n!==`schedule`&&(delete r.members,delete r.schedules,delete r.look),r}))},c=n=>{let r=i+n;if(r<0||r>=a.length)return;let o=[...a];[o[i],o[r]]=[o[r],o[i]],R(e,t,o)},u=r.type!==`checkbox`&&r.type!==`select`&&r.type!==`date`&&r.type!==`file`&&r.type!==`schedule`;return(0,l.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,l.jsxs)(`div`,{className:`flex items-center justify-between gap-2 flex-wrap`,children:[(0,l.jsxs)(`span`,{className:`text-[13px] font-bold text-foreground`,children:[`Question `,i+1,r.type===`schedule`&&(0,l.jsxs)(`span`,{className:`font-medium text-foreground/50`,children:[` · A time to book — `,Uo(r,S)]})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,l.jsx)(n.i,{icon:n.dr,disabled:i===0,title:`Move up`,onClick:()=>c(-1),children:`Up`}),(0,l.jsx)(n.i,{icon:n.hr,disabled:i===a.length-1,title:`Move down`,onClick:()=>c(1),children:`Down`}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,title:`Remove question ${i+1}`,onClick:()=>R(e,t,a.filter((e,t)=>t!==i)),children:`Remove`})]})]}),(0,l.jsx)(n.h,{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=>o({label:e,name:qo(r,e,a)},!1),onBlur:()=>L(e)}),(0,l.jsx)(n.d,{label:`Kind of answer`,hint:`Sets the box people type into and what counts as a valid answer.`,value:r.type||`text`,options:Ho(r.type,S.length>0),allowEmpty:!1,onChange:s}),(0,l.jsx)(n._,{label:`Required`,hint:`On means the form cannot be sent until this is answered.`,hintWideOnly:!0,enabled:!!r.required,onChange:e=>o({required:e},!0)}),r.type===`select`&&(0,l.jsx)($o,{choices:r.options||[],onChange:e=>o({options:e},!0)}),r.type===`schedule`&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.r,{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:n.mt(r).length?void 0:`Pick at least one schedule`,children:(0,l.jsx)(Li,{schedules:S,selected:n.mt(r),onPick:e=>{o({schedules:n.tt(n.mt(r),e,S)},!0)}})}),(0,l.jsx)(n.d,{label:`How should the booking look?`,value:r.look||`compact`,options:n.y,allowEmpty:!1,onChange:e=>o({look:e===`calendar`?`calendar`:`compact`},!0)})]}),r.type===`file`&&(0,l.jsx)(n.h,{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=>o({placeholder:e},!1),onBlur:()=>L(e)}),r.type===`currency`&&(0,l.jsx)(n.h,{label:`Currency symbol`,hint:`Shown inside the box, before the amount.`,value:r.currencySymbol||``,placeholder:`$`,onChange:e=>o({currencySymbol:e},!1),onBlur:()=>L(e)}),u&&(0,l.jsx)(n.h,{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=>o({placeholder:e},!1),onBlur:()=>L(e)})]},i)},ee=(e,t)=>{let r=k[e]||t,i=Lo.has(e),a=r.formType||`public`,o=r.fields||[],s=y.has(e);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsxs)(n.u,{icon:n.Ht,title:`Basics`,description:`What people see at the top of this form and on its button.`,children:[(0,l.jsx)(n.h,{label:`Form name`,hint:`The heading at the top of the form.`,value:r.title||``,placeholder:`e.g. Get in touch`,onChange:t=>F(e,r,{title:t}),onBlur:()=>L(e)}),(0,l.jsx)(n.h,{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=>F(e,r,{buttonName:t,submitText:t}),onBlur:()=>L(e)})]}),(0,l.jsx)(n.u,{icon:n.Rt,title:`Who it is for`,description:`Who can fill this in, and where their answers land.`,children:(0,l.jsx)(n.d,{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:a,allowEmpty:!1,disabled:!0,options:[{value:`public`,label:`Anyone`},{value:`private`,label:`Signed-in users`}],onChange:t=>I(e,r,{formType:t})})}),(0,l.jsx)(n.u,{icon:n.tn,title:`After sending`,description:`What happens the moment someone sends this form.`,children:(0,l.jsx)(n.h,{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=>F(e,r,{redirectTo:t}),onBlur:()=>L(e)})}),(0,l.jsxs)(n.u,{icon:n.bn,title:`Questions`,description:`Everything this form asks for, in the order people answer it.`,actions:(0,l.jsx)(n.i,{icon:n.cn,compact:!0,title:`Add a question`,onClick:()=>R(e,r,[...o,Jo()]),children:`Add question`}),children:[o.length===0?(0,l.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.`}):o.map((t,n)=>U(e,r,t,n,o)),o.length>0&&(0,l.jsx)(`div`,{className:`flex justify-start`,children:(0,l.jsx)(n.i,{icon:n.cn,onClick:()=>R(e,r,[...o,Jo()]),children:`Add question`})})]}),(s||!i)&&(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 pt-1`,children:[s&&(0,l.jsx)(n.i,{icon:n.rn,tone:`danger`,compact:!0,title:`Reset this form`,onClick:()=>E({kind:`reset`,id:e}),children:`Reset this form`}),!i&&(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Delete this form`,onClick:()=>E({kind:`delete`,id:e}),children:`Delete this form`})]})]})};return(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:`Forms`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/forms`,H?`/${H}`:``]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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,l.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,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-lg md:text-xl font-extrabold text-foreground tracking-tight leading-tight md:leading-7`,children:`Your forms`}),(0,l.jsxs)(`p`,{className:`text-[12.5px] md:text-[14px] font-medium text-foreground/60 mt-1 md:mt-2 leading-relaxed`,children:[(0,l.jsx)(`span`,{className:`md:hidden`,children:`Look a form over and touch it up. Answers arrive in your Inbox.`}),(0,l.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,l.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(d).length===0&&!p?(0,l.jsx)(`div`,{className:`flex flex-col gap-4`,children:(0,l.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,l.jsx)(n.an,{className:`w-6 h-6 text-foreground/40`}),(0,l.jsx)(`p`,{className:`text-[13px] font-bold text-foreground/60`,children:`You have no forms yet.`}),(0,l.jsx)(`p`,{className:`text-[12.5px] text-foreground/55 font-medium leading-relaxed text-center max-w-md`,children:Yo.firstForm})]})}):(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsx)(n.At,{children:Object.entries(d).map(([e,t])=>{let r=k[e]||t,i=C[e],a=h[e],o=(r.fields||[]).length;return(0,l.jsxs)(n.kt.div,{initial:{opacity:0,y:12},animate:{opacity:1,y:0},exit:{opacity:0,y:-12},transition:{duration:.35,ease:`easeOut`},onClick:()=>V(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 ${i?`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,l.jsxs)(`div`,{className:`flex flex-row justify-between w-full gap-2 ${x?`items-start`:`items-center`}`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-1 min-w-0 flex-1 pr-2 sm:pr-4`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`h3`,{className:`text-[14px] font-bold text-foreground break-words ml-1 leading-snug`,children:r.title||`Untitled form`}),a&&(0,l.jsx)(n.yn,{className:`w-3 h-3 animate-spin text-accent ml-2 shrink-0`})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 mt-1.5 ml-1`,children:[(0,l.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,l.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full shrink-0 ${r.formType===`private`?`bg-blue-500`:`bg-emerald-500`}`}),Wo[r.formType||`public`]]}),(0,l.jsx)(`span`,{className:`max-sm:hidden text-[11px] font-medium text-foreground/45`,children:o===1?`1 question`:`${o} questions`})]})]}),x?(0,l.jsxs)(`div`,{className:`flex items-center gap-0.5 shrink-0 -mt-0.5 -mr-1.5`,children:[(0,l.jsx)(`button`,{type:`button`,title:`Preview this form`,"aria-label":`Preview this form`,onClick:e=>{e.stopPropagation(),v(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,l.jsx)(n.In,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{type:`button`,title:i?`Close this form`:`Open this form`,"aria-label":i?`Close this form`:`Open this form`,"aria-expanded":i,onClick:t=>{t.stopPropagation(),V(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,l.jsx)(n.tr,{className:`w-4 h-4 transition-transform duration-300 ${i?`rotate-180`:``}`})})]}):(0,l.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,l.jsx)(n.i,{icon:n.In,title:`Preview this form`,onClick:e=>{e.stopPropagation(),v(r)},children:`Preview`}),(0,l.jsx)(`button`,{type:`button`,title:i?`Close this form`:`Open this form`,"aria-label":i?`Close this form`:`Open this form`,"aria-expanded":i,onClick:t=>{t.stopPropagation(),V(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,l.jsx)(n.tr,{className:`w-4 h-4 transition-transform duration-300 ${i?`rotate-180`:``}`})})]})]}),(0,l.jsx)(n.At,{children:i&&(0,l.jsx)(n.kt.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:ee(e,t)})})]},t._uiKey||e)})}),p&&(0,l.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,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin text-accent`}),(0,l.jsx)(`span`,{className:`text-[12px] font-bold text-foreground/50 tracking-wider uppercase select-none`,children:`Loading your forms`})]})]})})]})]}),(0,l.jsx)(me,{isOpen:!!T,onCancel:()=>E(null),onConfirm:()=>{T&&(T.kind===`delete`?z(T.id):B(T.id))},title:T?.kind===`reset`?`Reset this form`:`Delete this form`,message:T?.kind===`reset`?`Undo every change made to ${d[T.id]?.title||T.id} and put it back the way it shipped. Answers already collected are kept.`:`Permanently delete ${T?d[T.id]?.title||T.id:``}. This cannot be undone. Answers already collected are kept.`,confirmText:T?.kind===`reset`?`Reset form`:`Delete form`,isProcessing:D}),_&&(0,l.jsx)(t.t,{formConfig:_,onClose:()=>v(null)})]})}var ts=[{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`}],ns=new Set([`home`,`drive`,`assets`,`contact`,`guide`,`templates`,`setup`,`support`,`theme`,`page_order`,`tab_order`]),rs={public:0,user:1,internal:2,admin:3},is=(e,t)=>{let n=String(e||``).trim();return n?n.startsWith(`/`)?n:`/${n}`:`/${t}`},as=e=>new Set((Array.isArray(e?.order)?e.order:[]).filter(e=>e&&typeof e==`object`&&e.removed).map(e=>String(e.id)));function os(e,t,n,i,a=S()){let o=[...ts];for(let{id:t,data:n}of e)ns.has(t)||o.push({id:t,title:String(n?.pageName||n?.title||t),path:is(n?.route,t),brief:String(n?.brief||``),config:n,audience:`public`});for(let{id:e,data:n}of t)ns.has(e)||o.push({id:e,title:String(n?.tabName||n?.title||e),path:is(n?.route,e),brief:String(n?.brief||``),config:n,audience:r.V(n?.pageType)});for(let[e,t]of a){if(ns.has(e)||o.some(t=>t.id===e))continue;let a=!!t.isPublic;if((a?n:i).has(e))continue;let s=t.config||{},c=is(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`:r.V(s.pageType)})}return o.sort((e,t)=>(rs[e.audience||`public`]??9)-(rs[t.audience||`public`]??9)||e.title.localeCompare(t.title))}function ss(){let[e,t]=(0,a.useState)(null),[r,i]=(0,a.useState)(null),[s,c]=(0,a.useState)(new Set),[l,u]=(0,a.useState)(new Set);return(0,a.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)(n.Sr,`sys_pages`),n=>t(e(n)),()=>t([])),(0,o.onSnapshot)((0,o.collection)(n.Sr,`sys_tabs`),t=>i(e(t)),()=>i([])),(0,o.onSnapshot)((0,o.doc)(n.Sr,`sys_configs`,`page_order`),e=>c(as(e.exists()?e.data():null)),()=>{}),(0,o.onSnapshot)((0,o.doc)(n.Sr,`sys_configs`,`tab_order`),e=>u(as(e.exists()?e.data():null)),()=>{})];return()=>r.forEach(e=>e())},[]),e===null||r===null?null:os(e,r,s,l)}function cs({product:e,live:t,open:r,onToggle:i,onChange:a,onProceed:o}){let s=t=>a({...e,...t});if(!Gr(e,t))return(0,l.jsx)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] opacity-50`,"aria-disabled":`true`,children:(0,l.jsxs)(`div`,{className:`w-full flex items-center justify-between gap-3 px-4 py-3`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/60 truncate`,children:Jr(e)}),(0,l.jsx)(n.f,{state:`off`,label:`Finish it above first`})]})});let c=si(e),u=e.kind===`subscription`;return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`button`,{type:`button`,onClick:i,"aria-expanded":r,className:`w-full flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Jr(e)}),(0,l.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,l.jsx)(n.f,{state:c?`off`:`saved`,label:c?`Question left`:`Described`}),(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${r?`rotate-180`:``}`})]})]}),r&&(0,l.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,l.jsx)(n.m,{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=>s({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,l.jsxs)(`div`,{className:`flex flex-col gap-3 rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5`,children:[(0,l.jsx)(n._,{label:`Email the buyer a confirmation`,hint:`Needs email set up on this screen.`,hintWideOnly:!0,enabled:e.emailReceipt,onChange:e=>s({emailReceipt:e})}),(0,l.jsx)(n._,{label:`Email me when someone buys`,hint:`Needs email set up on this screen.`,hintWideOnly:!0,enabled:e.notifyOwner,onChange:e=>s({notifyOwner:e})})]}),(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:[c?(0,l.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:c}):(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Described — press Proceed to say where it goes.`}),c?(0,l.jsx)(`span`,{}):(0,l.jsx)(n.i,{icon:n.pr,onClick:o,children:`Proceed`})]})]})]})}function ls({products:e,live:t,openId:r,onToggle:i,onChange:a,onProceed:o}){return e===null?(0,l.jsx)(`p`,{className:n.a,children:`Loading your payments…`}):e.length===0?(0,l.jsx)(`p`,{className:`${n.a} 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,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.map(e=>(0,l.jsx)(cs,{product:e,live:t,open:r===e.id,onToggle:()=>i(e.id),onChange:a,onProceed:()=>o(e.id)},e.id))})}var us=[{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 ds({row:e,on:t,onToggle:r}){return(0,l.jsxs)(`button`,{type:`button`,role:`checkbox`,"aria-checked":t,"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,l.jsx)(`span`,{"aria-hidden":!0,className:`w-[18px] h-[18px] rounded-md border flex items-center justify-center shrink-0 transition-colors ${t?`bg-accent border-accent`:`border-[var(--panel-border)]`}`,children:t&&(0,l.jsx)(n.nr,{className:`w-3 h-3 text-[var(--button-fg,#fff)]`})}),(0,l.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 truncate min-w-0`,children:e.title}),(0,l.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/40 truncate shrink-0`,children:e.path})]})}function fs({product:e,pageRows:t,live:r,open:i,onToggle:a,onChange:o}){let s=t=>o({...e,...t});if(!(Gr(e,r)&&!si(e)))return(0,l.jsx)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] opacity-50`,"aria-disabled":`true`,children:(0,l.jsxs)(`div`,{className:`w-full flex items-center justify-between gap-3 px-4 py-3`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/60 truncate`,children:Jr(e)}),(0,l.jsx)(n.f,{state:`off`,label:`Describe it above first`})]})});let c=di(e,t);return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`button`,{type:`button`,onClick:a,"aria-expanded":i,className:`w-full flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Jr(e)}),(0,l.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,l.jsx)(n.f,{state:c?`off`:`saved`,label:c?`Where does it go?`:`Placed`}),(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${i?`rotate-180`:``}`})]})]}),i&&(0,l.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,l.jsx)(n.r,{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,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[us.map(n=>{let r=t.filter(e=>(e.audience||`public`)===n.audience);return r.length?(0,l.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,l.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-widest text-foreground/40 px-1`,children:n.label}),(0,l.jsx)(`div`,{className:`flex flex-col rounded-2xl border border-[var(--panel-border)]/60 px-2 py-1.5`,children:r.map(t=>(0,l.jsx)(ds,{row:t,on:li(e,t),onToggle:()=>s({pageIds:ui(e,t)})},t.id))})]},n.audience):null}),(0,l.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Pages you make on the`,` `,(0,l.jsx)(u.Link,{to:`/pages`,className:`text-accent font-bold hover:underline`,children:`Pages screen`}),` `,`appear here on their own.`]})]})}),(0,l.jsx)(n.m,{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=>s({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,l.jsx)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:c?(0,l.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:c}):(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Placed — the request under these carries it.`})})]})]})}function ps({products:e,pageRows:t,live:i,openId:a,onToggle:o,onChange:s}){if(e===null||t===null)return(0,l.jsx)(`p`,{className:n.a,children:`Loading your pages…`});if(e.length===0)return(0,l.jsx)(`p`,{className:`${n.a} px-1`,children:`Nothing here yet. Each payment you describe above appears here with one question: which pages it goes on.`});let c=fi(e,t,i),u=c?``:xi(e,t,i);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.map(e=>(0,l.jsx)(fs,{product:e,pageRows:t,live:i,open:a===e.id,onToggle:()=>o(e.id),onChange:s},e.id))}),(0,l.jsx)(r.g,{title:`Copy this to wire everything in`,prompt:u,locked:u===``}),c?(0,l.jsx)(`span`,{className:n.a,children:c}):(0,l.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 on the Pages screen, with Edit with AI.`})]})}function ms({title:e,path:t,hint:r}){let[i,o]=(0,a.useState)(!1),s=n.M(t);return(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-2.5 rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/80 truncate`,children:e}),(0,l.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/45 truncate`,children:r||s})]}),(0,l.jsx)(n.i,{icon:i?n.nr:n.Un,compact:!0,title:`Copy the link to ${e}`,onClick:()=>{try{navigator.clipboard?.writeText(s)?.catch(()=>{})}catch{}o(!0),setTimeout(()=>o(!1),1500)},children:i?`Copied`:`Copy link`})]})}var hs=e=>Ji(`pay-${qr(e)}`)||`pay-${e.id}`,gs=e=>{let t=Fr(e).map(e=>e.amount.trim()).filter(Boolean).join(` + `);return`${qr(e)}${t?` — ${t}`:``}`};function _s(e,t,n){return[xa(t,n),`This page is the page of my payment link for ${qr(e)} — everyone I send ${t.path} to lands here and pays here.`,...ti(e,t.path)].join(`
|
|
26
|
+
`)}function vs({product:e,open:t,onToggle:i,onChange:o,onRemove:s,onCustomise:c}){let[u,d]=(0,a.useState)(!1),[f,p]=(0,a.useState)(!1),[m,h]=(0,a.useState)(``),[g,_]=(0,a.useState)(``),v=e.customPath.trim(),y=v?v.startsWith(`/`)?v:`/${v}`:n.et(e.id);return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2 pr-3`,children:[(0,l.jsxs)(`button`,{type:`button`,onClick:i,"aria-expanded":t,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:gs(e)}),(0,l.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[(0,l.jsx)(n.f,{state:v?`saved`:`off`,label:v?`Your own page`:`Ready-made page`}),(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${t?`rotate-180`:``}`})]})]}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Remove the link to ${qr(e)}`,onClick:()=>d(!0),children:`Remove`})]}),(0,l.jsx)(me,{isOpen:u,title:`Remove the link to ${qr(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:()=>d(!1),onConfirm:()=>{d(!1),s()}}),t&&(0,l.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,l.jsx)(n.r,{label:`The link`,hint:`Send it to anyone. The page wears your theme and your app's name.`,children:(0,l.jsx)(ms,{title:qr(e),path:y})}),(0,l.jsx)(n.h,{label:`What is it called?`,value:Fr(e)[0]?.name||``,onChange:t=>o({...e,items:[{...Fr(e)[0]||{amount:``},name:t},...Fr(e).slice(1)]}),placeholder:`A one-hour session`}),(0,l.jsx)(n.m,{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,l.jsx)(n.h,{label:`The price`,value:Fr(e)[0]?.amount||``,onChange:t=>o({...e,items:[{...Fr(e)[0]||{name:``},amount:t},...Fr(e).slice(1)]}),placeholder:`25`,error:Fr(e)[0]?.amount.trim()&&Ir(Fr(e)[0].amount)===null?`Just a number, like 25.`:void 0}),!v&&!f&&!m&&(0,l.jsx)(n.i,{icon:n.It,onClick:()=>p(!0),children:`Customise this page`}),(f||m)&&(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-4`,children:[(0,l.jsx)(n.m,{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}),g&&(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:g}),m?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(r.g,{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:m}),(0,l.jsx)(n._,{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?`/${hs(e)}`:``})})]}):(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(n.i,{icon:n.It,disabled:!e.customNote.trim(),onClick:async()=>{_(``);let e=await c();if(typeof e==`string`){_(e);return}h(e.prompt)},children:`Make the page`}),(0,l.jsx)(n.i,{onClick:()=>{p(!1),_(``)},children:`Never mind`})]})]}),v&&!m&&(0,l.jsx)(n._,{label:`The page is built — send people there`,hint:`The link opens ${y}. Change the page on the Pages screen with Edit with AI. Turn this off to go back to the ready-made page.`,enabled:!0,onChange:t=>o({...e,customPath:t?e.customPath:``})})]})]})}function ys({products:e,onChange:t,onRemove:r}){let[i,o]=(0,a.useState)(null),s=e.filter(e=>e.kind===`once`),c=()=>{let e={...Pr(`p_${Date.now().toString(36)}`),kind:`once`,items:[{name:``,amount:``}]};t(e),o(e.id)},u=async e=>{let t=hs(e),n=`Pay — ${qr(e)}`,r={name:n,address:t,type:`public`,about:e.customNote.trim()};try{await Zi(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}=Xi(r),a={title:n,path:`/${t}`};return{path:a.path,prompt:_s(e,a,i)}};return(0,l.jsx)(n.u,{icon:n.Sn,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:(0,l.jsx)(n.i,{icon:n.cn,title:`Add a payment link`,onClick:c,children:`Add a payment link`}),children:(0,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:s.length===0?(0,l.jsx)(`p`,{className:`${n.a} 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.`}):s.map(e=>(0,l.jsx)(vs,{product:e,open:i===e.id,onToggle:()=>o(i===e.id?null:e.id),onChange:t,onRemove:()=>r(e.id),onCustomise:()=>u(e)},e.id))})})}var bs=e=>e.trim()&&Ir(e)===null?`Just a number, like 25.`:void 0,xs=e=>/^price_[A-Za-z0-9]+$/.test(e.trim());function Ss({item:e,index:t,onChange:r,onRemove:i,removable:a}){let o=bs(e.amount);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`input`,{type:`text`,value:e.name,onChange:t=>r({...e,name:t.target.value}),placeholder:t===0?`A one-hour call`:`A two-hour call`,"aria-label":`Thing ${t+1} — its name`,className:`${n.o} flex-1 min-w-0`}),(0,l.jsx)(`input`,{type:`text`,inputMode:`decimal`,value:e.amount,onChange:t=>r({...e,amount:t.target.value}),placeholder:`25`,"aria-label":`Thing ${t+1} — its price`,className:`${n.o} w-24 shrink-0 text-right ${o?`border-red-500/50`:``}`}),a&&(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Remove ${e.name.trim()||`thing ${t+1}`}`,onClick:i,children:`Remove`})]}),o&&(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:o})]})}function Cs({plan:e,index:t,onChange:r,onRemove:i}){let a=t=>r({...e,...t});return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-4`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,l.jsxs)(`span`,{className:`text-[11px] font-bold uppercase tracking-widest text-foreground/40`,children:[`Plan `,t+1]}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Remove this plan`,onClick:i,children:`Remove plan`})]}),(0,l.jsx)(n.h,{label:`What is this plan called?`,value:e.name,onChange:e=>a({name:e}),placeholder:`Basic`}),(0,l.jsx)(n.h,{label:`One line about it`,hint:`Optional — what a buyer gets on this plan.`,value:e.description,onChange:e=>a({description:e}),placeholder:`Up to 3 projects and email support`}),[[`monthly`,`Billed monthly`,`a month`],[`yearly`,`Billed yearly`,`a year`]].map(([r,i,o])=>(0,l.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/80 ml-1`,children:i}),(0,l.jsx)(n.g,{enabled:e[r].on,onChange:t=>a({[r]:{...e[r],on:t}}),label:`${i} — plan ${t+1}`})]}),e[r].on&&(0,l.jsx)(n.h,{label:`The price ${o}`,hint:`Just the number — 25 charges 25 ${o} in your Stripe account's currency.`,value:e[r].amount,onChange:t=>a({[r]:{...e[r],amount:t}}),placeholder:r===`monthly`?`25`:`250`,error:bs(e[r].amount)})]},r))]})}function ws({product:e,plan:t,index:r,live:i,onChange:a}){let o=i?`livePriceId`:`priceId`,s=(e,t)=>({...e,[o]:t}),c=(!t.monthly.on||xs(t.monthly[o]))&&(!t.yearly.on||xs(t.yearly[o])),u=e=>a({...t,...e}),d=e=>e.trim()&&!xs(e)?`A price id starts with price_ — copy it from the price you just made.`:void 0;return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:t.name.trim()||`Plan ${r+1}`}),(0,l.jsx)(n.f,{state:c?`saved`:`off`,label:c?`Done`:i?`Waiting for its live ids`:`Waiting for its ids`})]}),(0,l.jsx)(`ol`,{className:`space-y-1.5 list-decimal list-inside text-[12.5px] font-medium text-foreground/60 leading-relaxed`,children:Yr(e,t,i).map((e,t)=>(0,l.jsx)(`li`,{children:e},t))}),t.monthly.on&&(0,l.jsx)(n.h,{label:i?`Paste the live monthly price id`:`Paste the monthly price id`,value:t.monthly[o],onChange:e=>u({monthly:s(t.monthly,e)}),placeholder:`price_…`,error:d(t.monthly[o])}),t.yearly.on&&(0,l.jsx)(n.h,{label:i?`Paste the live yearly price id`:`Paste the yearly price id`,value:t.yearly[o],onChange:e=>u({yearly:s(t.yearly,e)}),placeholder:`price_…`,error:d(t.yearly[o])}),i&&(0,l.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 Ts({product:e,open:t,live:r,onToggle:i,onChange:o,onRemove:s,onProceed:c}){let u=t=>o({...e,...t}),d=(t,n)=>u({plans:e.plans.map((e,r)=>r===t?n:e)}),f=Gr(e,r),p=Wr(e,r),[m,h]=(0,a.useState)(!1),g=qr(e);return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2 pr-3`,children:[(0,l.jsxs)(`button`,{type:`button`,onClick:i,"aria-expanded":t,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:Jr(e)}),(0,l.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[e.kind&&(0,l.jsx)(n.f,{state:f?`saved`:`off`,label:f?`Ready`:`In progress`}),(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${t?`rotate-180`:``}`})]})]}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Remove ${g}`,onClick:()=>h(!0),children:`Remove`})]}),(0,l.jsx)(me,{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),s()}}),t&&(0,l.jsxs)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:[(0,l.jsx)(n.d,{label:`How is it paid?`,value:e.kind,onChange:t=>u({kind:t===`once`||t===`subscription`?t:``,plans:t===`subscription`&&!e.plans.length?[Mr()]:e.plans,items:t===`once`&&!e.items.length?[Nr()]:e.items}),options:[{value:`once`,label:`Once — one payment`},{value:`subscription`,label:`A subscription that renews`}],placeholder:`Choose one`}),e.kind===`once`&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.r,{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,l.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[e.items.map((t,n)=>(0,l.jsx)(Ss,{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,l.jsx)(n.i,{icon:n.cn,className:`self-start`,onClick:()=>u({items:[...e.items,Nr()]}),children:`Add another`})]})}),e.items.length>1&&(0,l.jsx)(n.h,{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,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h,{label:`What is the subscription called?`,value:e.name,onChange:e=>u({name:e}),placeholder:`Membership`}),(0,l.jsx)(n.m,{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,l.jsx)(n.r,{label:`Its plans`,hint:`Each plan can be billed monthly, yearly, or both.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.plans.map((t,n)=>(0,l.jsx)(Cs,{plan:t,index:n,onChange:e=>d(n,e),onRemove:()=>u({plans:e.plans.filter((e,t)=>t!==n)})},n)),(0,l.jsx)(n.i,{icon:n.cn,className:`self-start`,onClick:()=>u({plans:[...e.plans,Mr()]}),children:`Add a plan`})]})}),Kr(e)&&(0,l.jsx)(n.r,{label:r?`Now make it in Stripe — live mode`:`Now make it in Stripe`,hint:r?`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,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:e.plans.map((t,n)=>(0,l.jsx)(ws,{product:e,plan:t,index:n,live:r,onChange:e=>d(n,e)},n))})})]}),(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3 pt-1`,children:[e.kind&&!f?(0,l.jsx)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:p}):e.kind?(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-emerald-500`,children:`Ready — press Proceed to say how it works.`}):(0,l.jsx)(`span`,{}),f?(0,l.jsx)(n.i,{icon:n.pr,onClick:c,children:`Proceed`}):(0,l.jsx)(`span`,{})]})]})]})}function Es(){let[e,t]=(0,a.useState)(null),[r,i]=(0,a.useState)(!1),[s,c]=(0,a.useState)(null),[u,d]=(0,a.useState)(null),[f,p]=(0,a.useState)(null),[m,h]=(0,a.useState)(``),g=(0,a.useRef)(new Map),_=(0,a.useRef)(null),v=(0,a.useRef)(null),y=ss();(0,a.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(n.Sr,kr),e=>{let n=!!e.docs.find(e=>e.id===Ar)?.data()?.liveMode;if(i(n),Ti(n),g.current.size)return;let r=[];e.forEach(e=>{e.id!==`_settings`&&r.push(Vr(e.id,e.data()))}),r.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)),t(r)},()=>t([]));return()=>e()},[]);let b=e=>{let t=g.current.get(e.id);t&&clearTimeout(t),g.current.set(e.id,setTimeout(async()=>{g.current.delete(e.id);try{let{id:t,...r}=e;await(0,o.setDoc)((0,o.doc)(n.Sr,kr,t),r)}catch(e){console.error(`Could not save the product`,e)}},600))},x=e=>{t(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=Pr(`p_${Date.now().toString(36)}`);t(t=>[...t||[],e]),c(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(``),t(e=>(e||[]).filter(e=>e.id!==r)),s===r&&c(null),u===r&&d(null),f===r&&p(null);try{await(0,o.deleteDoc)((0,o.doc)(n.Sr,kr,r))}catch(e){console.error(`Could not remove the product`,e),a&&t(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=>{c(null),d(e),_.current?.scrollIntoView({behavior:`smooth`,block:`start`})};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.u,{icon:n.Zt,title:`What you sell`,description:`Things paid for once, each with a price; or a subscription with plans and their Stripe ids.`,children:(0,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:e===null?(0,l.jsx)(`p`,{className:n.a,children:`Loading what you sell…`}):(0,l.jsxs)(l.Fragment,{children:[e.length===0&&(0,l.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,l.jsx)(Ts,{product:e,open:s===e.id,live:r,onToggle:()=>c(s===e.id?null:e.id),onChange:x,onRemove:()=>C(e.id),onProceed:()=>w(e.id)},e.id)),!!m&&(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:m}),(0,l.jsx)(n.i,{icon:n.cn,className:`self-start`,onClick:S,children:`Add something you sell`})]})})}),(0,l.jsx)(`div`,{ref:_,children:(0,l.jsx)(n.u,{icon:n.Ft,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,l.jsx)(ls,{products:e,live:r,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,l.jsx)(`div`,{ref:v,children:(0,l.jsx)(n.u,{icon:n.ln,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,l.jsx)(ps,{products:e,pageRows:y,live:r,openId:f,onToggle:e=>p(f===e?null:e),onChange:x})})}),(0,l.jsx)(ys,{products:e||[],onChange:x,onRemove:C})]})}function Ds(e,t,n){return!e&&t!==`live`?{state:`off`,label:`In test mode`}:t===`live`?n?{state:`saved`,label:`Live`}:{state:`saved`,label:`Live — webhook still to add`}:{state:`saving`,label:`Waiting for the live key`}}function Os(){let[e,t]=(0,a.useState)(null),[i,s]=(0,a.useState)([]),[c,u]=(0,a.useState)(null),[d,f]=(0,a.useState)(!1);(0,a.useEffect)(()=>(0,o.onSnapshot)((0,o.collection)(n.Sr,kr),e=>{t(!!e.docs.find(e=>e.id===Ar)?.data()?.liveMode);let n=[];e.forEach(e=>{e.id!==`_settings`&&n.push(Vr(e.id,e.data()))}),n.sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)),s(n)},()=>t(!1)),[]),(0,a.useEffect)(()=>{let e=!0,t=async()=>{try{let t=await(await fetch(`/api/payments/status`)).json();if(!e)return;u(t?.mode===`live`||t?.mode===`test`?t.mode:null),f(!!t?.webhookConfigured)}catch{}};t();let n=setInterval(t,5e3);return()=>{e=!1,clearInterval(n)}},[]);let p=async e=>{t(e);try{await(0,o.setDoc)((0,o.doc)(n.Sr,kr,Ar),{liveMode:e},{merge:!0})}catch(e){console.error(`Could not save the go-live switch`,e)}};if(!d)return null;let m=!!e,h=Ds(m,c,d),g=i.filter(e=>Gr(e,!1)),_=g.filter(e=>!Gr(e,!0)),v=g.length>0&&_.length===0;return(0,l.jsx)(n.p,{icon:n.in,title:`Go live`,description:m?`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:h,enabled:e===null?null:m,onChange:p,children:m&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)(`ol`,{className:`space-y-2 list-decimal list-inside text-[12.5px] font-medium text-foreground/70 leading-relaxed`,children:[(0,l.jsxs)(`li`,{children:[`In your Stripe dashboard, switch `,(0,l.jsx)(`strong`,{children:`Test mode`}),` OFF. If Stripe asks you to `,(0,l.jsx)(`strong`,{children:`activate your account`}),` first — business details, a bank account for payouts — finish that: live payments only run on an activated account.`]}),(0,l.jsxs)(`li`,{children:[`Open`,` `,(0,l.jsx)(`a`,{href:`https://dashboard.stripe.com/apikeys`,target:`_blank`,rel:`noopener noreferrer`,className:`text-accent font-bold hover:underline`,children:`Developers → API keys`}),` `,`and copy the live Secret key — it starts with `,(0,l.jsx)(`strong`,{children:`sk_live_`}),`. In AI Studio's Secrets tab, open `,(0,l.jsx)(`strong`,{children:`STRIPE_SECRET_KEY`}),` and paste it over the old value.`]}),(0,l.jsxs)(`li`,{children:[`Open`,` `,(0,l.jsx)(`a`,{href:`https://dashboard.stripe.com/webhooks`,target:`_blank`,rel:`noopener noreferrer`,className:`text-accent font-bold hover:underline`,children:`Developers → Webhooks`}),` `,`and click `,(0,l.jsx)(`strong`,{children:`Add endpoint`}),`. As the endpoint URL, paste exactly this:`,(0,l.jsx)(`div`,{className:`my-2`,children:(0,l.jsx)(r.l,{code:r.k(),label:`Copy your webhook address`,compact:!0})}),`When Stripe asks which events to listen for, click`,` `,(0,l.jsx)(`strong`,{children:`Select events`}),`, search for`,` `,(0,l.jsx)(`strong`,{children:`checkout.session.completed`}),` and tick just that one. Save, then put the `,(0,l.jsx)(`strong`,{children:`Signing secret`}),` it shows (whsec_…) into the`,` `,(0,l.jsx)(`strong`,{children:`STRIPE_WEBHOOK_SECRET`}),` secret. This is what keeps receipts and your sale alerts sending even when a buyer closes the tab before coming back.`]}),(0,l.jsxs)(`li`,{children:[`Rebuild the app so it starts with the new keys — the chip up here flips to`,` `,(0,l.jsx)(`strong`,{children:`Live`}),` on its own once it has.`]})]}),(0,l.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,l.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.`]}),g.length>0&&!v&&(0,l.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,l.jsx)(`strong`,{children:`live`}),` price ids — `,_.length===g.length?`each one`:`${_.length} of ${g.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.`]}),v&&(0,l.jsx)(r.g,{title:`Tell your assistant about the switch`,prompt:Oi(g)})]})})}var ks={email:{collection:`sys_configs`,doc:`email`},payments:{collection:`sys_payments`,doc:`_settings`}},As=e=>e?.enabled!==!1;function js(e){let{collection:t,doc:i}=ks[e],[s,c]=(0,a.useState)({loading:!0,on:!0});return(0,a.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(n.Sr,t,i),e=>c({loading:!1,on:As(e.exists()?e.data():null)}),()=>c({loading:!1,on:!0})),[t,i]),{loading:s.loading,on:s.on,set:async a=>{let l=s.on;c({loading:!1,on:a});try{return await(0,o.setDoc)((0,o.doc)(n.Sr,t,i),{enabled:a},{merge:!0}),e===`payments`&&r.w(),null}catch{return c({loading:!1,on:l}),`The switch could not be saved. Check that you are signed in as an admin.`}}}}function Ms(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 Ns(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 Ps=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`}},Fs=e=>e?new Date(e*1e3).toLocaleDateString(void 0,{day:`numeric`,month:`short`,year:`numeric`}):``;function Is({label:e,tone:t}){return(0,l.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 Ls({children:e,tone:t=`quiet`}){return(0,l.jsx)(`p`,{className:`text-[12.5px] font-medium leading-relaxed px-1 ${t===`error`?`text-red-500`:`text-foreground/50`}`,children:e})}function Rs(){let{user:e}=r.j(),[t,i]=(0,a.useState)(null),[o,s]=(0,a.useState)(``),[c,d]=(0,a.useState)(null),[f,p]=(0,a.useState)(``),[m,h]=(0,a.useState)([]),[g,_]=(0,a.useState)([]),[v,y]=(0,a.useState)(!1),[b,x]=(0,a.useState)(``),[S,C]=(0,a.useState)(!1),[w,T]=(0,a.useState)(!1),[E,D]=(0,a.useState)(``),O=js(`payments`),[k,A]=(0,a.useState)(``),j=Ps(O.on),M=(0,a.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]);(0,a.useEffect)(()=>{let e=!1;return fetch(`/api/payments/status`).then(e=>e.json()).then(t=>{e||i(t)}).catch(()=>{e||s(`The server could not be reached.`)}),()=>{e=!0}},[]);let N=(0,a.useCallback)((e,t)=>{let n=e.charges||[],r=e.subscriptions||[];h(e=>t?[...e,...n]:n),_(e=>t?[...e,...r]:r),C(!!(e.chargesHasMore||e.subscriptionsHasMore))},[]);(0,a.useEffect)(()=>{if(!t?.configured||!e)return;let n=!1;return M(`/api/payments/products`).then(e=>{n||d(e.products||[])}).catch(e=>{n||p(e.message)}),M(`/api/payments/orders`).then(e=>{n||(N(e,!1),y(!0))}).catch(e=>{n||(x(e.message),y(!0))}),()=>{n=!0}},[t?.configured,e,M,N]);let P=async()=>{T(!0);try{let e=new URLSearchParams,t=m[m.length-1],n=g[g.length-1];t&&e.set(`starting_after`,t.id),n&&e.set(`subscriptions_after`,n.id),N(await M(`/api/payments/orders?${e}`),!0)}catch(e){x(e.message)}T(!1)},F=e=>{navigator.clipboard?.writeText(e),D(e),setTimeout(()=>D(``),2e3)},I=[...m,...g].sort((e,t)=>(t.created||0)-(e.created||0)),L=(c||[]).flatMap(e=>e.prices),R=t?.mode===`live`?`https://dashboard.stripe.com/products`:`https://dashboard.stripe.com/test/products`,z=!!(t&&!t.configured);return(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`Payments`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/payments`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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:!t&&!o?(0,l.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,l.jsx)(n.yn,{className:`w-6 h-6 animate-spin text-accent`})}):z?(0,l.jsxs)(n.u,{icon:n.Hn,title:`Connect Stripe`,description:`This app is not taking payments yet.`,collapsible:!1,children:[(0,l.jsx)(Ls,{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,l.jsxs)(u.Link,{to:`/setup`,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]`,children:[`Set up payments`,(0,l.jsx)(n.pr,{className:`w-3.5 h-3.5`})]})]}):(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[t?.mode===`live`&&(0,l.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,l.jsx)(n.Ut,{className:`w-4 h-4 text-red-500 shrink-0`}),(0,l.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,l.jsx)(n.p,{icon:n.sn,title:`Take payments`,description:j.description,chip:j.chip,enabled:O.loading?null:O.on,onChange:async e=>A(await O.set(e)||``),children:k?(0,l.jsx)(Ls,{tone:`error`,children:k}):null}),(0,l.jsx)(n.u,{icon:n.ln,title:`Connection`,description:`Whether this app can take money right now.`,defaultOpen:!t?.webhookConfigured,actions:o?(0,l.jsx)(n.f,{state:`error`,label:`Unreachable`}):(0,l.jsx)(n.f,{state:`saved`,label:t?.mode===`live`?`Live`:`Test mode`}),children:o?(0,l.jsx)(Ls,{tone:`error`,children:o}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(Ls,{children:t?.mode===`live`?`Stripe is connected with a live key. Payments made anywhere on your site are real.`:`Stripe is connected with a test key. Buttons work end to end, but only test cards are accepted and no real money moves.`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2.5 px-1 flex-wrap`,children:[(0,l.jsx)(n.f,{state:t?.webhookConfigured?`saved`:`off`,label:t?.webhookConfigured?`Webhook connected`:`Webhook not set`}),!t?.webhookConfigured&&(0,l.jsxs)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Add it on the`,` `,(0,l.jsx)(u.Link,{to:`/setup`,className:`text-accent font-bold hover:underline`,children:`setup page`}),` `,`— it keeps receipts and sale alerts sending, and the Go live switch appears here once it is in.`]})]})]})}),(0,l.jsx)(Os,{}),(0,l.jsx)(Es,{}),(0,l.jsx)(n.u,{icon:n.Kt,title:`In your Stripe account`,description:`The products and prices Stripe has right now — where price ids come from.`,defaultOpen:!1,children:f?(0,l.jsx)(Ls,{tone:`error`,children:f}):c===null?(0,l.jsx)(`div`,{className:`flex items-center justify-center py-6 text-foreground/40`,children:(0,l.jsx)(n.yn,{className:`w-5 h-5 animate-spin text-accent`})}):L.length===0?(0,l.jsxs)(Ls,{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,l.jsx)(`a`,{href:R,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,l.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:L.map(e=>(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${n.n}`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate min-w-0 flex-1`,children:e.productName||`Unnamed product`}),(0,l.jsxs)(`span`,{className:`text-[12.5px] font-semibold text-foreground/60 whitespace-nowrap shrink-0`,children:[Ns(e.amount,e.currency),e.interval?` / ${e.interval}`:``]}),(0,l.jsx)(n.i,{compact:!0,icon:E===e.id?n.nr:n.Un,title:`Copy the price id for ${e.productName||`this price`}`,onClick:()=>F(e.id),children:E===e.id?`Copied`:`Copy price id`})]},e.id))})}),(0,l.jsx)(n.u,{icon:n.on,title:`Payments received`,description:`Every charge and subscription, straight from Stripe.`,defaultOpen:!1,children:b?(0,l.jsx)(Ls,{tone:`error`,children:b}):v?I.length===0?(0,l.jsx)(Ls,{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,l.jsxs)(`div`,{className:`flex flex-col gap-2.5`,children:[I.map(e=>{let t=Ms(e);return(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.name||e.email||`Someone`}),(0,l.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,l.jsx)(`span`,{className:`max-sm:hidden text-[11.5px] font-medium text-foreground/45 whitespace-nowrap shrink-0`,children:Fs(e.created)}),(0,l.jsxs)(`span`,{className:`text-[12.5px] font-semibold text-foreground/70 whitespace-nowrap shrink-0`,children:[Ns(e.amount,e.currency),e.kind===`subscription`&&e.interval?` / ${e.interval}`:``]}),(0,l.jsx)(Is,{label:t.label,tone:t.tone})]},e.id)}),S&&(0,l.jsx)(n.i,{busy:w,onClick:P,className:`self-center mt-1`,children:`Show older payments`})]}):(0,l.jsx)(`div`,{className:`flex items-center justify-center py-6 text-foreground/40`,children:(0,l.jsx)(n.yn,{className:`w-5 h-5 animate-spin text-accent`})})})]})})]})]})}var zs={from:`09:00`,to:`17:00`},Bs=e=>e.name.trim()||e.email.split(`@`)[0]||``,Vs=e=>n.I(e)?{state:`saved`,label:`Bookable`}:e.enabled?{state:`off`,label:`In progress`}:{state:`off`,label:`Turned off`},Hs=()=>`s_${Date.now().toString(36)}${Math.random().toString(36).slice(2,6)}`,Us=e=>({...n.F(Hs(),e.id,Bs(e),n.G()),createdAt:Date.now()}),Ws=`__new_payment__`,Gs=`w-[6.5rem] shrink-0`,Ks=`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 qs({day:e,windows:t,onChange:r}){let i=t.length>0,a=(e,n)=>r(t.map((t,r)=>r===e?{...t,...n}:t));return(0,l.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,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3 h-9`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-medium ${i?`text-foreground/80`:`text-foreground/40`}`,children:n.C[e]}),(0,l.jsx)(n.g,{enabled:i,onChange:e=>r(e?[zs]:[]),label:`${n.C[e]} — bookable`})]}),i&&(0,l.jsxs)(`div`,{className:`flex flex-col gap-2 min-w-0`,children:[t.map((i,o)=>(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`div`,{className:Gs,children:(0,l.jsx)(n.Et,{ariaLabel:`${n.C[e]} from${o?` (${o+1})`:``}`,value:i.from,options:n.T,onChange:e=>a(o,{from:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),(0,l.jsx)(`span`,{className:`w-3 text-center text-foreground/40 text-[13px] shrink-0 select-none`,children:`–`}),(0,l.jsx)(`div`,{className:Gs,children:(0,l.jsx)(n.Et,{ariaLabel:`${n.C[e]} to${o?` (${o+1})`:``}`,value:i.to,options:n.w,onChange:e=>a(o,{to:e}),className:`console-select`,compact:!0,portal:!0,direction:`auto`})}),t.length>1&&(0,l.jsx)(`button`,{type:`button`,title:`Remove these hours on ${n.C[e]}`,"aria-label":`Remove ${n.C[e]} hours ${o+1}`,onClick:()=>r(t.filter((e,t)=>t!==o)),className:Ks,children:(0,l.jsx)(n.Pt,{className:`w-3.5 h-3.5`})})]},o)),t.length<2&&(0,l.jsx)(`button`,{type:`button`,onClick:()=>r([...t,{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 Js({value:e,products:t,onChange:r,onCreate:i}){let[o,s]=(0,a.useState)(!1),[c,u]=(0,a.useState)(``),[d,f]=(0,a.useState)(``),[p,m]=(0,a.useState)(``),h=[...t.map(e=>({value:e.id,label:`${qr(e)} — ${Fr(e).map(e=>e.amount).filter(Boolean).join(` + `)||`no price yet`}`})),{value:Ws,label:`+ Create a one-time payment`}];return(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,l.jsx)(n.d,{label:`Add a payment for this meeting`,hint:t.find(t=>t.id===e)?`Taken on the booking page before the time is confirmed. Its price and receipts are on the Payments screen.`:`Optional. A one-time payment taken on the booking page before the time is confirmed.`,value:o?Ws:e,placeholder:`No payment`,options:h,onChange:e=>{if(e===`__new_payment__`){s(!0);return}s(!1),r(e)}}),o&&(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]/60 px-4 py-3.5 flex flex-col gap-3`,children:[(0,l.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-widest text-foreground/40`,children:`A new one-time payment`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`input`,{type:`text`,value:c,onChange:e=>u(e.target.value),placeholder:`A one-hour session`,"aria-label":`The payment's name`,className:`w-full h-11 px-4 rounded-[var(--input-radius,0.75rem)] border border-[var(--panel-border)] bg-[var(--panel-bg)] text-[14px] text-foreground outline-none transition-all duration-300 placeholder:text-foreground/35 hover:border-accent/40 focus:border-accent disabled:opacity-50 disabled:cursor-not-allowed console-field flex-1 min-w-0`}),(0,l.jsx)(`input`,{type:`text`,inputMode:`decimal`,value:d,onChange:e=>f(e.target.value),placeholder:`25`,"aria-label":`The payment's price`,className:`w-full h-11 px-4 rounded-[var(--input-radius,0.75rem)] border border-[var(--panel-border)] bg-[var(--panel-bg)] text-[14px] text-foreground outline-none transition-all duration-300 placeholder:text-foreground/35 hover:border-accent/40 focus:border-accent disabled:opacity-50 disabled:cursor-not-allowed console-field w-24 shrink-0 text-right`})]}),p&&(0,l.jsx)(`span`,{className:`text-[11.5px] font-semibold text-red-500 leading-snug px-1`,children:p}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(n.i,{icon:n.cn,onClick:async()=>{if(!c.trim()){m(`Give the payment a name.`);return}if(Ir(d)===null){m(`Just a number for the price, like 25.`);return}m(``);let e=await i(c.trim(),d.trim());if(e){m(e);return}s(!1),u(``),f(``)},children:`Create it`}),(0,l.jsx)(n.i,{onClick:()=>{s(!1),m(``)},children:`Never mind`})]})]})]})}function Ys({schedule:e,members:t,products:r,onChange:i,onCreatePayment:a}){let o=t=>i({...e,...t}),s=n.it(e),c=t.find(t=>t.id===e.memberId);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.h,{label:`What is it called?`,hint:`The kind of meeting — visitors read this on the booking page.`,value:e.name,onChange:e=>o({name:e}),placeholder:`A 1-hour session`}),(0,l.jsx)(n.m,{label:`A line or two about it`,hint:`Optional — what it is for, what to bring, what happens after.`,value:e.description,onChange:e=>o({description:e}),placeholder:`A first conversation about what you need and how I can help.`}),t.length>1&&(0,l.jsx)(n.d,{label:`Whose time is it?`,value:e.memberId,options:t.map(e=>({value:e.id,label:Bs(e)||e.email})),allowEmpty:!1,onChange:n=>{let r=t.find(e=>e.id===n);o({memberId:n,memberName:(!e.memberName.trim()||c&&e.memberName===Bs(c))&&r?Bs(r):e.memberName})}}),(0,l.jsx)(n.h,{label:`The name visitors see`,value:e.memberName,onChange:e=>o({memberName:e}),placeholder:`Anna`}),(0,l.jsx)(n._,{label:`Can be booked`,hint:`Off until the hours are complete and you turn this on.`,enabled:e.enabled,onChange:e=>o({enabled:e})}),(0,l.jsx)(n.t,{value:e.timeZone,onChange:e=>o({timeZone:e})}),(0,l.jsx)(n.d,{label:`How long is one booking?`,value:String(e.slotMinutes),options:n.k,allowEmpty:!1,onChange:e=>o({slotMinutes:Number(e)})}),(0,l.jsx)(n.r,{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 under any of their schedules is taken here too.`,children:(0,l.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:n.S.map(t=>(0,l.jsx)(qs,{day:t,windows:e.days[t]||[],onChange:n=>o({days:{...e.days,[t]:n}})},t))})}),(0,l.jsx)(n.d,{label:`How far ahead can people book?`,value:String(e.horizonDays),options:n.E,allowEmpty:!1,onChange:e=>o({horizonDays:Number(e)})}),(0,l.jsx)(n.d,{label:`How much notice do you need?`,value:String(e.noticeHours),options:n.D,allowEmpty:!1,onChange:e=>o({noticeHours:Number(e)})}),(0,l.jsx)(Js,{value:e.paymentId,products:r,onChange:e=>o({paymentId:e}),onCreate:async(e,t)=>{let n=await a(e,t);return n&&n.startsWith(`p_`)?(o({paymentId:n}),null):n||`The payment could not be made — make sure you are signed in as an admin and try again.`}}),(0,l.jsx)(n.r,{label:`Booking link`,hint:n.I(e)?`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 schedule is complete and turned on.`,children:(0,l.jsx)(ms,{title:n.st(e),path:n.H(e.id)})}),(0,l.jsx)(`div`,{className:`pt-1`,children:s?(0,l.jsx)(`span`,{className:n.a,children:s}):e.enabled?(0,l.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,l.jsx)(`span`,{className:n.a,children:`Complete — turn on Can be booked to offer it.`})})]})}function Xs({schedule:e,members:t,products:r,open:i,stale:o,error:s,onToggle:c,onChange:u,onRemove:d,onCreatePayment:f}){let p=Vs(e),[m,h]=(0,a.useState)(!1),g=n.st(e);return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] ${o?`opacity-60`:``}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2 pr-3`,children:[(0,l.jsxs)(`button`,{type:`button`,onClick:c,"aria-expanded":i,className:`flex-1 min-w-0 flex items-center justify-between gap-3 px-4 py-3 text-left cursor-pointer`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-semibold text-foreground/75 truncate`,children:n.ot(e)}),(0,l.jsxs)(`span`,{className:`flex items-center gap-2.5 shrink-0`,children:[o?(0,l.jsx)(`span`,{className:`${n.a} max-sm:hidden`,children:`No longer on the team`}):(0,l.jsx)(n.f,{state:p.state,label:p.label}),(0,l.jsx)(n.tr,{className:`w-3.5 h-3.5 text-foreground/40 shrink-0 transition-transform ${i?`rotate-180`:``}`})]})]}),(0,l.jsx)(n.i,{icon:n.Gt,tone:`danger`,compact:!0,title:`Remove ${g}`,onClick:()=>h(!0),children:`Remove`})]}),(0,l.jsx)(me,{isOpen:m,title:`Remove ${g}?`,message:o?`They are no longer on the team, so nobody can book them. Bookings already taken are kept.`:`Its booking link stops working and it leaves every page and form it was picked on. Bookings already taken are kept.`,confirmText:`Yes, remove`,cancelText:`Keep it`,onCancel:()=>h(!1),onConfirm:()=>{h(!1),d()}}),i&&(0,l.jsx)(`div`,{className:`px-4 pb-4 pt-4 border-t border-[var(--panel-border)]/60 flex flex-col gap-4`,children:(0,l.jsx)(Ys,{schedule:e,members:t,products:r,onChange:u,onCreatePayment:f})}),s&&(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-4 pb-3`,children:s})]})}var Zs=e=>({id:e.uid,name:String(e.displayName||``),email:String(e.email||``),role:`admin`});function Qs(){let[e,t]=(0,a.useState)([]);return(0,a.useEffect)(()=>{let e=(0,o.onSnapshot)((0,o.collection)(n.Sr,kr),e=>{let n=[];e.forEach(e=>{e.id!==`_settings`&&n.push(Vr(e.id,e.data()))}),t(n.filter(e=>e.kind===`once`).sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)))},()=>t([]));return()=>e()},[]),e}function $s(){let{user:e}=r.j(),{loading:i,members:s}=t.d(),{loading:c,schedules:d}=t.c(),f=Qs(),[p,m]=(0,a.useState)({}),[h,g]=(0,a.useState)([]),[_,v]=(0,a.useState)(null),[y,b]=(0,a.useState)({}),x=(0,a.useRef)(new Map),S=(0,a.useMemo)(()=>{let e=new Map(d.map(e=>[e.id,e]));for(let t of Object.values(p))e.set(t.id,t);for(let t of h)e.delete(t);return[...e.values()].sort((e,t)=>(e.createdAt||0)-(t.createdAt||0)||e.id.localeCompare(t.id))},[d,p,h]),C=e=>{let n=x.current.get(e.id);n&&clearTimeout(n),x.current.set(e.id,setTimeout(async()=>{x.current.delete(e.id);let n=await t.o(e);b(t=>{let r={...t};return n?r[e.id]=n:delete r[e.id],r})},600))},w=e=>{m(t=>({...t,[e.id]:e})),C(e)},T=e?s.find(t=>t.id===e.uid)||Zs(e):null,E=T&&!s.some(e=>e.id===T.id)?[T,...s]:s,D=()=>{if(!T)return;let e=Us(T);m(t=>({...t,[e.id]:e})),v(e.id),C(e)},O=async e=>{let n=x.current.get(e);n&&(clearTimeout(n),x.current.delete(e)),m(t=>{let n={...t};return delete n[e],n}),g(t=>[...t,e]),_===e&&v(null);let r=await t.a(e);r&&(g(t=>t.filter(t=>t!==e)),b(t=>({...t,[e]:r})))},k=async(e,t)=>{let r={...Pr(`p_${Date.now().toString(36)}`),kind:`once`,items:[{name:e,amount:t}]};try{let{id:e,...t}=r;return await(0,o.setDoc)((0,o.doc)(n.Sr,kr,e),t),e}catch(e){return console.error(`Could not make the payment`,e),null}},A=i||c,j=new Set(E.map(e=>e.id));return(0,l.jsx)(n.u,{icon:n.sr,title:`Your schedules`,description:`One per kind of meeting — a name, whose time it is, the hours, the length, a payment if you like, and a link to send.`,actions:A?void 0:(0,l.jsx)(n.i,{icon:n.cn,title:`Add a schedule`,onClick:D,children:`Add a schedule`}),children:(0,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:A?(0,l.jsx)(`p`,{className:n.a,children:`Loading your schedules…`}):S.length===0?(0,l.jsxs)(`div`,{className:`flex flex-col items-start gap-3 px-1`,children:[(0,l.jsxs)(`p`,{className:n.a,children:[`No schedule yet. A schedule is one kind of meeting somebody offers — a 1-hour session, a 2-hour workshop — with its own hours, length and link. Everyone marked Internal or Admin on the`,` `,(0,l.jsx)(u.Link,{to:`/users`,className:`text-accent font-bold hover:underline`,children:`Users screen`}),` can have as many as you like; a person's schedules share their availability.`]}),(0,l.jsx)(n.i,{icon:n.cn,title:`Add a schedule`,onClick:D,children:`Add a schedule`})]}):S.map(e=>(0,l.jsx)(Xs,{schedule:e,members:E,products:f,stale:!j.has(e.memberId),open:_===e.id,error:y[e.id],onToggle:()=>v(_===e.id?null:e.id),onChange:w,onRemove:()=>O(e.id),onCreatePayment:k},e.id))})})}function ec({booking:e,zone:t,onCancel:r}){let[i,o]=(0,a.useState)(!1),[s,c]=(0,a.useState)(!1);return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)]`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-3`,children:[(0,l.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col gap-0.5`,children:[(0,l.jsxs)(`span`,{className:`text-[13px] font-semibold text-foreground/80 truncate`,children:[n.ft(e,t),e.memberName?` with ${e.memberName}`:``,e.scheduleName?` · ${e.scheduleName}`:``]}),(0,l.jsxs)(`span`,{className:`text-[12px] font-medium text-foreground/50 truncate`,children:[e.name||`Someone`,e.email&&(0,l.jsxs)(`span`,{className:`max-sm:hidden`,children:[` · `,e.email]})]})]}),(0,l.jsx)(n.i,{icon:n.Pt,tone:`danger`,compact:!0,title:`Cancel this booking`,onClick:()=>o(!0),children:`Cancel`})]}),(0,l.jsx)(me,{isOpen:i,title:`Cancel this booking?`,message:`The time becomes free again.`,confirmText:`Yes, cancel`,cancelText:`Keep it`,isProcessing:s,onCancel:()=>o(!1),onConfirm:async()=>{c(!0),await r(),c(!1),o(!1)}})]})}function tc(){let e=n.G(),{loading:r,bookings:i,error:o}=t.s(),[s,c]=(0,a.useState)(``);return(0,l.jsx)(n.u,{icon:n.cr,title:`Bookings`,description:`Shown in your time — ${n.ht(e)}. Each person also sees their own on My calendar.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[r?(0,l.jsx)(`p`,{className:n.a,children:`Loading bookings…`}):o?(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:o}):i.length===0?(0,l.jsx)(`p`,{className:`${n.a} px-1`,children:`Nothing booked yet. Bookings appear here the moment someone takes a time — and in your Inbox, like any form entry.`}):i.map(n=>(0,l.jsx)(ec,{booking:n,zone:e,onCancel:async()=>{c(``);let e=await t.n(n.id);e&&c(e)}},n.id)),!!s&&(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:s})]})})}function nc(){let{userRole:e}=r.j();return e===`admin`?(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`Schedule`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/schedule`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsx)(`div`,{className:`flex flex-col gap-1.5 px-1`,children:(0,l.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/60 leading-relaxed`,children:`The kinds of meeting you and your team can be booked for, each in its person's own time zone. Every schedule has a link to send; you can also pick it on a page under Booking on this page, or add it to a form as a Pick-a-time question.`})}),(0,l.jsx)($s,{}),(0,l.jsx)(tc,{})]})})]})]}):(0,l.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,l.jsx)(Sr,{})})}var rc=[`M`,`T`,`W`,`T`,`F`,`S`,`S`],ic=e=>e.slice(0,7),ac=e=>{let[t,n]=e.split(`-`).map(Number);return new Intl.DateTimeFormat(void 0,{month:`long`,year:`numeric`,timeZone:`UTC`}).format(new Date(Date.UTC(t,n-1,1)))},oc=(e,t)=>{let[n,r]=e.split(`-`).map(Number),i=new Date(Date.UTC(n,r-1+t,1));return`${i.getUTCFullYear()}-${String(i.getUTCMonth()+1).padStart(2,`0`)}`};function sc(e,t){let r=new Map;for(let i of e){let e=n._t(new Date(i.start),t).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 cc(e,t){return!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`}}function lc({booking:e,zone:t,paid:r,onCancel:i}){let[o,s]=(0,a.useState)(!1),[c,u]=(0,a.useState)(!1),d=cc(e,r),f=e.end<new Date().toISOString();return(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] ${f?`opacity-60`:``}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-3`,children:[(0,l.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col gap-0.5`,children:[(0,l.jsxs)(`span`,{className:`text-[13px] font-semibold text-foreground/80 truncate`,children:[n.q(new Date(e.start),t),`–`,n.q(new Date(e.end),t),e.scheduleName?` · ${e.scheduleName}`:``]}),(0,l.jsxs)(`span`,{className:`text-[12px] font-medium text-foreground/50 truncate`,children:[e.name||`Someone`,e.email&&(0,l.jsxs)(`span`,{className:`max-sm:hidden`,children:[` · `,e.email]}),e.answers.note&&(0,l.jsxs)(`span`,{className:`max-sm:hidden`,children:[` · `,e.answers.note]})]})]}),d&&(0,l.jsx)(n.f,{state:d.state,label:d.label}),!f&&(0,l.jsx)(n.i,{icon:n.Pt,tone:`danger`,compact:!0,title:`Cancel this booking`,onClick:()=>s(!0),children:`Cancel`})]}),(0,l.jsx)(me,{isOpen:o,title:`Cancel this booking?`,message:`The time becomes free again on every schedule of yours.`,confirmText:`Yes, cancel`,cancelText:`Keep it`,isProcessing:c,onCancel:()=>s(!1),onConfirm:async()=>{u(!0),await i(),u(!1),s(!1)}})]})}function uc({bookings:e,zone:r,paid:i,onCancel:o,now:s}){let c=n._t(s?s():new Date,r).dateKey,u=(0,a.useMemo)(()=>sc(e,r),[e,r]),[d,f]=(0,a.useState)(ic(c)),[p,m]=(0,a.useState)(c),h=t.m(d),g=u.get(p)||[],_=new Intl.DateTimeFormat(void 0,{timeZone:`UTC`,weekday:`long`,day:`numeric`,month:`long`}).format(new Date(`${p}T00:00:00Z`));return(0,l.jsxs)(`div`,{className:`flex flex-col md:flex-row gap-5 md:gap-8 w-full`,children:[(0,l.jsxs)(`div`,{className:`flex-1 min-w-0 flex flex-col gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,l.jsx)(`h4`,{className:`text-[15px] sm:text-[17px] font-bold text-foreground tracking-tight truncate`,children:ac(d)}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,l.jsx)(`button`,{type:`button`,onClick:()=>{f(ic(c)),m(c)},className:`px-3 py-1.5 text-[12.5px] font-bold border border-[var(--panel-border)] rounded-xl mr-1 hover:bg-foreground/5 transition-colors cursor-pointer`,children:`Today`}),(0,l.jsx)(`button`,{type:`button`,"aria-label":`Previous month`,onClick:()=>f(e=>oc(e,-1)),className:`p-1.5 rounded-xl text-foreground/50 hover:text-foreground hover:bg-foreground/5 transition-colors border border-transparent hover:border-[var(--panel-border)] cursor-pointer`,children:(0,l.jsx)(n.er,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{type:`button`,"aria-label":`Next month`,onClick:()=>f(e=>oc(e,1)),className:`p-1.5 rounded-xl text-foreground/50 hover:text-foreground hover:bg-foreground/5 transition-colors border border-transparent hover:border-[var(--panel-border)] cursor-pointer`,children:(0,l.jsx)(n.$n,{className:`w-4 h-4`})})]})]}),(0,l.jsxs)(`div`,{className:`grid grid-cols-7 gap-1`,role:`grid`,"aria-label":ac(d),children:[rc.map((e,t)=>(0,l.jsx)(`div`,{className:`text-center text-[11px] font-bold uppercase tracking-wider text-foreground/40 py-1`,children:e},t)),h.map((e,t)=>{if(!e)return(0,l.jsx)(`div`,{"aria-hidden":!0},`blank-${t}`);let n=u.get(e)?.length||0,r=e===p,i=e===c;return(0,l.jsxs)(`button`,{type:`button`,role:`gridcell`,"aria-label":`${e}${n?`, ${n} booked`:``}`,"aria-selected":r,onClick:()=>m(e),className:`relative flex flex-col items-center justify-center aspect-square rounded-xl text-[14px] font-semibold transition-all cursor-pointer ${r?`bg-accent text-[var(--button-fg,#fff)] shadow-lg shadow-accent/20`:n?`text-foreground hover:bg-foreground/[0.06]`:`text-foreground/40 hover:bg-foreground/[0.04]`} ${i&&!r?`ring-1 ring-accent/50`:``}`,children:[Number(e.slice(8,10)),n>0&&(0,l.jsx)(`span`,{"aria-hidden":!0,className:`absolute bottom-1 text-[9px] font-bold leading-none px-1 rounded-full ${r?`bg-[var(--button-fg,#fff)]/20`:`bg-accent/15 text-accent`}`,children:n})]},e)})]})]}),(0,l.jsxs)(`div`,{className:`md:w-[320px] shrink-0 flex flex-col gap-2`,children:[(0,l.jsx)(`p`,{className:`text-[13px] font-bold text-foreground`,children:_}),g.length===0?(0,l.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50`,children:`Nothing booked on this day.`}):g.map(e=>(0,l.jsx)(lc,{booking:e,zone:r,paid:i[e.paymentSession],onCancel:()=>o(e.id)},e.id))]})]})}function dc(){let{user:e,userRole:i}=r.j(),o=e?.uid||``,s=n.G(),{schedules:c}=t.l(r.I(i)?o:null),{loading:d,bookings:f,error:p}=t.s({members:o?[o]:[],includePast:!0}),[m,h]=(0,a.useState)({}),[g,_]=(0,a.useState)(``);return(0,a.useEffect)(()=>{let e=f.filter(e=>e.paymentSession&&m[e.paymentSession]===void 0);if(!e.length)return;let t=!1;return Promise.all(e.map(async e=>[e.paymentSession,(await r.x(e.paymentSession)).paid])).then(e=>{t||h(t=>({...t,...Object.fromEntries(e)}))}),()=>{t=!0}},[f,m]),r.I(i)?(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`My calendar`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/my-calendar`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsxs)(`p`,{className:`text-[13px] font-medium text-foreground/60 leading-relaxed px-1`,children:[`Every booking made with you, under every schedule of yours — shown in your time, `,n.ht(s),`. A time booked on one schedule is taken on all of them.`]}),(0,l.jsxs)(n.u,{icon:n.or,title:`Bookings`,description:`Pick a day to see who is coming.`,children:[d?(0,l.jsx)(`p`,{className:n.a,children:`Loading your bookings…`}):p?(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1`,children:p}):(0,l.jsx)(uc,{bookings:f,zone:s,paid:m,onCancel:async e=>{_(``);let n=await t.n(e);n&&_(n)}}),!!g&&(0,l.jsx)(`p`,{className:`text-[12px] font-semibold text-red-500 px-1 mt-3`,children:g})]}),c.length>0&&(0,l.jsx)(n.u,{icon:n.Un,title:`Your booking links`,description:`Send one to anyone — they pick a free time and it lands here.`,children:(0,l.jsxs)(`div`,{className:`flex flex-col gap-2`,children:[c.map(e=>(0,l.jsx)(ms,{title:n.st(e),path:n.H(e.id)},e.id)),i===`admin`&&(0,l.jsxs)(`p`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug px-1`,children:[`Change a schedule's hours, length or payment on the `,(0,l.jsx)(u.Link,{to:`/schedule`,className:`text-accent font-bold hover:underline`,children:`Schedule screen`}),`.`]})]})})]})})]})]}):(0,l.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,l.jsx)(Sr,{})})}var fc=/^[^\s@,;]+@[^\s@,;.]+(\.[^\s@,;.]+)*\.[a-z]{2,}$/i,pc=`booking`;function mc(e){if(!e||e.kind!==`once`)return null;let t=Fr(e),n=t.reduce((e,t)=>e+(Ir(t.amount)||0),0),r=e.name.trim()||t.map(e=>e.name.trim()).filter(Boolean).join(` and `)||qr(e);return n>0?{amount:n,name:r}:null}var hc=(e,t=`usd`)=>{try{return new Intl.NumberFormat(void 0,{style:`currency`,currency:t.toUpperCase()}).format(e)}catch{return`${e} ${t.toUpperCase()}`}};function gc(e){let[t,r]=(0,a.useState)({id:``,product:null});return(0,a.useEffect)(()=>{if(!e)return;let t=!1;return(0,o.getDoc)((0,o.doc)(n.Sr,kr,e)).then(n=>{t||r({id:e,product:n.exists()?Vr(n.id,n.data()):null})}).catch(()=>{t||r({id:e,product:null})}),()=>{t=!0}},[e]),e?t.id===e?{loading:!1,product:t.product}:{loading:!0,product:null}:{loading:!1,product:null}}function _c({children:e}){return(0,l.jsx)(`main`,{className:`flex-1 w-full max-w-5xl mx-auto px-4 pt-2 pb-16 md:pt-4 z-10 flex flex-col`,children:(0,l.jsx)(n.kt.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 vc({icon:e,title:t,children:n}){return(0,l.jsxs)(`div`,{className:`flex flex-col items-center text-center py-8 gap-4`,children:[(0,l.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,l.jsx)(e,{className:`w-7 h-7 text-accent`})}),(0,l.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold text-foreground tracking-tight`,children:t}),n&&(0,l.jsx)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed max-w-md`,children:n}),(0,l.jsx)(u.Link,{to:`/`,className:`text-[13px] font-bold text-accent hover:underline mt-2`,children:`Back to the site`})]})}function yc({sessionId:e,schedule:t}){let[i,o]=(0,a.useState)(null);if((0,a.useEffect)(()=>{let t=!1;return r.x(e).then(e=>{t||o(e)}),()=>{t=!0}},[e]),!i)return(0,l.jsx)(vc,{icon:n.yn,title:`Confirming your payment…`,children:`One moment — checking with the payment provider.`});let s=i.metadata?.when||``;return i.paid?(0,l.jsx)(vc,{icon:n.cr,title:`Booked and paid`,children:(0,l.jsxs)(`p`,{children:[s?`${s} — `:``,n.st(t),`.`,i.customerEmail?` A receipt is on its way to ${i.customerEmail}.`:``]})}):(0,l.jsx)(vc,{icon:n.Kn,title:`Not confirmed yet`,children:(0,l.jsx)(`p`,{children:i.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 bc(){let{id:e=``}=(0,u.useParams)(),[i]=(0,u.useSearchParams)(),{activeConfig:s}=t.y(),{loading:c,schedules:d}=t.c(),f=d.find(t=>t.id===e)||null,{loading:p,product:m}=gc(f?.paymentId||``),h=mc(m),g=r.D(),[_,v]=(0,a.useState)(()=>n.G()),[y]=(0,a.useState)(()=>new Date),b=t.u(f?[f.memberId]:[],y),x=(0,a.useMemo)(()=>f&&n.I(f)?[f]:[],[f]),[S,C]=(0,a.useState)(null),[w,T]=(0,a.useState)(()=>n.xr.currentUser?.displayName||``),[E,D]=(0,a.useState)(()=>n.xr.currentUser?.email||``),[O,k]=(0,a.useState)(``),[A,j]=(0,a.useState)({}),[M,N]=(0,a.useState)(!1),[P,F]=(0,a.useState)(``),[I,L]=(0,a.useState)(``),R=i.get(`session_id`)||``,z=i.get(`cancelled`)===`1`;if(c)return(0,l.jsx)(_c,{children:(0,l.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-16 text-foreground/50`,children:[(0,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin text-accent`}),(0,l.jsx)(`span`,{className:`text-[13px] font-medium`,children:`Loading…`})]})});if(!f)return(0,l.jsx)(_c,{children:(0,l.jsx)(vc,{icon:n.ar,title:`This booking link is no longer open`,children:`It may have been taken down. Ask whoever sent it for a new one.`})});if(R)return(0,l.jsx)(_c,{children:(0,l.jsx)(yc,{sessionId:R,schedule:f})});if(I)return(0,l.jsx)(_c,{children:(0,l.jsx)(vc,{icon:n.cr,title:`Booked`,children:(0,l.jsxs)(`p`,{children:[I,`. `,E?`We have your email as ${E}.`:``]})})});if(!n.I(f))return(0,l.jsx)(_c,{children:(0,l.jsx)(vc,{icon:n.ar,title:n.st(f),children:`This is not taking bookings at the moment.`})});let B=!!f.paymentId&&!p&&(!h||!g.loading&&!g.configured);return(0,l.jsxs)(_c,{children:[z&&(0,l.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,l.jsxs)(`div`,{className:`flex flex-col gap-1.5 mb-6`,children:[s?.appName&&(0,l.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-[0.2em] text-foreground/40`,children:s.appName}),(0,l.jsx)(`h1`,{className:`text-2xl sm:text-3xl md:text-4xl font-extrabold text-foreground tracking-tight`,children:f.name.trim()||`Book a time`}),(0,l.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-4 gap-y-1 text-[13px] font-semibold text-foreground/60`,children:[(0,l.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,l.jsx)(n.Bt,{className:`w-3.5 h-3.5 text-accent`}),`with `,f.memberName]}),(0,l.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,l.jsx)(n.Kn,{className:`w-3.5 h-3.5 text-accent`}),n.pt(f.slotMinutes)]}),h&&(0,l.jsx)(`span`,{className:`inline-flex items-center gap-1.5 text-foreground`,children:hc(h.amount)})]}),f.description.trim()&&(0,l.jsx)(`p`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed mt-2 max-w-2xl whitespace-pre-line`,children:f.description.trim()})]}),B?(0,l.jsx)(`p`,{className:`text-[14px] font-medium text-foreground/60`,children:`This booking cannot be paid for right now — please try again later.`}):S?(0,l.jsxs)(`div`,{className:`flex flex-col gap-5 max-w-[520px]`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-xl px-4 py-3 glass-panel`,style:{borderRadius:`var(--input-radius, 0.75rem)`},children:[(0,l.jsx)(`span`,{className:`text-[14px] font-semibold text-foreground truncate`,children:n.U(S,f.memberName,_)}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>C(null),className:`text-[12.5px] font-bold text-accent hover:underline shrink-0 cursor-pointer`,children:`Change`})]}),(0,l.jsx)(t.g,{label:`Your name`,value:w,onChange:e=>T(e.target.value),error:A.name,placeholder:`Jane Doe`}),(0,l.jsx)(t.g,{label:`Your email`,type:`email`,value:E,onChange:e=>D(e.target.value),error:A.email,placeholder:`jane@example.com`}),(0,l.jsxs)(`div`,{className:`flex flex-col w-full`,children:[(0,l.jsxs)(`label`,{className:`text-[13px] font-medium text-foreground/50 select-none mb-1.5 ml-1`,children:[`Anything we should know? `,(0,l.jsx)(`span`,{className:`text-foreground/35`,children:`(optional)`})]}),(0,l.jsx)(`textarea`,{rows:3,value:O,onChange:e=>k(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 glass-panel min-h-[90px] resize-none`})]}),P&&(0,l.jsx)(`p`,{role:`alert`,className:`text-[13px] font-semibold text-red-500`,children:P}),(0,l.jsx)(t.h,{variant:`primary`,onClick:async()=>{if(!S||M)return;let e={};if(w.trim()||(e.name=`Your name, please.`),fc.test(E.trim())||(e.email=`That does not look like an email address — check for a typo, e.g. jane@example.com`),j(e),Object.keys(e).length)return;N(!0),F(``);let i=n.U(S,f.memberName,_),a=await t.r(S);if(a){F(a),C(null),N(!1);return}let s=``;try{let e=n.xr.currentUser;s=(await(0,o.addDoc)((0,o.collection)(n.Sr,`user_submissions`),{name:w.trim(),email:E.trim(),...O.trim()?{note:O.trim()}:{},...n.R(`time`,S,f.memberName,_),schedule:n.st(f),...e?{uid:e.uid,submitterName:e.displayName||``,submitterEmail:e.email||``,submitterAvatar:e.photoURL||``}:{uid:`guest`},formId:pc,submittedAt:(0,o.serverTimestamp)()})).id}catch(e){console.error(`Could not save the booking entry`,e),await t.i(S),F(`The booking could not be saved — check your connection and try again.`),N(!1);return}let c=null;if(h){let e=await r.S({amount:h.amount,productName:`${n.st(f)} — ${i}`,metadata:{bookingId:n.dt(S.memberId,S.start),scheduleId:f.id,page:n.H(f.id),when:i,emailReceipt:m?.emailReceipt===!1?`no`:`yes`,notifyOwner:m?.notifyOwner===!1?`no`:`yes`},successPath:n.H(f.id),cancelPath:`${n.H(f.id)}?cancelled=1`});if(typeof e==`string`){await t.i(S),F(e),N(!1);return}c=e}let l=await t.f(S,{memberName:f.memberName,scheduleId:f.id,scheduleName:f.name,paymentId:f.paymentId,paymentSession:c?.sessionId||``,timeZone:_,name:w.trim(),email:E.trim(),answers:O.trim()?{note:O.trim()}:{},formId:pc,entryId:s});if(l&&console.warn(l),c){r.b.goTo(c.url);return}ji(`heads_up`,{title:`New booking`,summary:`${w.trim()} booked ${n.st(f)} — ${i}`,details:{Name:w.trim(),Email:E.trim(),When:i,...O.trim()?{Note:O.trim()}:{}}}).catch(()=>{}),L(i),N(!1)},disabled:M||p,className:`w-full py-3 text-[14px] font-bold`,children:M?h?`Opening checkout…`:`Booking…`:h?`Book and pay ${hc(h.amount)}`:`Confirm booking`})]}):(0,l.jsxs)(l.Fragment,{children:[P&&(0,l.jsx)(`p`,{role:`alert`,className:`mb-3 text-[13px] font-semibold text-red-500`,children:P}),(0,l.jsx)(t.p,{members:x,value:S,onChange:C,taken:b,timeZone:_,onTimeZone:v})]})]})}function xc({children:e,className:n,variant:i=`primary`,pendingLabel:o=`Opening checkout…`,...s}){let{loading:c,configured:u}=r.D(),[d,f]=(0,a.useState)(!1),[p,m]=(0,a.useState)(null);return c||!u?null:(0,l.jsxs)(`span`,{className:`inline-flex flex-col items-stretch gap-2`,children:[(0,l.jsx)(t.h,{variant:i,className:n,onClick:async()=>{if(d)return;f(!0),m(null);let e=await r.T(s);e&&(m(e),f(!1))},disabled:d,children:d?o:e??`Pay`}),p&&(0,l.jsx)(`span`,{role:`alert`,className:`text-[13px] font-semibold text-red-400 leading-snug`,children:p})]})}function Sc(){let{id:e=``}=(0,u.useParams)(),{activeConfig:i}=t.y(),s=r.D(),[c,d]=(0,a.useState)({loading:!0,product:null});(0,a.useEffect)(()=>{let t=!1;return(0,o.getDoc)((0,o.doc)(n.Sr,kr,e)).then(e=>{t||d({loading:!1,product:e.exists()?Vr(e.id,e.data()):null})}).catch(()=>{t||d({loading:!1,product:null})}),()=>{t=!0}},[e]);let f=c.product,p=f?.customPath.trim()||``;if(p)return(0,l.jsx)(u.Navigate,{to:p.startsWith(`/`)?p:`/${p}`,replace:!0});let m=f?Fr(f).filter(e=>Ir(e.amount)):[],h=f?.name.trim()||m[0]?.name.trim()||`Pay`;return(0,l.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,l.jsx)(n.kt.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:c.loading?(0,l.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-16 text-foreground/50`,children:[(0,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin text-accent`}),(0,l.jsx)(`span`,{className:`text-[13px] font-medium`,children:`Loading…`})]}):!f||f.kind!==`once`||!m.length?(0,l.jsxs)(`div`,{className:`flex flex-col items-center text-center py-8 gap-4`,children:[(0,l.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,l.jsx)(n.Zt,{className:`w-7 h-7 text-accent`})}),(0,l.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold text-foreground tracking-tight`,children:`This payment link is no longer open`}),(0,l.jsx)(`p`,{className:`text-[14px] text-foreground/60 max-w-md`,children:`Ask whoever sent it for a new one.`}),(0,l.jsx)(u.Link,{to:`/`,className:`text-[13px] font-bold text-accent hover:underline mt-2`,children:`Back to the site`})]}):(0,l.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[i?.appName&&(0,l.jsx)(`span`,{className:`text-[11px] font-bold uppercase tracking-[0.2em] text-foreground/40`,children:i.appName}),(0,l.jsx)(`h1`,{className:`text-2xl sm:text-3xl md:text-4xl font-extrabold text-foreground tracking-tight`,children:h}),f.description.trim()&&(0,l.jsx)(`p`,{className:`text-[14px] md:text-[15px] text-foreground/60 leading-relaxed mt-1 max-w-2xl whitespace-pre-line`,children:f.description.trim()})]}),!s.loading&&!s.configured&&(0,l.jsx)(`p`,{className:`text-[14px] font-medium text-foreground/60`,children:`Payments are not open right now — please try again later.`}),(0,l.jsx)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60`,children:m.map((e,t)=>(0,l.jsxs)(`div`,{className:`flex items-center justify-between gap-4 px-4 py-3.5`,children:[(0,l.jsxs)(`div`,{className:`min-w-0 flex flex-col`,children:[(0,l.jsx)(`span`,{className:`text-[15px] font-semibold text-foreground truncate`,children:e.name.trim()||h}),(0,l.jsx)(`span`,{className:`text-[13px] font-medium text-foreground/50`,children:hc(Ir(e.amount)||0)})]}),(0,l.jsxs)(xc,{amount:Ir(e.amount)||0,productName:e.name.trim()||h,metadata:{productId:f.id,page:n.et(f.id),emailReceipt:f.emailReceipt?`yes`:`no`,notifyOwner:f.notifyOwner?`yes`:`no`},successPath:`/payment-complete`,cancelPath:n.et(f.id),className:`px-5 py-2.5 text-[14px] font-bold`,children:[`Pay `,hc(Ir(e.amount)||0)]})]},t))})]})})})}var{collection:Cc,doc:wc}=ks.email,Tc=(e,t)=>{let n=String(e||``).trim().toLowerCase(),r=String(t||``).trim().toLowerCase();return!!n&&n===r};function Ec(){let[e,t]=(0,a.useState)({loading:!0,testedFrom:null});return(0,a.useEffect)(()=>(0,o.onSnapshot)((0,o.doc)(n.Sr,Cc,wc),e=>{let n=e.exists()?e.data()?.testedFrom:null;t({loading:!1,testedFrom:typeof n==`string`&&n.trim()?n:null})},()=>t({loading:!1,testedFrom:null})),[]),{loading:e.loading,testedFrom:e.testedFrom,mark:async e=>{if(e.trim()){t({loading:!1,testedFrom:e});try{await(0,o.setDoc)((0,o.doc)(n.Sr,Cc,wc),{testedFrom:e},{merge:!0})}catch(e){console.error(`Could not remember the test send`,e)}}}}}var Dc=e=>[{title:`Hear about what happens`,body:`A booking, a form entry, a new member — at your address the moment it happens.`,icon:n.lr,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:n.gn,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:n.on,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:n.tn,where:{path:`/pages`,label:`Pages screen`}}],Oc=e=>String(e||``).toLowerCase().endsWith(`@resend.dev`),kc=e=>String(e||``).split(`@`)[1]||``,Ac=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 jc({children:e,tone:t=`quiet`}){return(0,l.jsx)(`p`,{className:`text-[12.5px] font-medium leading-relaxed px-1 ${t===`error`?`text-red-500`:`text-foreground/50`}`,children:e})}function Mc({from:e}){return(0,l.jsx)(`div`,{className:`flex flex-col divide-y divide-[var(--panel-border)]/60 rounded-2xl border border-[var(--panel-border)]/60`,children:Dc(e).map(e=>{let t=e.icon;return(0,l.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,l.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,l.jsx)(t,{className:`w-4 h-4`})}),(0,l.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,l.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,l.jsxs)(u.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,l.jsx)(n.pr,{className:`w-3 h-3`})]})]},e.title)})})}function Nc(){let[e,t]=(0,a.useState)(null),[i,o]=(0,a.useState)(``),s=js(`email`),[c,d]=(0,a.useState)(``),f=Ec();(0,a.useEffect)(()=>{let e=!1;return fetch(`/api/email/status`).then(e=>e.json()).then(n=>{e||t({configured:!!n?.configured,from:n?.from??null,adminCount:Number(n?.adminCount)||0})}).catch(()=>{e||o(`The server could not be reached.`)}),()=>{e=!0}},[]);let p=!!(e&&!e.configured),m=Oc(e?.from),h=Ac(s.on),g=!f.loading&&Tc(f.testedFrom,e?.from);return(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`Email`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/email`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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&&!i?(0,l.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,l.jsx)(n.yn,{className:`w-6 h-6 animate-spin text-accent`})}):p?(0,l.jsxs)(n.u,{icon:n.hn,title:`Connect email`,description:`This app is not sending email yet.`,collapsible:!1,children:[(0,l.jsx)(jc,{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,l.jsxs)(u.Link,{to:`/setup`,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]`,children:[`Set up email`,(0,l.jsx)(n.pr,{className:`w-3.5 h-3.5`})]})]}):(0,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,l.jsx)(n.p,{icon:n.sn,title:`Send email`,description:h.description,chip:h.chip,enabled:s.loading?null:s.on,onChange:async e=>d(await s.set(e)||``),children:c?(0,l.jsx)(jc,{tone:`error`,children:c}):null}),(0,l.jsx)(n.u,{icon:n.gn,title:`Connection`,description:g&&!i?`Mail goes out as ${e?.from}.`:`Whether this app can send email right now.`,defaultOpen:!g||!e?.adminCount,actions:i?(0,l.jsx)(n.f,{state:`error`,label:`Unreachable`}):(0,l.jsx)(n.f,{state:`saved`,label:`Connected`}),children:i?(0,l.jsx)(jc,{tone:`error`,children:i}):g?(0,l.jsxs)(`div`,{className:`flex items-center gap-2.5 px-1 flex-wrap`,children:[(0,l.jsx)(n.f,{state:e?.adminCount?`saved`:`off`,label:e?.adminCount?`Your mail reaches ${e.adminCount} address${e.adminCount===1?``:`es`}`:`No address for your mail`}),!e?.adminCount&&(0,l.jsxs)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Sale alerts and form alerts have nowhere to go —`,` `,(0,l.jsx)(u.Link,{to:`/setup`,className:`text-accent font-bold hover:underline`,children:`add ADMIN_EMAILS on the setup page`}),`.`]})]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)(jc,{children:[`Mail goes out as `,(0,l.jsx)(`span`,{className:`font-bold text-foreground/70`,children:e?.from}),`.`,m?` That is Resend’s shared practice address — fine for testing, but it often lands in spam. Before launch, verify your own domain in Resend and add EMAIL_FROM on the setup page.`:` That only works if ${kc(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.`]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2.5 px-1 flex-wrap`,children:[(0,l.jsx)(n.f,{state:e?.adminCount?`saved`:`off`,label:e?.adminCount?`Your mail reaches ${e.adminCount} address${e.adminCount===1?``:`es`}`:`No address for your mail`}),!e?.adminCount&&(0,l.jsxs)(`span`,{className:`text-[11px] sm:text-[11.5px] text-foreground/40 font-medium leading-snug`,children:[`Sale alerts and form alerts have nowhere to go —`,` `,(0,l.jsx)(u.Link,{to:`/setup`,className:`text-accent font-bold hover:underline`,children:`add ADMIN_EMAILS on the setup page`}),`.`]})]}),(0,l.jsx)(`div`,{className:`px-1`,children:(0,l.jsx)(r.c,{onSent:t=>f.mark(t||e?.from||``),trailing:(0,l.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,l.jsx)(n.Rn,{className:`w-3 h-3`})]})})})]})}),(0,l.jsx)(n.u,{icon:n.Xt,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,l.jsx)(Mc,{from:e?.from||``})})]})})]})]})}var Pc=`src/your-ai-workflow-firebase-os`;function Fc(){let e=new Set;for(let[t,n]of S()){let r=n?.config?.route,i=typeof r==`string`&&r.trim()?r.startsWith(`/`)?r:`/`+r:`/`+t.toLowerCase();e.add(i)}return[...e].sort()}var Ic=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``);function Lc(e){let t=e?.contentKey||e?.tabName||e?.pageName||e?.pageId||`Page`;return`${Pc}/microcomponents/${Ic(String(t))||`Page`}Content.tsx`}function Rc(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 ${Pc}/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. ${Pc}/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(`
|
|
27
|
+
`)}function zc(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 ${Pc}/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. ${Pc}/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(`
|
|
28
|
+
`)}function Bc({config:e,customContent:i}){let{config:o}=t.y(),{userRole:s}=r.j();return(0,a.useEffect)(()=>{document.title=e.pageName||e.pageTitle||o.appName||`Your AI Firebase`},[e.pageName,e.pageTitle,o.appName]),(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-4 md:mb-6 flex items-center gap-3`,children:[(0,l.jsx)(Ne,{}),(0,l.jsxs)(`div`,{className:`min-w-0`,children:[(0,l.jsx)(r.y,{children:e.pageTitle||e.pageName||`New Page`}),e.route&&(0,l.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,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})]}),(0,l.jsx)(n.kt.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:i?(0,l.jsx)(`div`,{className:`fbos-content-slot flex-1 p-4 md:p-8`,children:(0,l.jsx)(i,{config:e})}):e.form?(0,l.jsx)(`div`,{className:`fbos-content-slot flex-1 flex flex-col items-center justify-start p-4 md:p-8`,children:(0,l.jsx)(t.t,{isInline:!0,formId:e.form})}):(0,l.jsxs)(`div`,{className:`flex-1 flex flex-col items-center justify-center m-4 md:m-8 gap-6`,children:[(0,l.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,l.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/70`,children:`This page is empty`}),(0,l.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.`})]}),r.L(s)&&(0,l.jsx)(`div`,{className:`w-full max-w-lg`,children:(0,l.jsx)(r.g,{compact:!0,title:`Already asked, and it is still empty? Paste this`,prompt:Rc(e.route||`/`,Lc(e))})})]})})]})}function Vc({config:e,customContent:i}){let{user:s}=r.j(),{config:u}=t.y(),[f,p]=(0,a.useState)([]),[m,h]=(0,a.useState)(!0),[g,_]=(0,a.useState)(!1),[v,y]=(0,a.useState)(``),[b,x]=(0,a.useState)(``),[S,C]=(0,a.useState)(!1),[w,T]=(0,a.useState)(null),E=(0,a.useRef)(null),[D,O]=(0,a.useState)(!1),[k,A]=(0,a.useState)(null),[j,M]=(0,a.useState)(null),N=e=>{if(M(e),e){let t=e.fileType||``;I(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},P=j,[F,I]=(0,a.useState)(!0),[L,R]=(0,a.useState)(!1),[z,B]=(0,a.useState)(null),[V,H]=(0,a.useState)(``),[U,ee]=(0,a.useState)(``),[W,G]=(0,a.useState)([]),K=(0,a.useRef)(null),q=`user_${(e.tabName||e.pageId||`user_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`)}_records`;(0,a.useEffect)(()=>{document.title=e.tabTitle||e.tabName||u.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,u.appName]),(0,a.useEffect)(()=>{if(!s)return;try{let e=localStorage.getItem(`fbos_records_${q}`);e?(p(JSON.parse(e)),h(!1)):h(!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}}),t=(0,o.onSnapshot)((0,o.query)((0,o.collection)(n.Sr,q),(0,o.where)(`uid`,`==`,s.uid),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),p(n),h(!1),localStorage.setItem(`fbos_records_${q}`,JSON.stringify(n))},e=>{console.error(`Error fetching records:`,e),h(!1)});return()=>t()},[s,q]),(0,a.useEffect)(()=>{m||localStorage.setItem(`fbos_records_${q}`,JSON.stringify(f))},[f,m,q]);let J=async e=>{if(e.preventDefault(),!(!s||!v.trim())){C(!0);try{let e=await(0,o.addDoc)((0,o.collection)(n.Sr,q),{name:v.trim(),note:b.trim(),uid:s.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)()});p(t=>[{id:e.id,name:v.trim(),note:b.trim(),uid:s.uid,recordType:`record`,createdAt:Date.now()},...t]),y(``),x(``),_(!1)}catch(e){console.error(`Error saving record:`,e)}C(!1)}},Y=async e=>{let t=e.target.files?.[0];if(!t||!s)return;let r=await n.Tt(t);O(!0);try{let e=`user_files/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,t=(0,c.ref)(n.wr,e);await(0,c.uploadBytes)(t,r,{customMetadata:{ownerId:s.uid}});let i=await(0,c.getDownloadURL)(t);if(E.current)E.current(r,i,{uid:s.uid,storagePath:e});else{let e=await(0,o.addDoc)((0,o.collection)(n.Sr,q),{name:r.name,note:`${r.type||`File`} · ${_e(r.size)}`,uid:s.uid,recordType:`file`,fileName:r.name,fileType:r.type||`unknown`,fileSize:r.size,downloadURL:i,createdAt:(0,o.serverTimestamp)()});p(t=>[{id:e.id,name:r.name,note:`${r.type||`File`} · ${_e(r.size)}`,uid:s.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)}O(!1),K.current&&(K.current.value=``)},X=async()=>{if(k){R(!0);try{let e=f.find(e=>e.id===k);if(await(0,o.deleteDoc)((0,o.doc)(n.Sr,q,k)),e?.recordType===`file`&&e.downloadURL)try{let t=e.downloadURL.split(`user_files%2F`)[1]?.split(`?`)[0];t&&await(0,c.deleteObject)((0,c.ref)(n.wr,`user_files/${decodeURIComponent(t)}`)).catch(()=>{})}catch(e){console.error(`Error cleaning up user file:`,e)}p(e=>e.filter(e=>e.id!==k)),A(null)}catch(e){console.error(`Error deleting record:`,e)}R(!1)}},[te,ne]=(0,a.useState)(null),[re,ie]=(0,a.useState)(``),[ae,Z]=(0,a.useState)(!1),[oe,Q]=(0,a.useState)(null),ce=(0,a.useRef)([]),le=e=>{if(e.recordType===`file`){ne(e.id),ie(e.name);return}B(e.id),H(e.name),ee(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??``)}));G(n),ce.current=n.map(e=>e.key)},ue=async()=>{if(!te||!re.trim()){ne(null);return}let e=f.find(e=>e.id===te);if(e&&e.name===re.trim()){ne(null);return}Z(!0);try{await(0,o.updateDoc)((0,o.doc)(n.Sr,q,te),{name:re.trim()}),p(e=>e.map(e=>e.id===te?{...e,name:re.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}Z(!1),ne(null)},de=async()=>{await fe(),B(null)},fe=async()=>{if(!z||!V.trim())return;C(!0);let e={};W.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let t=W.map(e=>e.key.trim()).filter(Boolean),r=ce.current.filter(e=>!t.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(n.Sr,q,z),{name:V.trim(),note:U.trim(),...e}),p(e=>e.map(e=>{if(e.id!==z)return e;let t={...e,name:V.trim(),note:U.trim()};return r.forEach(e=>{delete t[e]}),W.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),ce.current=t}catch(e){console.error(`Error saving record:`,e)}C(!1)},pe=(e,t)=>e?e.startsWith(`image/`)?t?(0,l.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${t})`}}):(0,l.jsx)(n.An,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,l.jsx)(n.Lt,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,l.jsx)(n.Pn,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,l.jsx)(n._r,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,l.jsx)(n.Wn,{className:`w-4 h-4`}):(0,l.jsx)(n.Nn,{className:`w-4 h-4`}):(0,l.jsx)(n.Pn,{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-purple-500/10 text-purple-500`: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 t=(e.buttonStorageIcon||`upload`).trim(),r=t.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return n.jt[r]?n.jt[r]:n.jt[t]?n.jt[t]:n.Vt||n.cn})(),be=e.buttonStyle!==`secondary`,xe=e.buttonStorageStyle===`primary`;return(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:e.tabTitle||e.tabName||`User Page`}),e.route&&(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.jsxs)(n.kt.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,l.jsx)(`input`,{type:`file`,ref:K,onChange:Y,className:`hidden`}),!i&&(0,l.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,l.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,l.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:m?`Loading…`:`${f.length} ${f.length===1?`item`:`items`}`})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>K.current?.click(),disabled:D,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:[D?(0,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin`}):(0,l.jsx)(ye,{className:`w-4 h-4`}),e.buttonStorageText&&(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,l.jsx)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>_(!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,l.jsx)(n.cn,{className:`w-4 h-4`}):(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,l.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[m&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,l.jsx)(n.yn,{className:`w-8 h-8 text-accent animate-spin`})}),i?(0,l.jsx)(`div`,{className:`fbos-content-slot`,children:(0,l.jsx)(i,{config:e,actions:{records:f,loading:m,collection:q,user:s,saveRecord:async e=>{let t=(0,o.doc)((0,o.collection)(n.Sr,q)),r={id:t.id,uid:s.uid,recordType:`record`,createdAt:Date.now(),...e};p(e=>[r,...e]),await(0,o.setDoc)(t,{uid:s.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,t)=>{p(n=>n.map(n=>n.id===e?{...n,...t}:n)),await(0,o.updateDoc)((0,o.doc)(n.Sr,q,e),t)},deleteRecord:async e=>{await(0,o.deleteDoc)((0,o.doc)(n.Sr,q,e))},startEdit:e=>le(e),confirmDelete:e=>A(e),uploadFile:()=>K.current?.click(),openAddForm:()=>_(!0),setAddForm:e=>T(()=>e),setFileHandler:e=>{E.current=e}}})}):(0,l.jsxs)(l.Fragment,{children:[!m&&f.length===0&&(0,l.jsxs)(n.kt.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,l.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,l.jsx)(n.cn,{className:`w-6 h-6 text-accent/40`})}),(0,l.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,l.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`})]}),!m&&f.length>0&&(0,l.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,l.jsx)(n.At,{children:f.map((e,t)=>{let r=z===e.id;return(0,l.jsxs)(n.kt.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},transition:{delay:t*.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,l.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,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),Q(e.id),setTimeout(()=>Q(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,l.jsx)(n.nr,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-3.5 h-3.5`})}),(0,l.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,l.jsx)(n.Bn,{className:`w-3.5 h-3.5`})})]}),(0,l.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,l.jsx)(n.un,{className:`w-3.5 h-3.5`})}),(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),A(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,l.jsx)(n.Gt,{className:`w-3.5 h-3.5`})})]}),(0,l.jsxs)(`div`,{className:`flex items-start gap-3 mb-3`,children:[(0,l.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&N(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`?pe(e.fileType,e.downloadURL):(0,l.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,l.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[te===e.id?(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,value:re,onChange:e=>ie(e.target.value),onBlur:()=>ue(),onKeyDown:e=>{e.key===`Enter`&&ue(),e.key===`Escape`&&ne(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,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>N(e)}),(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:ve(e.createdAt)})]})]}),e.note&&(0,l.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,l.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,l.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e))]},e.id)})})})]})]})]})]}),(0,l.jsx)(n.At,{children:g&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>!S&&_(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,l.jsx)(n.kt.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:w?a.default.createElement(w,{onSave:async e=>{C(!0);try{await(0,o.addDoc)((0,o.collection)(n.Sr,q),{uid:s.uid,recordType:`record`,createdAt:(0,o.serverTimestamp)(),...e}),_(!1)}catch(e){console.error(`Error saving record:`,e)}C(!1)},onClose:()=>!S&&_(!1),saving:S}):(0,l.jsxs)(`form`,{onSubmit:J,className:`p-5 flex flex-col gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>!S&&_(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:v,onChange:e=>y(e.target.value),placeholder:`Name *`,disabled:S,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,l.jsx)(`textarea`,{value:b,onChange:e=>x(e.target.value),placeholder:`Note (optional)`,disabled:S,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,l.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,l.jsx)(t.h,{type:`submit`,isLoading:S,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:S?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,d.createPortal)((0,l.jsx)(n.At,{children:P&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>N(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,l.jsx)(`button`,{onClick:()=>N(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,l.jsx)(n.Pt,{className:`w-5 h-5`})}),(0,l.jsxs)(n.kt.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,l.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,l.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,l.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:P.fileName||P.name}),(0,l.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[ge(P.fileType),` • `,_e(P.fileSize||0)]})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,l.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(P.downloadURL),Q(`preview`),setTimeout(()=>Q(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,l.jsx)(n.nr,{className:`w-4 h-4 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),ne(P.id),ie(P.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,l.jsx)(n.un,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),A(P.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,l.jsx)(n.Gt,{className:`w-4 h-4`})}),(0,l.jsx)(`a`,{href:P.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,l.jsx)(n.Bn,{className:`w-4 h-4`})})]})]}),(0,l.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>N(null),children:(0,l.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[F&&(0,l.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,l.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,l.jsx)(n.yn,{className:`w-5 h-5 text-accent animate-spin`})})}),P.fileType?.startsWith(`image/`)?(0,l.jsx)(`img`,{onLoad:()=>I(!1),onError:()=>I(!1),src:P.downloadURL,alt:P.fileName||P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType?.startsWith(`video/`)?(0,l.jsx)(`video`,{onLoadedData:()=>I(!1),onError:()=>I(!1),src:P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType===`application/pdf`?(0,l.jsx)(`iframe`,{onLoad:()=>I(!1),src:P.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${F?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,l.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(),I(!1)},children:[(0,l.jsx)(n.Pn,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,l.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,l.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,l.jsx)(n.At,{children:z&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.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,l.jsx)(n.kt.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,l.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),S&&(0,l.jsx)(n.yn,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>de(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`input`,{autoFocus:!0,required:!0,value:V,onChange:e=>H(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:U,onChange:e=>{ee(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),W.map((e,t)=>(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let n=[...W];n[t].key=e.target.value,G(n)},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,l.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let n=[...W];n[t].value=e.target.value,G(n)},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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>G(W.filter((e,n)=>n!==t)),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,l.jsx)(n.Pt,{className:`w-3 h-3`})})]},t)),(0,l.jsxs)(`button`,{type:`button`,onClick:()=>G([...W,{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,l.jsx)(n.cn,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,l.jsx)(me,{isOpen:!!k,onCancel:()=>A(null),onConfirm:X,title:`Delete Record`,message:(0,l.jsxs)(l.Fragment,{children:[`Are you sure you want to delete `,(0,l.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:f.find(e=>e.id===k)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:L})]})}function Hc({config:e,customContent:i}){let{user:s}=r.j(),{config:u}=t.y(),[f,p]=(0,a.useState)([]),[m,h]=(0,a.useState)(!0),[g,_]=(0,a.useState)(!1),[v,y]=(0,a.useState)(``),[b,x]=(0,a.useState)(``),[S,C]=(0,a.useState)(!1),[w,T]=(0,a.useState)(null),E=(0,a.useRef)(null),[D,O]=(0,a.useState)(!1),[k,A]=(0,a.useState)(null),[j,M]=(0,a.useState)(null),N=e=>{if(M(e),e){let t=e.fileType||``;I(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},P=j,[F,I]=(0,a.useState)(!0),[L,R]=(0,a.useState)(!1),[z,B]=(0,a.useState)(null),[V,H]=(0,a.useState)(``),[U,ee]=(0,a.useState)(``),[W,G]=(0,a.useState)([]),K=(0,a.useRef)(null),[q,J]=(0,a.useState)(null),Y=(0,a.useRef)([]),X=`admin_${(e.tabName||e.pageId||`admin_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`)}_records`;(0,a.useEffect)(()=>{document.title=e.tabTitle||e.tabName||u.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,u.appName]);let te=()=>({name:s.displayName||s.email?.split(`@`)[0]||`Admin`,email:s.email||``,avatar:s.photoURL||``});(0,a.useEffect)(()=>{if(!s)return;try{let e=localStorage.getItem(`fbos_records_${X}`);e?(p(JSON.parse(e)),h(!1)):h(!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}}),t=(0,o.onSnapshot)((0,o.query)((0,o.collection)(n.Sr,X),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(150)),t=>{let n=e(t.docs);p(n),h(!1),localStorage.setItem(`fbos_records_${X}`,JSON.stringify(n))},t=>{console.error(`Error listening to admin records:`,t);let r=(0,o.onSnapshot)((0,o.query)((0,o.collection)(n.Sr,X),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),p(n),h(!1),localStorage.setItem(`fbos_records_${X}`,JSON.stringify(n))});return()=>r()});return()=>t()},[s,X]);let ne=async e=>{if(e.preventDefault(),!(!s||!v.trim())){C(!0);try{let e=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{name:v.trim(),note:b.trim(),uid:s.uid,recordType:`record`,creatorName:e.name,creatorEmail:e.email,creatorAvatar:e.avatar,createdAt:(0,o.serverTimestamp)()}),y(``),x(``),_(!1)}catch(e){console.error(`Error saving admin record:`,e)}C(!1)}},re=async e=>{let t=e.target.files?.[0];if(!t||!s)return;let r=await n.Tt(t);O(!0);try{let e=`admin_files/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,t=(0,c.ref)(n.wr,e);await(0,c.uploadBytes)(t,r,{customMetadata:{ownerId:s.uid}});let i=await(0,c.getDownloadURL)(t);if(E.current)E.current(r,i,{uid:s.uid,storagePath:e});else{let e=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{name:r.name,note:`${r.type||`File`} · ${ve(r.size)}`,uid:s.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)}O(!1),K.current&&(K.current.value=``)},ie=async()=>{if(k){R(!0);try{let e=f.find(e=>e.id===k);if(await(0,o.deleteDoc)((0,o.doc)(n.Sr,X,k)),e?.recordType===`file`&&e.downloadURL)try{let t=e.downloadURL.split(`admin_files%2F`)[1]?.split(`?`)[0];t&&await(0,c.deleteObject)((0,c.ref)(n.wr,`admin_files/${decodeURIComponent(t)}`)).catch(()=>{})}catch(e){console.error(`Error cleaning up admin file:`,e)}A(null)}catch(e){console.error(`Error deleting admin record:`,e)}R(!1)}},[ae,Z]=(0,a.useState)(null),[oe,Q]=(0,a.useState)(``),[ce,le]=(0,a.useState)(!1),ue=e=>{if(e.recordType===`file`){Z(e.id),Q(e.name);return}B(e.id),H(e.name),ee(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??``)}));G(n),Y.current=n.map(e=>e.key)},de=async()=>{if(!ae||!oe.trim()){Z(null);return}let e=f.find(e=>e.id===ae);if(e&&e.name===oe.trim()){Z(null);return}le(!0);try{await(0,o.updateDoc)((0,o.doc)(n.Sr,X,ae),{name:oe.trim()}),p(e=>e.map(e=>e.id===ae?{...e,name:oe.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}le(!1),Z(null)},fe=async()=>{if(!z||!V.trim()){B(null);return}C(!0);let e={};W.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let t=W.map(e=>e.key.trim()).filter(Boolean),r=Y.current.filter(e=>!t.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(n.Sr,X,z),{name:V.trim(),note:U.trim(),...e}),p(e=>e.map(e=>{if(e.id!==z)return e;let t={...e,name:V.trim(),note:U.trim()};return r.forEach(e=>{delete t[e]}),W.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),Y.current=t}catch(e){console.error(`Error updating record:`,e)}C(!1),B(null)},pe=async()=>{if(!z||!V.trim())return;let e={};W.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let t=W.map(e=>e.key.trim()).filter(Boolean),r=Y.current.filter(e=>!t.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(n.Sr,X,z),{name:V.trim(),note:U.trim(),...e}),p(e=>e.map(e=>{if(e.id!==z)return e;let t={...e,name:V.trim(),note:U.trim()};return r.forEach(e=>{delete t[e]}),W.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),Y.current=t}catch(e){console.error(`Error silently saving record:`,e)}},he=(e,t)=>e?e.startsWith(`image/`)?t?(0,l.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${t})`}}):(0,l.jsx)(n.An,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,l.jsx)(n.Lt,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,l.jsx)(n.Pn,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,l.jsx)(n._r,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,l.jsx)(n.Wn,{className:`w-4 h-4`}):(0,l.jsx)(n.Nn,{className:`w-4 h-4`}):(0,l.jsx)(n.Pn,{className:`w-4 h-4`}),ge=e=>e?e.startsWith(`image/`)?`bg-emerald-500/10 text-emerald-500`:e.startsWith(`video/`)||e.startsWith(`audio/`)?`bg-purple-500/10 text-purple-500`: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`,_e=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)},ve=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]},ye=e=>{if(!e)return``;let t=e.toMillis?e.toMillis():e;return new Date(t).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})},be=(()=>{let t=(e.buttonStorageIcon||`upload`).trim(),r=t.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return n.jt[r]?n.jt[r]:n.jt[t]?n.jt[t]:n.Vt||n.cn})(),xe=e.buttonStyle!==`secondary`,Se=e.buttonStorageStyle===`primary`,Ce=e=>e.uid===s?.uid,we=({record:e})=>{let t=e.creatorName||e.creatorEmail?.split(`@`)[0]||`Admin`,n=e.creatorEmail||``,r=e.creatorAvatar||``,i=t.split(` `).map(e=>e[0]).join(``).toUpperCase().slice(0,2);return(0,l.jsxs)(`div`,{className:`flex items-center gap-2 mt-2 pt-2 border-t border-[var(--panel-border)]/30`,children:[r?(0,l.jsx)(`img`,{src:r,alt:``,className:`w-5 h-5 rounded-full object-cover shrink-0`}):(0,l.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:i}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 flex-1`,children:[(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 truncate`,children:t}),n&&(0,l.jsxs)(`span`,{className:`text-[10px] text-foreground/25 truncate`,children:[`· `,n]})]})]})};return(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:e.tabTitle||e.tabName||`Admin Page`}),e.route&&(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.jsxs)(n.kt.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,l.jsx)(`input`,{type:`file`,ref:K,onChange:re,className:`hidden`}),!i&&(0,l.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,l.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,l.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:m?`Loading…`:`${f.length} ${f.length===1?`item`:`items`}`})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>K.current?.click(),disabled:D,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`} ${Se?`btn-primary`:`btn-secondary`}`,children:[D?(0,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin`}):(0,l.jsx)(be,{className:`w-4 h-4`}),e.buttonStorageText&&(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,l.jsx)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>_(!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`} ${xe?`btn-primary`:`btn-secondary`}`,children:e.buttonText===`+`||!e.buttonText?(0,l.jsx)(n.cn,{className:`w-4 h-4`}):(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,l.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[m&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,l.jsx)(n.yn,{className:`w-8 h-8 text-accent animate-spin`})}),i?(0,l.jsx)(`div`,{className:`fbos-content-slot`,children:(0,l.jsx)(i,{config:e,actions:{records:f,loading:m,collection:X,user:s,saveRecord:async e=>{let t=(0,o.doc)((0,o.collection)(n.Sr,X)),r=te(),i={id:t.id,uid:s.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:Date.now(),...e};p(e=>[i,...e]),await(0,o.setDoc)(t,{uid:s.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,t)=>{p(n=>n.map(n=>n.id===e?{...n,...t}:n)),await(0,o.updateDoc)((0,o.doc)(n.Sr,X,e),t)},deleteRecord:async e=>{await(0,o.deleteDoc)((0,o.doc)(n.Sr,X,e))},startEdit:e=>ue(e),confirmDelete:e=>A(e),uploadFile:()=>K.current?.click(),openAddForm:()=>_(!0),setAddForm:e=>T(()=>e),setFileHandler:e=>{E.current=e}}})}):(0,l.jsxs)(l.Fragment,{children:[!m&&f.length===0&&(0,l.jsxs)(n.kt.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,l.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,l.jsx)(n.cn,{className:`w-6 h-6 text-accent/40`})}),(0,l.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,l.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.`})]}),!m&&f.length>0&&(0,l.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,l.jsx)(n.At,{children:f.map((e,t)=>{let r=z===e.id,i=Ce(e);return(0,l.jsxs)(n.kt.div,{initial:!1,animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},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,l.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,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),J(e.id),setTimeout(()=>J(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:q===e.id?(0,l.jsx)(n.nr,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-3.5 h-3.5`})}),(0,l.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,l.jsx)(n.Bn,{className:`w-3.5 h-3.5`})})]}),i&&(0,l.jsxs)(l.Fragment,{children:[(0,l.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,l.jsx)(n.un,{className:`w-3.5 h-3.5`})}),(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),A(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,l.jsx)(n.Gt,{className:`w-3.5 h-3.5`})})]})]}),(0,l.jsxs)(`div`,{className:`flex items-start gap-3 mb-2`,children:[(0,l.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&N(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 ${ge(e.fileType)}`:`bg-accent/10 text-accent`}`,children:e.recordType===`file`?he(e.fileType,e.downloadURL):(0,l.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,l.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[ae===e.id?(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,value:oe,onChange:e=>Q(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,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>N(e)}),(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:ye(e.createdAt)})]})]}),e.note&&(0,l.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,l.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,l.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e)),(0,l.jsx)(we,{record:e})]},e.id)})})})]})]})]})]}),(0,l.jsx)(n.At,{children:g&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>!S&&_(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,l.jsx)(n.kt.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:w?a.default.createElement(w,{onSave:async e=>{C(!0);try{let t=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{uid:s.uid,recordType:`record`,creatorName:t.name,creatorEmail:t.email,creatorAvatar:t.avatar,createdAt:(0,o.serverTimestamp)(),...e}),_(!1)}catch(e){console.error(`Error saving record:`,e)}C(!1)},onClose:()=>!S&&_(!1),saving:S}):(0,l.jsxs)(`form`,{onSubmit:ne,className:`p-5 flex flex-col gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>!S&&_(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:v,onChange:e=>y(e.target.value),placeholder:`Name *`,disabled:S,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,l.jsx)(`textarea`,{value:b,onChange:e=>x(e.target.value),placeholder:`Note (optional)`,disabled:S,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,l.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,l.jsx)(t.h,{type:`submit`,isLoading:S,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:S?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,d.createPortal)((0,l.jsx)(n.At,{children:P&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>N(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,l.jsx)(`button`,{onClick:()=>N(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,l.jsx)(n.Pt,{className:`w-5 h-5`})}),(0,l.jsxs)(n.kt.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,l.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,l.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,l.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:P.fileName||P.name}),(0,l.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[_e(P.fileType),` • `,ve(P.fileSize||0)]})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,l.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(P.downloadURL),J(`preview`),setTimeout(()=>J(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:q===`preview`?(0,l.jsx)(n.nr,{className:`w-4 h-4 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),Z(P.id),Q(P.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,l.jsx)(n.un,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),A(P.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,l.jsx)(n.Gt,{className:`w-4 h-4`})}),(0,l.jsx)(`a`,{href:P.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,l.jsx)(n.Bn,{className:`w-4 h-4`})})]})]}),(0,l.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>N(null),children:(0,l.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[F&&(0,l.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,l.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,l.jsx)(n.yn,{className:`w-5 h-5 text-accent animate-spin`})})}),P.fileType?.startsWith(`image/`)?(0,l.jsx)(`img`,{onLoad:()=>I(!1),onError:()=>I(!1),src:P.downloadURL,alt:P.fileName||P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType?.startsWith(`video/`)?(0,l.jsx)(`video`,{onLoadedData:()=>I(!1),onError:()=>I(!1),src:P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType===`application/pdf`?(0,l.jsx)(`iframe`,{onLoad:()=>I(!1),src:P.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${F?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,l.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(),I(!1)},children:[(0,l.jsx)(n.Pn,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,l.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,l.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,l.jsx)(n.At,{children:z&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.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,l.jsx)(n.kt.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,l.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),S&&(0,l.jsx)(n.yn,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>fe(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`input`,{autoFocus:!0,required:!0,value:V,onChange:e=>H(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:U,onChange:e=>{ee(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),W.map((e,t)=>(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let n=[...W];n[t].key=e.target.value,G(n)},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,l.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let n=[...W];n[t].value=e.target.value,G(n)},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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>G(W.filter((e,n)=>n!==t)),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,l.jsx)(n.Pt,{className:`w-3 h-3`})})]},t)),(0,l.jsxs)(`button`,{type:`button`,onClick:()=>G([...W,{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,l.jsx)(n.cn,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,l.jsx)(me,{isOpen:!!k,onCancel:()=>A(null),onConfirm:ie,title:`Delete Record`,message:(0,l.jsxs)(l.Fragment,{children:[`Are you sure you want to delete `,(0,l.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:f.find(e=>e.id===k)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:L})]})}function Uc({config:e,customContent:i}){let{user:s}=r.j(),{config:u}=t.y(),[f,p]=(0,a.useState)([]),[m,h]=(0,a.useState)(!0),[g,_]=(0,a.useState)(!1),[v,y]=(0,a.useState)(``),[b,x]=(0,a.useState)(``),[S,C]=(0,a.useState)(!1),[w,T]=(0,a.useState)(null),E=(0,a.useRef)(null),[D,O]=(0,a.useState)(!1),[k,A]=(0,a.useState)(null),[j,M]=(0,a.useState)(null),N=e=>{if(M(e),e){let t=e.fileType||``;I(t.startsWith(`image/`)||t.startsWith(`video/`)||t===`application/pdf`)}},P=j,[F,I]=(0,a.useState)(!0),[L,R]=(0,a.useState)(!1),[z,B]=(0,a.useState)(null),[V,H]=(0,a.useState)(``),[U,ee]=(0,a.useState)(``),[W,G]=(0,a.useState)([]),K=(0,a.useRef)(null),[q,J]=(0,a.useState)(null),Y=(0,a.useRef)([]),X=`mem_${(e.tabName||e.pageId||`internal_page`).toLowerCase().replace(/[^a-z0-9]+/g,`_`)}_records`;(0,a.useEffect)(()=>{document.title=e.tabTitle||e.tabName||u.appName||`Your AI Firebase`},[e.tabTitle,e.tabName,u.appName]),(0,a.useEffect)(()=>{if(!s)return;try{let e=localStorage.getItem(`fbos_records_${X}`);e?(p(JSON.parse(e)),h(!1)):h(!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}}),t=(0,o.onSnapshot)((0,o.query)((0,o.collection)(n.Sr,X),(0,o.orderBy)(`createdAt`,`desc`),(0,o.limit)(150)),t=>{let n=e(t.docs);p(n),h(!1),localStorage.setItem(`fbos_records_${X}`,JSON.stringify(n))},t=>{console.error(`Error listening to shared records:`,t);let r=(0,o.onSnapshot)((0,o.query)((0,o.collection)(n.Sr,X),(0,o.limit)(150)),t=>{let n=e(t.docs);n.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),p(n),h(!1),localStorage.setItem(`fbos_records_${X}`,JSON.stringify(n))});return()=>r()});return()=>t()},[s,X]);let te=()=>({name:s.displayName||s.email?.split(`@`)[0]||`Member`,email:s.email||``,avatar:s.photoURL||``}),ne=async e=>{if(e.preventDefault(),!(!s||!v.trim())){C(!0);try{let e=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{name:v.trim(),note:b.trim(),uid:s.uid,recordType:`record`,creatorName:e.name,creatorEmail:e.email,creatorAvatar:e.avatar,createdAt:(0,o.serverTimestamp)()}),y(``),x(``),_(!1)}catch(e){console.error(`Error saving shared record:`,e)}C(!1)}},re=async e=>{let t=e.target.files?.[0];if(!t||!s)return;let r=await n.Tt(t);O(!0);try{let e=`mem_files/${`${Date.now()}_${r.name.replace(/[^a-zA-Z0-9.-]/g,`_`)}`}`,t=(0,c.ref)(n.wr,e);await(0,c.uploadBytes)(t,r,{customMetadata:{ownerId:s.uid}});let i=await(0,c.getDownloadURL)(t);if(E.current)E.current(r,i,{uid:s.uid,storagePath:e});else{let e=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{name:r.name,note:`${r.type||`File`} · ${ve(r.size)}`,uid:s.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)}O(!1),K.current&&(K.current.value=``)},ie=async()=>{if(k){R(!0);try{let e=f.find(e=>e.id===k);if(await(0,o.deleteDoc)((0,o.doc)(n.Sr,X,k)),e?.recordType===`file`&&e.downloadURL)try{let t=e.downloadURL.split(`mem_files%2F`)[1]?.split(`?`)[0];t&&await(0,c.deleteObject)((0,c.ref)(n.wr,`mem_files/${decodeURIComponent(t)}`)).catch(()=>{})}catch(e){console.error(`Error cleaning up shared file:`,e)}A(null)}catch(e){console.error(`Error deleting shared record:`,e)}R(!1)}},[ae,Z]=(0,a.useState)(null),[oe,Q]=(0,a.useState)(``),[ce,le]=(0,a.useState)(!1),ue=e=>{if(e.recordType===`file`){Z(e.id),Q(e.name);return}B(e.id),H(e.name),ee(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??``)}));G(n),Y.current=n.map(e=>e.key)},de=async()=>{if(!ae||!oe.trim()){Z(null);return}let e=f.find(e=>e.id===ae);if(e&&e.name===oe.trim()){Z(null);return}le(!0);try{await(0,o.updateDoc)((0,o.doc)(n.Sr,X,ae),{name:oe.trim()}),p(e=>e.map(e=>e.id===ae?{...e,name:oe.trim()}:e))}catch(e){console.error(`Error renaming file:`,e)}le(!1),Z(null)},fe=async()=>{await pe(),B(null)},pe=async()=>{if(!z||!V.trim())return;C(!0);let e={};W.forEach(({key:t,value:n})=>{t.trim()&&(e[t.trim()]=n)});let t=W.map(e=>e.key.trim()).filter(Boolean),r=Y.current.filter(e=>!t.includes(e));r.forEach(t=>{e[t]=(0,o.deleteField)()});try{await(0,o.updateDoc)((0,o.doc)(n.Sr,X,z),{name:V.trim(),note:U.trim(),...e}),p(e=>e.map(e=>{if(e.id!==z)return e;let t={...e,name:V.trim(),note:U.trim()};return r.forEach(e=>{delete t[e]}),W.forEach(({key:e,value:n})=>{e.trim()&&(t[e.trim()]=n)}),t})),Y.current=t}catch(e){console.error(`Error saving record:`,e)}C(!1)},he=(e,t)=>e?e.startsWith(`image/`)?t?(0,l.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-cover bg-center shrink-0`,style:{backgroundImage:`url(${t})`}}):(0,l.jsx)(n.An,{className:`w-4 h-4`}):e.startsWith(`video/`)||e.startsWith(`audio/`)?(0,l.jsx)(n.Lt,{className:`w-4 h-4`}):e.includes(`pdf`)||e.includes(`word`)||e.includes(`text`)?(0,l.jsx)(n.Pn,{className:`w-4 h-4`}):e.includes(`zip`)||e.includes(`rar`)||e.includes(`archive`)?(0,l.jsx)(n._r,{className:`w-4 h-4`}):e.includes(`html`)||e.includes(`csv`)||e.includes(`json`)?(0,l.jsx)(n.Wn,{className:`w-4 h-4`}):(0,l.jsx)(n.Nn,{className:`w-4 h-4`}):(0,l.jsx)(n.Pn,{className:`w-4 h-4`}),ge=e=>e?e.startsWith(`image/`)?`bg-emerald-500/10 text-emerald-500`:e.startsWith(`video/`)||e.startsWith(`audio/`)?`bg-purple-500/10 text-purple-500`: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`,_e=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)},ve=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]},ye=e=>{if(!e)return``;let t=e.toMillis?e.toMillis():e;return new Date(t).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})},be=(()=>{let t=(e.buttonStorageIcon||`upload`).trim(),r=t.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``);return n.jt[r]?n.jt[r]:n.jt[t]?n.jt[t]:n.Vt||n.cn})(),xe=e.buttonStyle!==`secondary`,Se=e.buttonStorageStyle===`primary`,Ce=e=>e.uid===s?.uid,we=({record:e})=>{let t=e.creatorName||e.creatorEmail?.split(`@`)[0]||`Member`,n=e.creatorEmail||``,r=e.creatorAvatar||``,i=t.split(` `).map(e=>e[0]).join(``).toUpperCase().slice(0,2);return(0,l.jsxs)(`div`,{className:`flex items-center gap-2 mt-2 pt-2 border-t border-[var(--panel-border)]/30`,children:[r?(0,l.jsx)(`img`,{src:r,alt:``,className:`w-5 h-5 rounded-full object-cover shrink-0`}):(0,l.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:i}),(0,l.jsxs)(`div`,{className:`flex items-center gap-1 min-w-0 flex-1`,children:[(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/40 truncate`,children:t}),n&&(0,l.jsxs)(`span`,{className:`text-[10px] text-foreground/25 truncate`,children:[`· `,n]})]})]})};return(0,l.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,l.jsx)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6 flex items-center justify-between`,children:(0,l.jsxs)(`div`,{children:[(0,l.jsx)(r.y,{children:e.tabTitle||e.tabName||`Internal Page`}),e.route&&(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),e.route]})]})}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.jsxs)(n.kt.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,l.jsx)(`input`,{type:`file`,ref:K,onChange:re,className:`hidden`}),!i&&(0,l.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,l.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,l.jsx)(`h2`,{className:`text-xl font-extrabold text-foreground tracking-tight truncate`,children:e.tabTitle||e.tabName||`Dashboard`}),(0,l.jsx)(`p`,{className:`text-[13px] font-medium text-foreground/50 mt-1`,children:m?`Loading…`:`${f.length} ${f.length===1?`item`:`items`} · Internal`})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[e.storage!==!1&&(0,l.jsx)(l.Fragment,{children:(0,l.jsxs)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>K.current?.click(),disabled:D,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`} ${Se?`btn-primary`:`btn-secondary`}`,children:[D?(0,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin`}):(0,l.jsx)(be,{className:`w-4 h-4`}),e.buttonStorageText&&(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonStorageText})]})}),e.showButton!==!1&&(0,l.jsx)(n.kt.button,{whileHover:{scale:1.05},whileTap:{scale:.95},onClick:()=>_(!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`} ${xe?`btn-primary`:`btn-secondary`}`,children:e.buttonText===`+`||!e.buttonText?(0,l.jsx)(n.cn,{className:`w-4 h-4`}):(0,l.jsx)(`span`,{className:`text-[13px] font-bold`,children:e.buttonText})})]})]}),(0,l.jsxs)(`div`,{className:`p-6 md:p-8 flex-1 overflow-y-auto relative min-h-[400px]`,children:[m&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-10 flex items-center justify-center bg-background/50 backdrop-blur-sm`,children:(0,l.jsx)(n.yn,{className:`w-8 h-8 text-accent animate-spin`})}),i?(0,l.jsx)(`div`,{className:`fbos-content-slot`,children:(0,l.jsx)(i,{config:e,actions:{records:f,loading:m,collection:X,user:s,saveRecord:async e=>{let t=(0,o.doc)((0,o.collection)(n.Sr,X)),r=te(),i={id:t.id,uid:s.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:Date.now(),...e};p(e=>[i,...e]),await(0,o.setDoc)(t,{uid:s.uid,recordType:`record`,creatorName:r.name,creatorEmail:r.email,creatorAvatar:r.avatar,createdAt:(0,o.serverTimestamp)(),...e})},updateRecord:async(e,t)=>{p(n=>n.map(n=>n.id===e?{...n,...t}:n)),await(0,o.updateDoc)((0,o.doc)(n.Sr,X,e),t)},deleteRecord:async e=>{await(0,o.deleteDoc)((0,o.doc)(n.Sr,X,e))},startEdit:e=>ue(e),confirmDelete:e=>A(e),uploadFile:()=>K.current?.click(),openAddForm:()=>_(!0),setAddForm:e=>T(()=>e),setFileHandler:e=>{E.current=e}}})}):(0,l.jsxs)(l.Fragment,{children:[!m&&f.length===0&&(0,l.jsxs)(n.kt.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,l.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,l.jsx)(n.cn,{className:`w-6 h-6 text-accent/40`})}),(0,l.jsx)(`p`,{className:`text-[15px] font-bold mb-1.5 text-foreground/50`,children:`No items yet`}),(0,l.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.`})]}),!m&&f.length>0&&(0,l.jsx)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4`,children:(0,l.jsx)(n.At,{children:f.map(e=>{let t=z===e.id,r=Ce(e);return(0,l.jsxs)(n.kt.div,{initial:!1,animate:{opacity:1,y:0},exit:{opacity:0,scale:.95},onClick:()=>r?ue(e):null,className:`group flex flex-col bg-background border rounded-2xl p-5 transition-all relative ${r?`cursor-pointer`:``} ${t?`border-accent/40 shadow-lg ring-1 ring-accent/20`:`border-[var(--panel-border)] hover:border-accent/30 hover:shadow-lg`}`,children:[(0,l.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,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),navigator.clipboard.writeText(e.downloadURL),J(e.id),setTimeout(()=>J(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:q===e.id?(0,l.jsx)(n.nr,{className:`w-3.5 h-3.5 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-3.5 h-3.5`})}),(0,l.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,l.jsx)(n.Bn,{className:`w-3.5 h-3.5`})})]}),r&&(0,l.jsxs)(l.Fragment,{children:[(0,l.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,l.jsx)(n.un,{className:`w-3.5 h-3.5`})}),(0,l.jsx)(`button`,{onClick:t=>{t.stopPropagation(),A(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,l.jsx)(n.Gt,{className:`w-3.5 h-3.5`})})]})]}),(0,l.jsxs)(`div`,{className:`flex items-start gap-3 mb-2`,children:[(0,l.jsx)(`div`,{onClick:t=>{t.stopPropagation(),e.recordType===`file`&&N(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 ${ge(e.fileType)}`:`bg-accent/10 text-accent`}`,children:e.recordType===`file`?he(e.fileType,e.downloadURL):(0,l.jsx)(`div`,{className:`w-2 h-2 rounded-full bg-current`})}),(0,l.jsxs)(`div`,{className:`flex flex-col min-w-0 flex-1 relative`,children:[ae===e.id?(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,value:oe,onChange:e=>Q(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,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground truncate pr-12`,children:e.name}),e.recordType===`file`&&(0,l.jsx)(`div`,{className:`absolute inset-0 z-0 cursor-pointer`,onClick:()=>N(e)}),(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/35 font-bold uppercase tracking-wider mt-0.5`,children:ye(e.createdAt)})]})]}),e.note&&(0,l.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,l.jsxs)(`div`,{className:`flex items-center gap-1.5 mt-1`,children:[(0,l.jsxs)(`span`,{className:`text-[10px] font-bold text-foreground/30 uppercase tracking-wider shrink-0`,children:[e,`:`]}),(0,l.jsx)(`span`,{className:`text-[11px] font-semibold text-foreground/60 truncate`,children:String(t)})]},e)),(0,l.jsx)(we,{record:e})]},e.id)})})})]})]})]})]}),(0,l.jsx)(n.At,{children:g&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>!S&&_(!1),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/60 backdrop-blur-sm cursor-pointer`}),(0,l.jsx)(n.kt.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:w?a.default.createElement(w,{onSave:async e=>{C(!0);try{let t=te();await(0,o.addDoc)((0,o.collection)(n.Sr,X),{uid:s.uid,recordType:`record`,creatorName:t.name,creatorEmail:t.email,creatorAvatar:t.avatar,createdAt:(0,o.serverTimestamp)(),...e}),_(!1)}catch(e){console.error(`Error saving record:`,e)}C(!1)},onClose:()=>!S&&_(!1),saving:S}):(0,l.jsxs)(`form`,{onSubmit:ne,className:`p-5 flex flex-col gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`New Record`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>!S&&_(!1),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer p-0.5`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,required:!0,value:v,onChange:e=>y(e.target.value),placeholder:`Name *`,disabled:S,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,l.jsx)(`textarea`,{value:b,onChange:e=>x(e.target.value),placeholder:`Note (optional)`,disabled:S,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,l.jsx)(`div`,{className:`flex justify-end pt-1`,children:(0,l.jsx)(t.h,{type:`submit`,isLoading:S,className:`px-5 py-2 text-[12px] font-bold shadow-md`,children:S?`Saving…`:`Save`})})]})})]})}),typeof window<`u`&&(0,d.createPortal)((0,l.jsx)(n.At,{children:P&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[9999] flex items-center justify-center p-4 md:p-12`,children:[(0,l.jsx)(n.kt.div,{onClick:()=>N(null),initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},className:`absolute inset-0 bg-background/95 backdrop-blur-xl cursor-pointer`}),(0,l.jsx)(`button`,{onClick:()=>N(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,l.jsx)(n.Pt,{className:`w-5 h-5`})}),(0,l.jsxs)(n.kt.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,l.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,l.jsxs)(`div`,{className:`flex flex-col min-w-0 pr-4`,children:[(0,l.jsx)(`span`,{className:`text-xl font-extrabold text-foreground truncate`,children:P.fileName||P.name}),(0,l.jsxs)(`span`,{className:`text-[12px] text-foreground/70 font-bold uppercase tracking-wider mt-1`,children:[_e(P.fileType),` • `,ve(P.fileSize||0)]})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0`,children:[(0,l.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(P.downloadURL),J(`preview`),setTimeout(()=>J(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:q===`preview`?(0,l.jsx)(n.nr,{className:`w-4 h-4 text-emerald-500`}):(0,l.jsx)(n.xn,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),Z(P.id),Q(P.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,l.jsx)(n.un,{className:`w-4 h-4`})}),(0,l.jsx)(`button`,{onClick:()=>{N(null),A(P.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,l.jsx)(n.Gt,{className:`w-4 h-4`})}),(0,l.jsx)(`a`,{href:P.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,l.jsx)(n.Bn,{className:`w-4 h-4`})})]})]}),(0,l.jsx)(`div`,{className:`flex-1 w-full relative bg-foreground/[0.02] min-h-[50vh] md:min-h-[600px]`,onClick:()=>N(null),children:(0,l.jsxs)(`div`,{className:`absolute inset-x-4 inset-y-8 md:inset-x-12 md:inset-y-12 flex items-center justify-center`,children:[F&&(0,l.jsx)(`div`,{className:`absolute inset-0 flex items-center justify-center rounded-lg z-50 pointer-events-none`,children:(0,l.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,l.jsx)(n.yn,{className:`w-5 h-5 text-accent animate-spin`})})}),P.fileType?.startsWith(`image/`)?(0,l.jsx)(`img`,{onLoad:()=>I(!1),onError:()=>I(!1),src:P.downloadURL,alt:P.fileName||P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType?.startsWith(`video/`)?(0,l.jsx)(`video`,{onLoadedData:()=>I(!1),onError:()=>I(!1),src:P.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 ${F?`opacity-0`:`opacity-100`}`,onClick:e=>e.stopPropagation()}):P.fileType===`application/pdf`?(0,l.jsx)(`iframe`,{onLoad:()=>I(!1),src:P.downloadURL,className:`w-full h-full border-none rounded-lg relative z-10 transition-opacity duration-500 ${F?`opacity-0`:`opacity-100`}`,style:{backgroundColor:`white`},title:`PDF Preview`,onClick:e=>e.stopPropagation()}):(0,l.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(),I(!1)},children:[(0,l.jsx)(n.Pn,{className:`w-24 h-24 mb-6 opacity-40 drop-shadow-sm`}),(0,l.jsx)(`span`,{className:`text-[20px] font-extrabold text-foreground`,children:`Preview Unavailable`}),(0,l.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,l.jsx)(n.At,{children:z&&(0,l.jsxs)(`div`,{className:`fixed inset-0 z-[120] flex items-center justify-center p-4`,children:[(0,l.jsx)(n.kt.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,l.jsx)(n.kt.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,l.jsxs)(`div`,{className:`p-5 flex flex-col gap-3 max-h-[80vh] overflow-y-auto`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between mb-2 mt-2 px-1`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`span`,{className:`text-[14px] font-bold text-foreground`,children:`Edit Record`}),S&&(0,l.jsx)(n.yn,{className:`w-3 h-3 animate-spin text-foreground/40`})]}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>fe(),className:`text-foreground/30 hover:text-foreground/60 transition-colors cursor-pointer`,children:(0,l.jsx)(n.Pt,{className:`w-4 h-4`})})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-0 max-h-[70vh] overflow-y-auto no-scrollbar px-1`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`input`,{autoFocus:!0,required:!0,value:V,onChange:e=>H(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.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,l.jsx)(`textarea`,{ref:e=>{e&&(e.style.height=`auto`,e.style.height=e.scrollHeight+`px`)},value:U,onChange:e=>{ee(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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`})]}),W.map((e,t)=>(0,l.jsxs)(`div`,{className:`flex flex-col relative group/field`,children:[(0,l.jsx)(`input`,{placeholder:`FIELD NAME`,value:e.key,onChange:e=>{let n=[...W];n[t].key=e.target.value,G(n)},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,l.jsx)(`input`,{placeholder:`Field value...`,value:e.value,onChange:e=>{let n=[...W];n[t].value=e.target.value,G(n)},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,l.jsx)(`div`,{className:`border-b border-dashed border-[var(--panel-border)]/60`}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>G(W.filter((e,n)=>n!==t)),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,l.jsx)(n.Pt,{className:`w-3 h-3`})})]},t)),(0,l.jsxs)(`button`,{type:`button`,onClick:()=>G([...W,{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,l.jsx)(n.cn,{className:`w-3 h-3`}),` Add Field`]})]})]})})]})}),(0,l.jsx)(me,{isOpen:!!k,onCancel:()=>A(null),onConfirm:ie,title:`Delete Record`,message:(0,l.jsxs)(l.Fragment,{children:[`Are you sure you want to delete `,(0,l.jsx)(`strong`,{className:`text-foreground font-extrabold break-words mx-1`,children:f.find(e=>e.id===k)?.name}),` This action cannot be undone.`]}),confirmText:`Delete`,isProcessing:L})]})}var Wc=[`board`,`table`,`calendar`,`drive`],Gc=[`inline_form`,`popup_form`],Kc=e=>typeof e!=`string`||e===``||e===`none`||e===`custom`||![...Wc,...Gc].includes(e),qc=(e,t)=>Kc(e)||t&&!Jc(e),Jc=e=>typeof e==`string`&&Wc.includes(e),Yc=`/src/your-ai-workflow-firebase-os/microcomponents`,Xc=e=>(e||``).split(/[^a-zA-Z0-9]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``),Zc=e=>{let t=e.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).toLowerCase();return[t,t.replace(/_/g,``)]},Qc=e=>{let t=[e?.contentKey,e?.tabName,e?.pageId,e?.pageName].filter(e=>typeof e==`string`&&e.trim()).map(e=>Xc(e)).filter(Boolean);return[...new Set(t)].map(e=>`${e}Content.tsx`)},$c=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)])},el=new Map,tl=e=>{let t=el.get(e);return t||(t=import(`${Yc}/${e}`).then(e=>typeof e?.default==`function`||typeof e?.default==`object`?e.default:null).catch(()=>null),el.set(e,t)),t};async function nl(e){if(typeof window>`u`||$c(e))return null;for(let t of Qc(e)){let e=await tl(t);if(!e)continue;let[n,r]=Zc(t.replace(/Content\.tsx$/,``)),i=window.__FBOS_MICROCOMPONENTS__||{};return window.__FBOS_MICROCOMPONENTS__={[n]:e,[r]:e,...i},e}return null}var rl=(e,t)=>{let n=t?r.V(e.pageType):`public`;return{...e,pageType:n,isPrivate:t,isAdmin:n===`admin`,isInternal:n===`internal`,isShared:n===`internal`}};function il(){let e=(0,u.useLocation)(),{user:i,userRole:s,loading:c,roleResolved:d}=r.j(),f=n.br(),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 rl(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 rl({...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.S}:e===`/support`?{route:`/support`,template:`popup_form`,form:`support`,pageId:`support`,contentKey:`support`,pageName:`Support`,formConfigOverride:f.defaultConfigs?.supportForm||t.b}:null},[m,h]=(0,a.useState)(()=>p(e.pathname)),[g,_]=(0,a.useState)(()=>!p(e.pathname));(0,a.useEffect)(()=>{let r=!0,i=p(e.pathname);if(i){h(i),_(!1);let e=i.pageName||i.tabName||i.title;e&&(document.title=e)}return(async()=>{try{let i=e.pathname;i.startsWith(`/`)&&(i=i.substring(1));let[a,s,c,l,u,d]=await Promise.allSettled([(0,o.getDoc)((0,o.doc)(n.Sr,`sys_pages`,i)),(0,o.getDoc)((0,o.doc)(n.Sr,`sys_tabs`,i)),(0,o.getDocs)((0,o.query)((0,o.collection)(n.Sr,`sys_pages`),(0,o.where)(`route`,`==`,e.pathname),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(n.Sr,`sys_pages`),(0,o.where)(`route`,`==`,i),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(n.Sr,`sys_tabs`),(0,o.where)(`route`,`==`,e.pathname),(0,o.limit)(1))),(0,o.getDocs)((0,o.query)((0,o.collection)(n.Sr,`sys_tabs`),(0,o.where)(`route`,`==`,i),(0,o.limit)(1)))]),p=null,m=null,g=(e,t)=>{p||e.status===`fulfilled`&&(e.value.exists&&e.value.exists()?(p=rl(e.value.data(),t),m=e.value.id):e.value.docs&&e.value.docs.length>0&&(p=rl(e.value.docs[0].data(),t),m=e.value.docs[0].id))};if(g(a,!1),g(c,!1),g(l,!1),g(s,!0),g(u,!0),g(d,!0),!p){let t=(typeof window<`u`?window.__FBOS_PAGES__:null)||{};for(let[n,r]of Object.entries(t)){let t=r.config,a=r.isPublic,o=t.route||`/`+n;if(o===e.pathname||n===i){p=rl({...t,route:o,contentKey:t.pageId||n,pageId:n},!a),m=n;break}}}if(p||(e.pathname===`/contact`?(p={route:`/contact`,template:`popup_form`,form:`contact`,pageName:`Contact`},m=`contact`):e.pathname===`/support`&&(p={route:`/support`,template:`popup_form`,form:`support`,pageName:`Support`},m=`support`)),!r)return;if(p){if((m===`contact`||m===`support`)&&!p.form&&(p.form=m),p.contentKey||=p.pageId||m,p.pageId=m,localStorage.setItem(`fbos_route_${e.pathname}`,JSON.stringify(p)),p.form){let e=(typeof window<`u`?window.__FBOS_FORMS__:null)||{},i=n=>f.defaultConfigs?.[n]||f.defaultConfigs?.[`${n}Form`]||e[n]||(n===`contact`?t.S:n===`support`?t.b:null);if(localStorage.getItem(`fbos_custom_form_${p.form}`)){try{let e=localStorage.getItem(`fbos_form_${p.form}`);e&&(p.formConfigOverride=JSON.parse(e))}catch{}(0,o.getDoc)((0,o.doc)(n.Sr,`sys_forms`,p.form)).then(async e=>{if(r)if(e.exists()){let t={...e.data(),id:e.id};h(e=>({...e,formConfigOverride:t})),localStorage.setItem(`fbos_form_${p.form}`,JSON.stringify(t))}else{let e=i(p.form);e&&(h(t=>({...t,formConfigOverride:e})),localStorage.setItem(`fbos_form_${p.form}`,JSON.stringify(e)),localStorage.removeItem(`fbos_custom_form_${p.form}`))}})}else{let e=i(p.form);e&&(p.formConfigOverride=e)}}let i=p.pageName||p.tabName||p.title;i&&(document.title=i),h(p),_(!1)}else h(`not-found`),_(!1),localStorage.removeItem(`fbos_route_${e.pathname}`)}catch{r&&g&&(h(`not-found`),_(!1))}})(),()=>{r=!1}},[e.pathname]);let[v,y]=(0,a.useState)(!1),[b,x]=(0,a.useState)(null),[S,C]=(0,a.useState)(!1),w=m&&m!==`not-found`&&typeof m==`object`?[m.contentKey,m.tabName,m.pageId,m.pageName].filter(Boolean).join(`|`):``;if((0,a.useEffect)(()=>{if(x(null),!w||$c(m)){C(!1);return}let e=!1;C(!0),nl(m).then(t=>{e||(t&&x(()=>t),C(!1))});let t=setTimeout(()=>{e||C(!1)},4e3);return()=>{e=!0,clearTimeout(t)}},[w]),(0,a.useEffect)(()=>{let e;return g||c||!d||S?e=setTimeout(()=>y(!0),150):y(!1),()=>clearTimeout(e)},[g,c,d,S]),g||c||!d||S)return v?i?(0,l.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,l.jsxs)(`div`,{className:`mb-6`,children:[(0,l.jsx)(`div`,{className:`h-10 w-56 rounded-xl bg-foreground/5 animate-pulse mt-1`}),(0,l.jsx)(`div`,{className:`h-3 w-24 rounded bg-foreground/5 animate-pulse mt-3`})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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,l.jsx)(n.yn,{className:`w-6 h-6 animate-spin text-accent`})})]})]}):(0,l.jsx)(`div`,{className:`flex-1 flex items-center justify-center min-h-[40vh] z-10`,children:(0,l.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,l.jsx)(n.yn,{className:`w-4 h-4 animate-spin text-accent`}),(0,l.jsx)(`span`,{className:`text-[12px] font-medium text-foreground/60 tracking-wide`,children:`Loading page...`})]})}):null;if(m===`not-found`)return(0,l.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,l.jsxs)(`div`,{className:`flex flex-col items-center justify-center flex-1 text-center`,children:[(0,l.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,l.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,l.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,l.jsx)(`line`,{x1:`12`,y1:`8`,x2:`12`,y2:`12`}),(0,l.jsx)(`line`,{x1:`12`,y1:`16`,x2:`12.01`,y2:`16`})]})}),(0,l.jsx)(`h2`,{className:`text-2xl sm:text-3xl font-bold mb-3 text-foreground`,children:`Page Not Found`}),(0,l.jsx)(`p`,{className:`text-foreground/60 max-w-md`,children:`The route you are looking for does not exist or has been removed.`}),r.L(s)&&(()=>{let t=Fc();return(0,l.jsxs)(`div`,{className:`mt-8 w-full max-w-lg text-left flex flex-col gap-4`,children:[(0,l.jsxs)(`div`,{className:`rounded-2xl border border-[var(--panel-border)] bg-[var(--panel-bg)] px-5 py-4`,children:[(0,l.jsx)(`p`,{className:`text-[12px] font-extrabold tracking-tight text-gradient mb-1.5`,children:`Pages the app can see`}),(0,l.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,l.jsx)(r.g,{title:`If your assistant just made this page, paste this`,prompt:zc(e.pathname)})]})})()]})});if((m.pageId===`support`||m.isPrivate)&&!i)return(0,l.jsx)(u.Navigate,{to:`/login`,state:{from:e}});if(!r.F(s,m.isPrivate?m.pageType:`public`))return m.isAdmin?(0,l.jsx)(wr,{}):(0,l.jsx)(Cr,{});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=f.microcomponents||(typeof window<`u`?window.__FBOS_MICROCOMPONENTS__:void 0),k=e=>e.toLowerCase().replace(/[^a-z0-9]+/g,`_`).replace(/^_|_$/g,``),A=[m.contentKey,m.tabName,m.pageId,m.pageName,m.pageName?.replace(/\s+/g,`_`)].filter(Boolean).map(e=>k(e)).reduce((e,t)=>e||O?.[t],void 0),j=T||A||b||void 0,M=m.route||m.pageId||`custom`;if(qc(m.template,!!j))return m.isAdmin?(0,l.jsx)(Hc,{config:m,customContent:j},M):m.isInternal?(0,l.jsx)(Uc,{config:m,customContent:j},M):m.isPrivate?(0,l.jsx)(Vc,{config:m,customContent:j},M):(0,l.jsx)(Bc,{config:m,customContent:j},M);if(m.template===`board`){let e=m.isAdmin?`admin_${m.pageId||E}`:m.isInternal?`mem_${m.pageId||E}`:m.isPrivate?`user_${m.pageId||E}`:D;return(0,l.jsx)(f.components?.TemplateBoard||it,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Board`,subtitle:m.route,tasksCollection:`${e}_tasks`,categoriesCollection:`${e}_categories`,config:m,customContent:j},M)}if(m.template===`table`){let e=m.isAdmin?`admin_${m.pageId||E}`:m.isInternal?`mem_${m.pageId||E}`:m.isPrivate?`user_${m.pageId||E}`:D;return(0,l.jsx)(f.components?.TemplateTable||Pn,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Table`,subtitle:m.route,tableCollection:`${e}_table`,config:m,customContent:j},M)}if(m.template===`calendar`){let e=m.isAdmin?`admin_${m.pageId||E}`:m.isInternal?`mem_${m.pageId||E}`:m.isPrivate?`user_${m.pageId||E}`:D;return(0,l.jsx)(f.components?.TemplateCalendar||Ln,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Calendar`,subtitle:m.route,eventsCollection:`${e}_events`,defaultTimeFormat:m.defaultTimeFormat||m.defaulttimeformat||`12h`,config:m,customContent:j},M)}if(m.template===`drive`){let e=m.isAdmin?`admin_${m.pageId||E}`:m.isInternal?`mem_${m.pageId||E}`:m.isPrivate?`user_${m.pageId||E}`:D;return(0,l.jsx)(f.components?.TemplateDrive||Fe,{title:m.tabTitle||m.tabName||m.title||m.pageName||`Drive`,subtitle:m.route,filesCollection:`${e}_files`,config:m,customContent:j},M)}return m.template===`inline_form`?(0,l.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-start mt-8 relative z-10 w-full min-h-[60vh]`,children:(0,l.jsx)(t.t,{isInline:!0,formId:m.form,formConfig:m.formConfigOverride})}):(0,l.jsx)(`div`,{className:`flex-1 flex flex-col items-center justify-center relative z-10 w-full min-h-[60vh]`,children:(0,l.jsx)(t.t,{formId:m.form,formConfig:m.formConfigOverride,onClose:()=>window.history.back()})})}var al=e=>e.error?`error`:e.paid?`paid`:`unpaid`,ol={checking:{icon:n.Kn,tint:`text-accent`,title:`Checking your payment…`},paid:{icon:n.Xn,tint:`text-emerald-400`,title:`Thank you — payment received`},unpaid:{icon:n.Kn,tint:`text-amber-400`,title:`Not confirmed yet`},error:{icon:n.Zn,tint:`text-red-400`,title:`We could not confirm this payment`},cancelled:{icon:n.qn,tint:`text-foreground/50`,title:`Payment cancelled`}};function sl({cancelled:e=!1}){let[i]=(0,u.useSearchParams)(),o=i.get(`session_id`)||``,[s,c]=(0,a.useState)(`checking`),[d,f]=(0,a.useState)(null);(0,a.useEffect)(()=>{if(e)return;let t=!1;return r.x(o).then(e=>{t||(f(e),c(al(e)))}),()=>{t=!0}},[e,o]);let p=async()=>{c(`checking`);let e=await r.x(o);f(e),c(al(e))},m=ol[e?`cancelled`:s],h=m.icon;return(0,l.jsx)(`div`,{className:`flex-1 flex items-center justify-center w-full z-10 px-4 mb-16`,children:(0,l.jsxs)(n.kt.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,l.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,l.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,l.jsx)(h,{className:`w-7 h-7 md:w-8 md:h-8 ${m.tint} ${!e&&s===`checking`?`animate-pulse`:``}`})}),(0,l.jsx)(`h1`,{className:`text-2xl md:text-3xl font-extrabold mb-3 text-foreground tracking-tight`,children:m.title}),(0,l.jsxs)(`div`,{className:`text-[14px] md:text-[15px] text-foreground/60 mb-6 md:mb-8 leading-[1.6] tracking-wide`,children:[e&&(0,l.jsx)(`p`,{children:`Nothing was charged. You can try again whenever you like.`}),!e&&s===`checking`&&(0,l.jsx)(`p`,{children:`One moment — confirming with the payment provider.`}),!e&&s===`paid`&&(0,l.jsxs)(`p`,{children:[d?.amountTotal!=null&&d?.currency?`Your payment of ${d.amountTotal} ${d.currency.toUpperCase()} went through.`:`Your payment went through.`,d?.customerEmail?` A receipt is on its way to ${d.customerEmail}.`:``]}),!e&&s===`unpaid`&&(0,l.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&&s===`error`&&(0,l.jsxs)(`p`,{children:[d?.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,l.jsxs)(`div`,{className:`flex flex-col gap-3 max-w-[360px] mx-auto`,children:[!e&&(s===`unpaid`||s===`error`)&&(0,l.jsx)(t.h,{variant:`primary`,onClick:p,className:`w-full py-2.5 md:py-3 text-[14px] font-bold tracking-wide rounded-xl`,children:`Check again`}),(0,l.jsx)(u.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 cl({children:e,className:n,variant:i=`secondary`}){let{loading:o,configured:s}=r.D(),[c,u]=(0,a.useState)(!1),[d,f]=(0,a.useState)(null);return o||!s?null:(0,l.jsxs)(`span`,{className:`inline-flex flex-col items-stretch gap-2`,children:[(0,l.jsx)(t.h,{variant:i,className:n,onClick:async()=>{if(c)return;u(!0),f(null);let e=await r.C();e&&(f(e),u(!1))},disabled:c,children:c?`Opening…`:e??`Manage plan`}),d&&(0,l.jsx)(`span`,{role:`alert`,className:`text-[13px] font-semibold text-red-400 leading-snug`,children:d})]})}function ll(e){return e.status===`past_due`?{label:`Past due`,tone:`bad`}:e.active?{label:`Active`,tone:`good`}:{label:`Cancelled`,tone:`quiet`}}function ul(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}`}var dl=e=>e?new Date(e*1e3).toLocaleDateString(void 0,{day:`numeric`,month:`short`,year:`numeric`}):``;function fl({label:e,tone:t}){return(0,l.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 pl({payment:e}){let t=Ms({kind:`charge`,email:null,name:null,...e});return(0,l.jsxs)(`div`,{className:`flex items-center gap-3 px-3.5 py-2.5 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.description||`One-off payment`}),(0,l.jsx)(`span`,{className:`text-[11px] text-foreground/45 font-medium truncate`,children:dl(e.created)})]}),(0,l.jsx)(`span`,{className:`text-[12.5px] font-semibold text-foreground/70 whitespace-nowrap shrink-0`,children:Ns(e.amount,e.currency)}),(0,l.jsx)(fl,{label:t.label,tone:t.tone})]})}function ml({sub:e}){let t=ll(e),r=ul(e);return(0,l.jsxs)(`div`,{className:`flex flex-col gap-3 px-3.5 py-3 ${n.n}`,children:[(0,l.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,l.jsxs)(`div`,{className:`flex flex-col gap-0.5 min-w-0 flex-1`,children:[(0,l.jsx)(`span`,{className:`text-[13px] font-bold text-foreground truncate`,children:e.productName||`Subscription`}),(0,l.jsxs)(`span`,{className:`text-[11px] text-foreground/45 font-medium truncate`,children:[Ns(e.amount,e.currency),e.interval?` / ${e.interval}`:``,r?` — ${r}`:``]})]}),(0,l.jsx)(fl,{label:t.label,tone:t.tone})]}),(0,l.jsx)(cl,{className:`self-start`})]})}function hl(){let{user:e}=r.j(),{loading:t,subscriptions:i,payments:a,error:o}=r.E(),s=!t&&!o&&i.length===0&&a.length===0;return(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-6`,children:[(0,l.jsx)(r.y,{children:`Billing`}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/billing`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-6 flex-1 pb-16`,children:[(0,l.jsx)(se,{}),(0,l.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:t?(0,l.jsx)(`div`,{className:`flex items-center justify-center flex-1 text-foreground/40 py-16`,children:(0,l.jsx)(n.yn,{className:`w-6 h-6 animate-spin text-accent`})}):o?(0,l.jsx)(`p`,{className:`text-[12.5px] font-medium leading-relaxed px-1 text-red-500`,children:o}):s?(0,l.jsx)(n.u,{icon:n.on,title:`Nothing here yet`,description:`No payments have been made on this account.`,collapsible:!1,children:(0,l.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,l.jsxs)(l.Fragment,{children:[` (`,(0,l.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,l.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[i.length>0&&(0,l.jsx)(n.u,{icon:n.Hn,title:i.length===1?`Your subscription`:`Your subscriptions`,description:`Manage plan opens Stripe's own portal — cancel, switch, card, invoices.`,collapsible:!1,children:(0,l.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:i.map(e=>(0,l.jsx)(ml,{sub:e},e.id))})}),a.length>0&&(0,l.jsx)(n.u,{icon:n.on,title:`Your payments`,description:`Every payment on this account, straight from Stripe.`,collapsible:!1,children:(0,l.jsx)(`div`,{className:`flex flex-col gap-2.5`,children:a.map(e=>(0,l.jsx)(pl,{payment:e},e.id))})})]})})]})]})}var gl={contentKey:`dashboard`};function _l(){let{user:e}=r.j(),t=n.br(),[i,o]=(0,a.useState)(null),[s,c]=(0,a.useState)(()=>typeof window<`u`&&!$c(gl));(0,a.useEffect)(()=>{if($c(gl))return;let e=!1;nl(gl).then(t=>{e||(t&&o(()=>t),c(!1))});let t=setTimeout(()=>{e||c(!1)},4e3);return()=>{e=!0,clearTimeout(t)}},[]);let u=t.microcomponents?.dashboard||(typeof window<`u`?window.__FBOS_MICROCOMPONENTS__?.dashboard:void 0)||i||void 0,d=(e?.displayName||e?.email?.split(`@`)[0]||`there`).split(` `)[0],f=d.charAt(0).toUpperCase()+d.slice(1);return(0,l.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,l.jsxs)(n.kt.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},className:`mb-8`,children:[(0,l.jsxs)(r.y,{children:[`Welcome back, `,f,`.`]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2 text-foreground/40 font-bold uppercase tracking-[0.2em] text-[11px]`,children:[(0,l.jsx)(`span`,{className:`w-8 h-[1px] bg-foreground/10`}),`/dashboard`]})]}),(0,l.jsxs)(`div`,{className:`flex flex-col gap-4 flex-1 min-h-[500px]`,children:[(0,l.jsx)(`div`,{className:`flex justify-start`,children:(0,l.jsx)(se,{})}),(0,l.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)] ${u?`p-6 md:p-8`:`p-8 md:p-12 flex items-center justify-center`}`,children:[(0,l.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`}),u?(0,l.jsx)(`div`,{className:`fbos-content-slot relative z-10`,children:(0,l.jsx)(u,{})}):s?(0,l.jsx)(n.yn,{className:`w-6 h-6 text-accent animate-spin relative z-10`}):(0,l.jsx)(n.At,{mode:`wait`,children:(0,l.jsxs)(n.kt.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,l.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,l.jsx)(n.Vn,{className:`w-6 h-6`})}),(0,l.jsx)(`h2`,{className:`text-2xl font-extrabold text-foreground mb-2`,children:`No data added here yet`}),(0,l.jsx)(`p`,{className:`text-foreground/40 font-medium`,children:`Keep moving forward, your data will appear here.`})]})})]})]})]})}var vl=()=>(0,l.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,l.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,l.jsx)(n.Vn,{className:`w-6 h-6 text-accent animate-pulse`})}),(0,l.jsxs)(`div`,{className:`flex items-center gap-3 glass-panel px-5 py-2.5 rounded-full border border-[var(--panel-border)]`,children:[(0,l.jsx)(`div`,{className:`w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin`}),(0,l.jsx)(`span`,{className:`text-[13px] font-bold tracking-widest uppercase text-foreground/70`,children:`Connecting`})]})]});function yl({level:e,children:t}){let{user:n,userRole:i,loading:a,userInactive:o,signOut:s,roleResolved:c}=r.j(),d=(0,u.useLocation)();return a||!c?(0,l.jsx)(vl,{}):n?o?(0,l.jsx)(vr,{tone:`red`,title:`Access Denied`,message:`You don't have access to this app. Please contact the administrator.`,action:(0,l.jsx)(`button`,{onClick:()=>s(),className:yr,children:`Sign Out`})}):n.emailVerified?e===`admin`&&!r.L(i)?(0,l.jsx)(wr,{}):e===`internal`&&!r.I(i)?(0,l.jsx)(Cr,{}):(0,l.jsx)(l.Fragment,{children:t}):(0,l.jsx)(u.Navigate,{to:`/verify`}):(0,l.jsx)(u.Navigate,{to:`/login?from=${encodeURIComponent(d.pathname)}`})}var bl=({children:e})=>(0,l.jsx)(yl,{level:`signed-in`,children:e}),xl=({children:e})=>(0,l.jsx)(yl,{level:`admin`,children:e}),Sl=({children:e})=>(0,l.jsx)(yl,{level:`internal`,children:e});function Cl({children:e}){let{user:t,loading:n,roleResolved:i}=r.j(),[a]=(0,u.useSearchParams)();return n||!i?(0,l.jsx)(vl,{}):t&&t.emailVerified?(0,l.jsx)(u.Navigate,{to:a.get(`from`)||`/dashboard`,replace:!0}):(0,l.jsx)(l.Fragment,{children:e})}function wl({children:e}){let{user:t,loading:n,roleResolved:i}=r.j();return n||!i?(0,l.jsx)(vl,{}):t?t.emailVerified?(0,l.jsx)(u.Navigate,{to:`/dashboard`}):(0,l.jsx)(l.Fragment,{children:e}):(0,l.jsx)(u.Navigate,{to:`/`})}function Tl(){return(0,l.jsxs)(`div`,{className:`fixed top-0 left-0 w-full h-full pointer-events-none -z-0 overflow-hidden`,children:[(0,l.jsx)(n.kt.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,l.jsx)(n.kt.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 El(){let e=n.br().components?.Home||L;return(0,l.jsx)(r.A,{children:(0,l.jsxs)(`div`,{className:`min-h-screen relative flex flex-col overflow-x-hidden`,children:[(0,l.jsx)(I,{}),(0,l.jsxs)(u.Routes,{children:[(0,l.jsx)(u.Route,{path:`/`,element:(0,l.jsx)(Cl,{children:(0,l.jsx)(`div`,{className:`fbos-home-slot contents`,children:(0,l.jsx)(e,{})})})}),(0,l.jsx)(u.Route,{path:`/register`,element:(0,l.jsx)(Cl,{children:(0,l.jsx)(G,{})})}),(0,l.jsx)(u.Route,{path:`/login`,element:(0,l.jsx)(Cl,{children:(0,l.jsx)(K,{})})}),(0,l.jsx)(u.Route,{path:`/reset-password`,element:(0,l.jsx)(Cl,{children:(0,l.jsx)(le,{})})}),(0,l.jsx)(u.Route,{path:`/verify`,element:(0,l.jsx)(wl,{children:(0,l.jsx)(q,{})})}),(0,l.jsx)(u.Route,{path:`/book/:id`,element:(0,l.jsx)(bc,{})}),(0,l.jsx)(u.Route,{path:`/pay/:id`,element:(0,l.jsx)(Sc,{})}),(0,l.jsx)(u.Route,{path:`/payment-complete`,element:(0,l.jsx)(sl,{})}),(0,l.jsx)(u.Route,{path:`/payment-cancelled`,element:(0,l.jsx)(sl,{cancelled:!0})}),(0,l.jsx)(u.Route,{path:`/guide`,element:(0,l.jsx)(et,{})}),(0,l.jsx)(u.Route,{path:`/templates`,element:(0,l.jsx)(Be,{})}),(0,l.jsx)(u.Route,{path:`/board`,element:(0,l.jsx)(it,{})}),(0,l.jsx)(u.Route,{path:`/table`,element:(0,l.jsx)(Pn,{})}),(0,l.jsx)(u.Route,{path:`/calendar`,element:(0,l.jsx)(Ln,{})}),(0,l.jsx)(u.Route,{path:`/drive`,element:(0,l.jsx)(Fe,{})}),(0,l.jsx)(u.Route,{path:`/inline_form`,element:(0,l.jsx)(tt,{})}),(0,l.jsx)(u.Route,{path:`/popup_form`,element:(0,l.jsx)(nt,{})}),(0,l.jsx)(u.Route,{path:`/users`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(pe,{})})}),(0,l.jsx)(u.Route,{path:`/users/:id`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(pe,{})})}),(0,l.jsx)(u.Route,{path:`/inbox`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(je,{})})}),(0,l.jsx)(u.Route,{path:`/payments`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(Rs,{})})}),(0,l.jsx)(u.Route,{path:`/schedule`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(nc,{})})}),(0,l.jsx)(u.Route,{path:`/my-calendar`,element:(0,l.jsx)(Sl,{children:(0,l.jsx)(dc,{})})}),(0,l.jsx)(u.Route,{path:`/email`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(Nc,{})})}),(0,l.jsx)(u.Route,{path:`/submissions`,element:(0,l.jsx)(u.Navigate,{to:`/inbox`,replace:!0})}),(0,l.jsx)(u.Route,{path:`/requests`,element:(0,l.jsx)(u.Navigate,{to:`/inbox`,replace:!0})}),(0,l.jsx)(u.Route,{path:`/assets`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(ze,{})})}),(0,l.jsx)(u.Route,{path:`/drive/:rest`,element:(0,l.jsx)(u.Navigate,{to:`/assets`,replace:!0})}),(0,l.jsx)(u.Route,{path:`/theme`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(_r,{})})}),(0,l.jsx)(u.Route,{path:`/pages/*`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(Io,{})})}),(0,l.jsx)(u.Route,{path:`/forms/*`,element:(0,l.jsx)(xl,{children:(0,l.jsx)(es,{})})}),(0,l.jsx)(u.Route,{path:`/settings`,element:(0,l.jsx)(u.Navigate,{to:`/pages`,replace:!0})}),(0,l.jsx)(u.Route,{path:`/profile`,element:(0,l.jsx)(bl,{children:(0,l.jsx)(ce,{})})}),(0,l.jsx)(u.Route,{path:`/billing`,element:(0,l.jsx)(bl,{children:(0,l.jsx)(hl,{})})}),(0,l.jsx)(u.Route,{path:`/dashboard`,element:(0,l.jsx)(bl,{children:(0,l.jsx)(_l,{})})}),(0,l.jsx)(u.Route,{path:`/setup`,element:(0,l.jsx)(r.u,{})}),(0,l.jsx)(u.Route,{path:`/setup/payments`,element:(0,l.jsx)(r.n,{})}),(0,l.jsx)(u.Route,{path:`*`,element:(0,l.jsx)(il,{})})]}),(0,l.jsx)(Tl,{})]})})}function Dl(){return(0,l.jsx)(u.BrowserRouter,{children:(0,l.jsx)(Ol,{})})}function Ol(){let e=n.br();return e.firebaseConfig&&e.firebaseConfig.apiKey&&e.firebaseConfig.apiKey.trim()!==``&&e.firebaseConfig.projectId&&e.firebaseConfig.projectId.trim()!==``||r.d()?(0,l.jsx)(El,{}):(0,l.jsxs)(`div`,{className:`min-h-screen relative flex flex-col overflow-x-hidden`,children:[(0,l.jsx)(I,{standalone:!0}),(0,l.jsx)(r.u,{standalone:!0}),(0,l.jsx)(Tl,{})]})}function kl(e){b();let r=e.firebaseConfig;return r&&r.apiKey&&r.apiKey.trim()!==``&&r.projectId&&r.projectId.trim()!==``&&n.Cr(r),(0,l.jsx)(n.yr,{config:{firebaseConfig:e.firebaseConfig,adminEmails:e.adminEmails,basename:e.basename,onAuthChange:e.onAuthChange,themeConfig:e.themeConfig,components:e.components,customRoutes:e.customRoutes,microcomponents:e.microcomponents,defaultConfigs:e.defaultConfigs},children:(0,l.jsx)(t.v,{children:(0,l.jsx)(`div`,{className:`firebase-os flex-1 flex flex-col min-h-screen`,style:{background:`var(--bg-gradient)`,color:`var(--fg-color)`},children:(0,l.jsx)(Dl,{})})})})}var Al=Object.assign({}),jl={};for(let e in Al){let t=Al[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();jl[r]=t.default,jl[r.replace(/_/g,``)]=t.default}if(typeof window<`u`){let e=window.__FBOS_MICROCOMPONENTS__||{};window.__FBOS_MICROCOMPONENTS__={...jl,...e}}var Ml=(e,t)=>{let n=e.toLowerCase().replace(/[^a-z0-9]+/g,`_`),r=n.replace(/_/g,``);if(jl[n]=t,jl[r]=t,typeof window<`u`){let e=window.__FBOS_MICROCOMPONENTS__||{};window.__FBOS_MICROCOMPONENTS__={...e,[n]:t,[r]:t}}};function Nl(...e){return n.Dt(n.Ot(e))}var Pl=({title:e,className:t,children:n,...r})=>(0,l.jsxs)(`div`,{className:Nl(`border border-[var(--panel-border)] bg-[var(--panel-bg)] px-5 py-4`,t),style:{borderRadius:`var(--card-radius, 1rem)`},...r,children:[e?(0,l.jsx)(`p`,{className:`text-[12px] font-extrabold tracking-tight text-gradient mb-1.5`,children:e}):null,n]});Pl.displayName=`Card`;function Fl(...e){return n.Dt(n.Ot(e))}var Il=({sub:e,className:t,children:n,...r})=>(0,l.jsxs)(`div`,{className:Fl(`mb-4`,t),children:[(0,l.jsx)(`h2`,{className:`text-xl md:text-2xl font-extrabold tracking-tight text-foreground`,...r,children:n}),e?(0,l.jsx)(`p`,{className:`text-[13px] text-foreground/60 font-medium leading-relaxed mt-1`,children:e}):null]});Il.displayName=`SectionHeading`,exports.AdminNotifications=T,exports.Button=t.h,exports.Card=Pl,exports.ConfirmModal=me,exports.ContactPopup=t.t,exports.CustomSelect=n.Et,exports.DashboardNav=se,exports.FirebaseOS=kl,exports.Input=t.g,exports.ManagePlanButton=cl,exports.Navbar=I,exports.PayButton=xc,exports.PhoneInputField=i.t,exports.SectionHeading=Il,Object.defineProperty(exports,`auth`,{enumerable:!0,get:function(){return n.xr}}),exports.bookingPath=n.H,exports.cancelBooking=t.n,exports.confirmPayment=r.x,Object.defineProperty(exports,`db`,{enumerable:!0,get:function(){return n.Sr}}),exports.emailAnyone=Ni,exports.emailOwner=ji,exports.emailPerson=Mi,exports.emailStatus=Fi,exports.notify=w,exports.openBillingPortal=r.C,exports.payPath=n.et,exports.registerMicrocomponent=Ml,exports.startCheckout=r.T,Object.defineProperty(exports,`storage`,{enumerable:!0,get:function(){return n.wr}}),exports.useAuth=r.j,exports.useBookings=t.s,exports.useConfig=n.br,exports.useMyPayments=r.E,exports.usePaymentsEnabled=r.D,exports.useSales=r.O,exports.useTheme=t.y;
|