1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/onboardingEvents-iM3xWPll.js","assets/index-CbvCveKN.js","assets/index-DK9kCj9D.css","assets/estimatePdf-BnRXCDbF.js","assets/EstimateDocument-D2NBvf9z.js","assets/jspdf.es.min-CH-oufHI.js","assets/format-BZAqQT85.js","assets/en-US-wdCzBwgh.js","assets/differenceInCalendarDays-BmAYwV3_.js"])))=>i.map(i=>d[i]); 2import{A as Te,r as d,j as e,k as _e,C as J,B as k,o as w,D as Ie,E as nt,z as ne,I as $e,g as I,X as ge,G as rt,J as kt,K as O,l as Nt,N as St,_ as it,m as $t,O as Ct,Q as We,S as Et,L as X,T as Tt,U as It,V as Dt,W as qt,Y as Ft,Z as Mt,$ as ot,a0 as Pt,a1 as Ot,a2 as At,q as Rt,a3 as Lt}from"./index-CbvCveKN.js";import{R as lt,C as dt,S as Wt,a as Bt,b as zt,c as Ht,U as ct,E as Kt,f as Be,D as Yt,P as Ut}from"./PageContainer-Bx7SVsdy.js";import{f as G}from"./format-BZAqQT85.js";import{P as Qt}from"./plus-kYCBPFxU.js";import{l as mt,f as ze,S as ut,e as Gt,a as Jt,F as Vt,n as Xt}from"./FinishSetupForm-DTBys4UK.js";import{logOnboarding as T}from"./onboardingEvents-iM3xWPll.js";import{T as Zt}from"./textarea-BGGCYgxW.js";import{C as es}from"./checkbox-DibQEMjb.js";import{f as pt,S as ts,a as ss,H as as,l as ns,n as rs,r as is}from"./concierge-BidFqpW_.js";import{C as ye}from"./check-Bjw6cCk6.js";import{M as os}from"./message-square-text-D6Fv0jYK.js";import{F as ls}from"./file-spreadsheet-C065uECT.js";import{P as ds}from"./paperclip-DvFV8ZAn.js";import{R as cs}from"./rocket-CokyUU3P.js";import{C as ms}from"./chevron-right-f4vsMuAf.js";import{S as ht}from"./send-gD9LtlB-.js";import{U as us}from"./upload-BDKwK5D_.js";import{C as ft}from"./clock-v0Ie3bhO.js";import{w as ps}from"./appUrl-DO9lm0kM.js";import{a as hs}from"./templates-DNmeeYY2.js";import{T as fs}from"./TemplateIcon-CN0RSA5P.js";import{E as xs}from"./external-link-DtZsaCxu.js";import{m as gs}from"./jobShared-Dn-iCgbr.js";import{e as ys,l as _s,a as bs}from"./equipment-COx_XtNw.js";import{D as ws,b as vs}from"./maintenance-D4U-TS6n.js";import{e as ue,i as js}from"./pipeline-57THQ7iX.js";import{s as ks}from"./differenceInCalendarDays-BmAYwV3_.js";import{s as Ns}from"./startOfMonth-D-6yZJC1.js";import{t as Ss,c as $s,m as Cs}from"./en-US-wdCzBwgh.js";import{a as je}from"./addDays-eG_rRTHr.js";import{T as De}from"./Tray-lZQUbX4C.js";import{G as He}from"./GrainGradient-kJbOtAvv.js";import{W as xt}from"./wrench-CG-mx_ij.js";import{N as Es}from"./navigation-ioJs3N7t.js";import{P as Ts}from"./phone-C9i08TZ5.js";import{C as Is}from"./chevron-down-yKD6BMcU.js";import{A as Ds}from"./arrow-right-dw9dfM3J.js";import{C as qs}from"./circle-alert-CxgmNrG_.js";import{R as Fs}from"./users-BkZzL3s4.js";import{C as Ms}from"./parseISO-B0WEjCD3.js";import{M as Ps}from"./message-square-bjNINuLT.js";import{F as Os}from"./file-text-DDhZ7a0t.js";import{P as As}from"./percent-pp0svK_U.js";import{T as Ce}from"./triangle-alert-BJBV5PBt.js";import"./index-Jf4OHjGl.js";import"./layout-dashboard-rEexJXnQ.js";import"./ek-mark-light-Y4_w-cFG.js";import"./plug-BAhKXAxN.js";import"./index-DlFerWUd.js";import"./snowflake-CDB4vx7u.js";import"./isToday-CHwM1qlQ.js";import"./isSameDay-m0yeLtak.js";import"./photos-DjMSdZLU.js";/** 3 * @license lucide-react v0.462.0 - ISC 4 * 5 * This source code is licensed under the ISC license. 6 * See the LICENSE file in the root directory of this source tree. 7 */const Rs=Te("Image",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",ry:"2",key:"1m3agn"}],["circle",{cx:"9",cy:"9",r:"2",key:"af1f0g"}],["path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21",key:"1xmnt7"}]]);/** 8 * @license lucide-react v0.462.0 - ISC 9 * 10 * This source code is licensed under the ISC license. 11 * See the LICENSE file in the root directory of this source tree. 12 */const Ls=Te("MailX",[["path",{d:"M22 13V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h9",key:"1j9vog"}],["path",{d:"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7",key:"1ocrg3"}],["path",{d:"m17 17 4 4",key:"1b3523"}],["path",{d:"m21 17-4 4",key:"uinynz"}]]);/** 13 * @license lucide-react v0.462.0 - ISC 14 * 15 * This source code is licensed under the ISC license. 16 * See the LICENSE file in the root directory of this source tree. 17 */const Ws=Te("Smartphone",[["rect",{width:"14",height:"20",x:"5",y:"2",rx:"2",ry:"2",key:"1yt0o3"}],["path",{d:"M12 18h.01",key:"mhygvu"}]]);function Bs(t,a){const i=+Ss(t);return $s(t,i+a)}function zs(t,a){return Bs(t,a*Cs)}function Hs(t,a){return zs(t,-a)}const Ks=t=>
17{const[a,i]=d.useState(!1),[o,n]=d.useState(0),c=d.useRef(0),u=d.useRef(!1);return d.useEffect(()=>{let m=0,x=0;const v=b=>{window.scrollY===0&&!u.current&&(m=b.touches[0].clientY,c.current=m)},j=b=>{if(window.scrollY===0&&c.current>0&&!u.current){x=b.touches[0].clientY;const S=Math.max(0,(x-m)*.5);S>0&&(n(S),i(!0))}},N=async()=>{if(o>80&&!u.current){u.current=!0,n(80);try{await t()}finally{setTimeout(()=>{n(0),i(!1),u.current=!1,c.current=0},500)}}else n(0),i(!1),c.current=0};return document.addEventListener("touchstart",v,{passive:!0}),document.addEventListener("touchmove",j,{passive:!0}),document.addEventListener("touchend",N),()=>{document.removeEventListener("touchstart",v),document.removeEventListener("touchmove",j),document.removeEventListener("touchend",N)}},[o,t]),{isPulling:a,pullDistance:o}},Ys=({onRefresh:t,children:a})=>{const{isPulling:i,pullDistance:o}=Ks(t);return e.jsxs("div",{className:"relative",children:[e.jsx("div",{className:"fixed top-0 left-0 right-0 flex items-center justify-center transition-all duration-200 z-50",style:{transform:`translateY(${Math.min(o-60,0)}px)`,opacity:Math.min(o/80,1)},children:e.jsx("div",{className:"rounded-full border border-ink/10 bg-popover p-3 text-cta-orange shadow-lg",children:e.jsx(lt,{className:`h-5 w-5 ${o>80?"animate-spin":""}`,style:{transform:`rotate(${o*3}deg)`}})})}),e.jsx("div",{style:{transform:i?`translateY(${Math.min(o,100)}px)`:"none",transition:i?"none":"transform 0.3s ease"},children:a})]})},Us=()=>{const t=_e(),[a,i]=d.useState(new Date),{data:o}=J({queryKey:["user"],queryFn:async()=>{const{data:{user:c}}=await w.auth.getUser();if(!c)return null;const{data:u}=await w.from("users").select("company_name").eq("id",c.id).single();return{...c,company_name:(u==null?void 0:u.company_name)||"Company"}}});d.useEffect(()=>{const c=setInterval(()=>i(new Date),6e4);return()=>clearInterval(c)},[]);const n=(()=>{const c=a.getHours();return c<12?"Good morning":c<17?"Good afternoon":"Good evening"})();return e.jsxs("div",{className:"flex flex-col gap-4 sm:flex-row sm:flex-wrap sm:items-end sm:justify-between",children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-2",children:[e.jsxs("p",{className:"font-mono text-[12px] uppercase tracking-[0.08em] text-foreground-tertiary",children:[G(a,"EEEE, MMMM d")," · ",G(a,"h:mm a")]}),e.jsxs("h1",{className:"break-words text-[22px] font-semibold leading-[1.1] tracking-[-0.02em] text-foreground md:text-[24px]",children:[n,o!=null&&o.company_name?`, ${o.company_name}`:""]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:flex sm:items-center",children:[e.jsxs(k,{variant:"outline",onClick:()=>t("/jobs/new"),className:"h-11 md:h-9 gap-2",children:[e.jsx(dt,{className:"h-4 w-4",strokeWidth:1.8}),"Schedule job"]}),e.jsxs(k,{variant:"outline",onClick:()=>t("/estimates/new"),className:"h-11 md:h-9 gap-2",children:[e.jsx(Qt,{className:"h-4 w-4",strokeWidth:1.8}),"New estimate"]})]})]})},Ke="ek-concierge-hidden-at",Qs=3*24*60*60*1e3,Gs=[{value:"morning",label:"Morning"},{value:"afternoon",label:"Afternoon"},{value:"evening",label:"Evening"},{value:"any",label:"Any time"}],Ye=t=>I("min-h-0 rounded-md px-2.5 py-2 text-left text-[12.5px] font-medium transition-colors",t?"bg-foreground text-background":"bg-ink/[0.05] text-foreground-secondary hover:bg-ink/[0.09] hover:text-foreground"),gt=({open:t,onOpenChange:a,onSent:i,source:o})=>{const[n,c]=d.useState(""),[u,m]=d.useState(["price_book","first_quote"]),[x,v]=d.useState("any"),[j,N]=d.useState(""),[b,S]=d.useState(null),[A,H]=d.useState(!0),[K,h]=d.useState(!1),y=d.useRef(null);d.useEffect(()=>{t&&T("concierge_opened",{source:o})},[t,o]);const D=async()=>{if(!kt("A setup request"))return;const p=n.trim()?rs(n):null;if(n.trim()&&!p){O({title:"Check the number",description:"Enter a mobile number like (604) 555-0102.",variant:"destructive"});return}if(!p&&!b&&!j.trim()){O({title:"Add a number or a file",description:"Leave a mobile number so we can text you, or attach your price sheet.",variant:"destructive"});return}if(b&&b.size>20*1024*1024){O({title:"That file is over 20 MB",description:"Send a smaller export, or text it once we're in touch.",variant:"destructive"});return}h(!0);try{await is({phone:p,bestTime:x,helpWith:u,note:j,file:b,smsOptIn:!!p&&A}),T("concierge_requested",{source:o,help:u,has_file:!!b,has_phone:!!p,sms_opt_in:!!p&&A}
17),O({title:"Sent. Travis will be in touch today.",description:p?`By text at ${pt(p)}.`:"By email."}),i==null||i(),a(!1)}catch($){O({title:"Couldn't send that",description:$ instanceof Error?$.message:"Try again.",variant:"destructive"})}finally{h(!1)}};return e.jsx(Wt,{open:t,onOpenChange:a,children:e.jsxs(Bt,{side:"right",className:"flex w-full flex-col gap-5 overflow-y-auto p-5 sm:max-w-md","data-concierge-sheet":!0,children:[e.jsxs("div",{children:[e.jsx(zt,{className:"text-[16px]",children:"We'll set it up with you"}),e.jsx(Ht,{className:"mt-1 text-[13px] leading-[1.5]",children:"Free during your trial. Send your supplier price sheet and we load it; then we build your first real quote together in about 15 minutes."})]}),ts,e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx(ne,{htmlFor:"cc-phone",className:"text-[12.5px] font-normal text-foreground-secondary",children:"Mobile number"}),e.jsx($e,{id:"cc-phone",type:"tel",inputMode:"tel",autoComplete:"tel",value:n,onChange:p=>c(p.target.value),placeholder:"(604) 555-0102",className:"font-mono"}),n.trim()&&e.jsxs("label",{className:"mt-1 flex items-start gap-2.5 text-[12px] leading-[1.45] text-foreground-secondary",children:[e.jsx(es,{checked:A,onCheckedChange:p=>H(p===!0),className:"mt-0.5"}),e.jsx("span",{children:ss})]})]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(ne,{className:"text-[12.5px] font-normal text-foreground-secondary",children:"What should we set up?"}),e.jsx("div",{className:"grid grid-cols-2 gap-1.5",children:as.map(p=>{const $=u.includes(p.value);return e.jsx("button",{type:"button","aria-pressed":$,className:Ye($),onClick:()=>m($?u.filter(Y=>Y!==p.value):[...u,p.value]),children:p.label},p.value)})})]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx(ne,{className:"text-[12.5px] font-normal text-foreground-secondary",children:"Best time to reach you"}),e.jsx("div",{className:"grid grid-cols-4 gap-1.5",children:Gs.map(p=>e.jsx("button",{type:"button","aria-pressed":x===p.value,className:I(Ye(x===p.value),"text-center"),onClick:()=>v(p.value),children:p.label},p.value))})]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs(ne,{className:"text-[12.5px] font-normal text-foreground-secondary",children:["Supplier price sheet ",e.jsx("span",{className:"text-foreground-tertiary",children:"(optional)"})]}),e.jsx("input",{ref:y,type:"file",className:"hidden",accept:".csv,.xlsx,.xls,.pdf,.png,.jpg,.jpeg,.heic,.txt",onChange:p=>{var $;return S((($=p.target.files)==null?void 0:$[0])??null)}}),b?e.jsxs("div",{className:"flex items-center gap-2.5 rounded-lg border border-ink/[0.08] bg-card px-3 py-2.5",children:[e.jsx(ls,{className:"h-4 w-4 shrink-0 text-foreground-tertiary",strokeWidth:1.8}),e.jsx("span",{className:"min-w-0 flex-1 truncate text-[13px]",children:b.name}),e.jsx("button",{type:"button","aria-label":"Remove file",onClick:()=>{S(null),y.current&&(y.current.value="")},className:"text-foreground-tertiary hover:text-foreground",children:e.jsx(ge,{className:"h-4 w-4"})})]}):e.jsxs(k,{type:"button",variant:"outline",className:"justify-start gap-2",onClick:()=>{var p;return(p=y.current)==null?void 0:p.click()},children:[e.jsx(ds,{className:"h-4 w-4",strokeWidth:1.8})," Attach a spreadsheet, PDF or photo"]}),e.jsx("p",{className:"text-[12px] text-foreground-tertiary",children:"Whatever your supplier sends: a CSV, an Excel export, a PDF, even a photo of the page."})]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs(ne,{htmlFor:"cc-note",className:"text-[12.5px] font-normal text-foreground-secondary",children:["Anything we should know ",e.jsx("span",{className:"text-foreground-tertiary",children:"(optional)"})]}),e.jsx(Zt,{id:"cc-note",value:j,onChange:p=>N(p.target.value),placeholder:"Mostly furnace and AC replacements. I quote from a spreadsheet today.",className:"min-h-[72px]"})]}),e.jsxs("div",{className:"mt-auto flex gap-2 pt-2",children:[e.jsx(k,{variant:"outline",className:"flex-1",onClick:()=>a(!1),children:"Cancel"}),e.jsx(k,{variant:"orange",className:"flex-1","data-write":!0,disabled:K,onClick:()=>void D(),children:K?"Sendingâ¦":"Send to Travis"})]})]})})},Js=({trialing:t})=>
17{const a=Ie(),[i,o]=d.useState(!1),[n,c]=d.useState(()=>{try{const N=Number(nt(Ke)||0);return N>0&&Date.now()-N<Qs}catch{return!1}}),{data:u,isLoading:m}=J({queryKey:["concierge-request"],queryFn:ns,enabled:t,staleTime:6e4});d.useEffect(()=>{const N=new URLSearchParams(window.location.search);if(N.get("concierge")!=="1")return;c(!1),o(!0),N.delete("concierge");const b=N.toString();window.history.replaceState(null,"",`${window.location.pathname}${b?`?${b}`:""}`)},[]);const x=t&&!m&&!n;d.useEffect(()=>{x&&!u&&T("concierge_card_shown")},[x,u]);const v=e.jsx(gt,{open:i,onOpenChange:o,source:x?"dashboard_card":"email_link",onSent:()=>a.invalidateQueries({queryKey:["concierge-request"]})});if(!x)return i?v:null;if(u)return e.jsxs("div",{className:"flex items-center gap-3.5 rounded-xl border border-ink/[0.06] bg-card px-5 py-4","data-concierge-card":"sent",children:[e.jsx("span",{className:"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[#12B76A]/15",children:e.jsx(ye,{className:"h-4 w-4 text-ok",strokeWidth:1.8})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"text-[14px] font-medium",children:"Setup help is on its way"}),e.jsx("p",{className:"text-[13px] text-foreground-secondary",children:u.status==="done"?"All set. Reply to any email from Travis if you need more.":u.phone?`Travis will text ${pt(u.phone)}.`:"Travis will email you."})]})]});const j=()=>{c(!0);try{rt(Ke,String(Date.now()))}catch{}T("concierge_card_hidden")};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-col gap-4 roun
17ded-xl border border-ink/[0.06] bg-card p-5 md:flex-row md:items-center","data-concierge-card":!0,children:[e.jsx("span",{className:"hidden h-10 w-10 shrink-0 items-center justify-center rounded-full bg-cta-orange/15 md:flex",children:e.jsx(os,{className:"h-5 w-5 text-foreground-secondary",strokeWidth:1.8})}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"text-[14.5px] font-semibold",children:"Want it set up for you? Free."}),e.jsx("p",{className:"mt-0.5 text-[13px] leading-[1.5] text-foreground-secondary",children:"Send your supplier price sheet. We load your price book, then build your first real quote with you in about 15 minutes."})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[e.jsx(k,{variant:"ghost",size:"sm",onClick:j,className:"text-foreground-tertiary",children:"Not now"}),e.jsx(k,{variant:"orange",size:"sm","data-write":!0,onClick:()=>o(!0),children:"Set it up with me"})]})]}),v]})},ie=[{key:"first_win",label:"See what your customer sees",hint:"Send a sample to yourself and approve it on your phone. About 4 minutes.",icon:Ws},{key:"real_send",label:"Send your first real quote",hint:"To a real homeowner. Your trial gets 7 more days when it goes out.",icon:ht},{key:"price_book",label:"Load your price book",hint:"Import your supplier sheet, or send it to us and we'll load it.",icon:us},{key:"logo",label:"Add your logo",hint:"It goes at the top of every quote.",icon:Rs},{key:"team",label:"Invite a technician",hint:"Up to 25 people on your plan, no per-seat fees.",icon:ct}],Vs=7*24*60*60*1e3,Ue=t=>`ek-getting-started-dismissed:${t}`,Xs=()=>{var K;const t=_e(),[a,i]=d.useState(null),[o,n]=d.useState(!1),[c,u]=d.useState(!1);d.useEffect(()=>{w.auth.getUser().then(({data:{user:h}})=>{if(h){i(h.id);try{const y=Number(nt(Ue(h.id))||0);y>0&&Date.now()-y<Vs&&n(!0)}catch{}}})},[]);const m=()=>{n(!0),T("checklist_hidden");try{a&&rt(Ue(a),String(Date.now()))}catch{}},{data:x,isLoading:v}=J({queryKey:["onboarding-flags"],queryFn:async()=>{const{data:{user:h}}=await w.auth.getUser();if(!h)return null;const{data:y,error:D}=await w.from("users").select("organization_id, has_added_logo, has_imported_data, has_sent_estimate, has_invited_member, first_win_completed_at").eq("id",h.id).single();if(D||!y)return null;const{data:p}=y.organization_id?await w.from("organizations").select("subscription_status, trial_extended_at").eq("id",y.organization_id).maybeSingle():{data:null};return{done:{first_win:!!y.first_win_completed_at,real_send:!!y.has_sent_estimate,price_book:!!y.has_imported_data,logo:!!y.has_added_logo,team:!!y.has_invited_member},trialing:(p==null?void 0:p.subscription_status)==="trial",extended:!!(p!=null&&p.trial_extended_at)}},refetchInterval:1e4}),{data:j}=J({queryKey:["starter-template-id"],queryFn:async()=>{const h=await mt().catch(()=>null);return await ze(h?ut[h]:"3-Ton AC Replacement").catch(()=>null)??await ze().catch(()=>null)},staleTime:5*60*1e3}),N=h=>{switch(h){case"first_win":return"/dashboard?firstwin=1";case"real_send":return j?`/estimates/new?template=${j}`:"/estimates/new";case"price_book":return"/materials?import=1";case"logo":return"/settings?tab=company";case"team":return"/settings/team"}},b=x?ie.filter(h=>x.done[h.key]).length:0,S=b===ie.length,A=!v&&!!x&&!o;if(d.useEffect(()=>{A&&!S&&T("checklist_shown",{done:b})},[A,S,b]),d.useEffect(()=>{if(S){const h=setTimeout(()=>n(!0),5e3);return()=>clearTimeout(h)}},[S]),!A||!x)return null;if(S)return e.jsxs("div",{className:"flex items-center gap-3.5 rounded-xl border border-ink/[0.06] bg-card px-5 py-4",children:[e.jsx(cs,{className:"h-5 w-5 shrink-0 text-foreground-secondary",strokeWidth:1.8}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"text-[14px] font-semibold text-foreground",children:"You're set up"}),e.jsx("p",{className:"text-[13px] text-foreground-secondary",children:"Quotes out, price book in, team on board."})]}),e.jsx("button",{type:"button",onClick:m,"aria-label":"Dismiss",className:"flex h-11 w-11 shrink-0 items-center justify-center rounded-full text-foreground-tertiary hover:bg-ink/[0.06] hover:text-foreground md:h-9 md:w-9",children:e.jsx(ge,{className:"h-4 w-4",strokeWidth:1.8})})]});const H=(K=ie.find(h=>!x.done[h.key]))==null?void 0:K.key;return e.jsxs("div",{className:"flex flex-col gap-3.5 rounded-xl border border-ink/[0.06] bg-card p-5","data-getting-started":!0,children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("h3",{className:"text-[15px] font-semibold text-foreground",children:"Get your first quote approved"}),e.jsxs("p",{className:"text-[12.5px] text-foreground-tertiary",children:[b," of ",ie.length," done"]})]}),e.jsx("button",{type:"button",onClick:m,"aria-label":"Hide for a week",title:"Hide for a week",className:"-mr-2 flex h-9 w-9 items-center justify-center rounded-full text-foreground-tertiary transition-colors hover:bg-ink/[0.06] hover:text-foreground",children:e.jsx(ge,{className:"h-4 w-4",strokeWidth:1.8})})]}),e.jsx("div",{className:"h-1 overflow-hidden rounded-full bg-ink/[0.06]",children:e.jsx("div",{className:"h-full rounded-full bg-cta-orange transition-all duration-500",style:{width:`${b/ie.length*100}%`}})}),e.jsx("div",{className:"flex flex-col divide-y divide-ink/[0.06] overflow-hidden rounded-lg border border-ink/[0.06]",children:ie.map(h=>{const y=x.done[h.key],D=h.key===H,p=h.icon,$=h.key==="real_send"&&!y&&x.trialing&&!x.extended;return e.jsxs("div",{className:I("flex items-center gap-3 px-3.5 py-3",D?"bg-ink/[0.03]":"bg-card"),children:[y?e.jsx("span",{className:"flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-[#12B76A]/15",children:e.jsx(ye,{className:"h-3.5 w-3.5 text-ok",strokeWidth:2})}):e.jsx("span",{className:I("flex h-7 w-7 shrink-0 items-center justify-center rounded-full",D?"bg-cta-orange/15 text-cta-orange":"bg-ink/[0.06] text-foreground-secondary"),children:e.jsx(p,{className:"h-3.5 w-3.5",
17strokeWidth:1.8})}),e.jsxs("button",{type:"button",disabled:y,onClick:()=>{T("checklist_step_clicked",{step:h.key}),t(N(h.key))},className:I("flex min-w-0 flex-1 items-center gap-2 text-left",y?"cursor-default":"group"),children:[e.jsxs("span",{className:"flex min-w-0 flex-1 flex-col gap-0.5",children:[e.jsxs("span",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:I("text-[13.5px]",y?"text-foreground-tertiary line-through decoration-ink/20":"font-medium text-foreground"),children:h.label}),$&&e.jsx("span",{className:"whitespace-nowrap rounded-[5px] bg-emerald-500/15 px-1.5 py-px text-[11.5px] font-medium text-ok",children:"+7 trial days"})]}),!y&&(D||h.key==="price_book")&&e.jsx("span",{className:"text-[12px] leading-[1.45] text-foreground-secondary",children:h.hint})]}),!y&&e.jsx(ms,{className:"h-4 w-4 shrink-0 text-foreground-tertiary transition-colors group-hover:text-foreground",strokeWidth:1.8})]}),h.key==="price_book"&&!y&&e.jsx("button",{type:"button",onClick:()=>u(!0),className:"shrink-0 whitespace-nowrap text-[12.5px] font-medium text-info underline-offset-2 hover:underline",children:"Do it for me"})]},h.key)})}),e.jsx(gt,{open:c,onOpenChange:u,source:"checklist"})]})},Qe="trial_banner_dismissed",Zs=4,Ge=()=>new Date().toISOString().slice(0,10),ea=({daysRemaining:t})=>{const[a,i]=d.useState(!0),[o,n]=d.useState(!1),{toast:c}=Nt();d.useEffect(()=>{try{i(sessionStorage.getItem(Qe)===Ge())}catch{i(!1)}},[]);const u=()=>{try{sessionStorage.setItem(Qe,Ge())}catch{}i(!0)},m=async()=>{if(!St()){n(!0);try{const{data:{session:v}}=await w.auth.getSession();if(!v){c({title:"Please sign in",description:"Your session expired. Please sign in again to subscribe.",variant:"destructive"}),n(!1);return}await w.functions.invoke("ensure-provisioned",{headers:{Authorization:`Bearer ${v.access_token}`}}),it(()=>import("./onboardingEvents-iM3xWPll.js"),__vite__mapDeps([0,1,2])).then(b=>b.logOnboarding("checkout_started",{from:"trial_banner"}));const{data:j,error:N}=await w.functions.invoke("create-checkout",{headers:{Authorization:`Bearer ${v.access_token}`}});if(N)throw N;j!=null&&j.url&&(window.location.href=j.url)}catch(v){console.error("Checkout error:",v),c({title:"Checkout error",description:"We couldn't start checkout. Please try again in a moment.",variant:"destructive"}),n(!1)}}};if(a||t<=0||t>Zs)return null;const x=()=>t===1?"Trial ends today":`${t} days remaining in your trial`;return e.jsx("div",{className:"animate-fade-in rounded-xl border border-ink/[0.06] bg-card px-4 py-3 md:px-5",children:e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-3 text-[14px] text-ink/80",children:[e.jsx(ft,{className:"h-4 w-4 flex-shrink-0 text-foreground-secondary",strokeWidth:1.8}),e.jsxs("span",{children:[x()," · Subscribe to continue"]})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[e.jsx(k,{onClick:m,disabled:o,size:"sm",variant:"orange",className:"h-9 px-4 text-sm",children:o?"...":"Subscribe"}),e.jsx("button",{onClick:u,className:"flex h-9 w-9 items-center justify-center rounded-full text-foreground-tertiary transition-colors hover:bg-ink/[0.06] hover:text-foreground","aria-label":"Dismiss banner",children:e.jsx(ge,{className:"h-4 w-4",strokeWidth:1.8})})]})]})})},ke=["pick","address","send","approve","done"],Ee=t=>`ek-first-win:${t}`,yt=t=>`ek-first-win-skip:${t}`,_t=24*60*60*1e3,ta=3e3,sa=10*60*1e3,Je=t=>{try{const a=localStorage.getItem(Ee(t));return a?JSON.parse(a):null}catch{return null}},Ne=(t,a)=>{try{a?localStorage.setItem(Ee(t),JSON.stringify(a)):localStorage.removeItem(Ee(t))}catch{}},aa=t=>{try{const a=Number(localStorage.getItem(yt(t))||0);return a>0&&Date.now()-a<_t}catch{return!1}},Se=t=>`$${Math.round(t).toLocaleString("en-US")}`,fe=async t=>{const{data:a,error:i}=await w.from("estimates").select("id, status, sent_at, approved_at, approved_by_name, approved_tier_id, approval_token, client_email, client_name").eq("id",t).maybeSingle();if(i)throw i;return a},na=()=>J({queryKey:["first-win-gate"],queryFn:async()=>{const{data:{user:t}}=await w.auth.getUser();if(!t)return null;const{data:a,error:i}=await w.from("users").select("organization_id, company_name, first_win_completed_at, has_sent_estimate, first_win_estimate_id, first_win_skipped_at").eq("id",t.id).maybeSingle();if(i)throw i;if(!a)return null;let o=!0;if(a.organization_id){const{data:u}=await w.from("organizations").select("owner_id").eq("id",a.organization_id).maybeSingle();u&&(o=u.owner_id===t.id)}const n=t.user_metadata||{},c=typeof n.full_name=="string"&&n.full_name||typeof n.name=="string"&&n.name||"";return{userId:t.id,fullName:c,email:t.email||"",isOwner:o,completedAt:a.first_win_completed_at,hasSentEstimate:a.has_sent_estimate,firstWinEstimateId:a.first_win_estimate_id,companyName:a.company_name,skippedAt:a.first_win_skipped_at??null}},staleTime:3e4}),ra=()=>{const{data:t}
17=na(),[a,i]=$t(),[o,n]=d.useState(!1),[c,u]=d.useState(!1),[m,x]=d.useState(!1);return d.useEffect(()=>{if(a.get("firstwin")==="1"){n(!0);const v=new URLSearchParams(a);v.delete("firstwin"),i(v,{replace:!0})}},[a,i]),d.useEffect(()=>{if(!t||!t.isOwner)return;if(o){u(!0);return}if(m)return;x(!0);const v=t.completedAt==null&&!t.hasSentEstimate,j=!!t.skippedAt&&Date.now()-new Date(t.skippedAt).getTime()<_t;v&&!aa(t.userId)&&!j&&u(!0)},[t,o,m]),!t||!c?null:e.jsx(ia,{gate:t,replay:o&&t.completedAt!=null,onClose:()=>{u(!1),n(!1)}})},ia=({gate:t,replay:a,onClose:i})=>{const o=Ie(),{userId:n}=t,[c,u]=d.useState(null),[m,x]=d.useState(null),[v,j]=d.useState(null),[N,b]=d.useState(null),[S,A]=d.useState(""),[H,K]=d.useState(""),[h,y]=d.useState(null),[D,p]=d.useState(null),[$,Y]=d.useState(null),[R,Z]=d.useState(null),[de,pe]=d.useState(null),[M,ee]=d.useState(!1),[be,we]=d.useState(0),[ce,he]=d.useState(!1),V=d.useRef(null),L=d.useCallback(r=>{const l=Je(n)||{step:"pick"};Ne(n,{...l,...r})},[n]),U=d.useCallback(r=>{u(r),L({step:r}),T("firstwin_step",{step:r})},[L]);d.useEffect(()=>{T("firstwin_shown",{replay:a})},[a]),d.useEffect(()=>{let r=!1;return(async()=>{const l=a?null:Je(n);a&&Ne(n,null);const E=t.fullName||t.companyName||"";A((l==null?void 0:l.name)||E),K((l==null?void 0:l.email)||t.email),b((l==null?void 0:l.templateId)||null);const _=a?null:(l==null?void 0:l.estimateId)||t.firstWinEstimateId;if(_)try{const C=await fe(_);if(r)return;if(C){if(y(C.id),Z(C),C.sent_at&&p(C.client_email),C.client_email&&K((l==null?void 0:l.email)||C.client_email),C.client_name&&A((l==null?void 0:l.name)||C.client_name),C.status==="approved"||C.approved_at){u("done"),L({step:"done",estimateId:C.id});return}if(C.sent_at){u("approve"),L({step:"approve",estimateId:C.id});return}u("send"),L({step:"send",estimateId:C.id});return}}catch(C){O({title:"Could not check your sample estimate",description:C instanceof Error?C.message:"Starting from the top.",variant:"destructive"})}if(r)return;const g=l!=null&&l.step&&["pick","address"].includes(l.step)?l.step:"pick";u(g),L({step:g})})(),()=>{r=!0}},[]);const re=d.useCallback(async()=>{x(null),j(null);try{await Gt();const[r,l]=await Promise.all([Jt(),mt().catch(()=>null)]),E=l?ut[l]:null,_=E?[...r.filter(g=>g.template.name===E),...r.filter(g=>g.template.name!==E)]:r;if(x(_),_.length===0){j("No starter jobs were created. Check that the shared price book is loaded.");return}b(g=>g&&_.some(C=>C.template.id===g)?g:_[0].template.id)}catch(r){const l=r instanceof Error?r.message:"Please try again.";j(l),O({title:"Could not load the starter jobs",description:l,variant:"destructive"})}},[]);d.useEffect(()=>{re()},[re]),d.useEffect(()=>{const r=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=r}},[]),d.useEffect(()=>{var r;c&&((r=V.current)==null||r.focus())},[c]),d.useEffect(()=>{if(c!=="approve"||!h)return;let r=!1;ee(!1);const l=Date.now(),E=async()=>{if(!r){try{const g=await fe(h);if(r||!g)return;if(Z(g),g.status==="approved"||g.approved_at){r=!0,clearInterval(_),T("firstwin_approved"),U("done");return}}catch(g){console.error("First Win poll failed:",g)}Date.now()-l>sa&&(r=!0,clearInterval(_),ee(!0))}},_=setInterval(E,ta);return E(),()=>{r=!0,clearInterval(_)}},[c,h,be,U]),d.useEffect(()=>{if(c!=="done"||!h)return;let r=!1;return(async()=>{try{const l=R!=null&&R.approved_at?R:await fe(h);if(r||!l)return;l!==R&&Z(l);const E=w.from("estimate_tiers").select("id, title, total").eq("estimate_id",h),{data:_,error:g}=l.approved_tier_id?await E.eq("id",l.approved_tier_id).maybeSingle():await E.order("tier_number").limit(1).maybeSingle();if(g)throw g;!r&&_&&pe({title:_.title,total:Number(_.total)||0})}catch(l){O({title:"Could not load the approved option",description:l instanceof Error?l.message:"The approval itself went through.",variant:"destructive"})}})(),()=>{r=!0}},[c,h]);const te=d.useMemo(()=>(m==null?void 0:m.find(r=>r.template.id===N))||null,[m,N]),se=()=>{try{localStorage.setItem(yt(n),String(Date.now()))}catch{}w.from("users").update({first_win_skipped_at:new Date().toISOString()}).eq("id",n).then(()=>{}),T("firstwin_skipped",{step:c??"pick"}),i()},me=r=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r.trim()),s=async()=>{var E;const r=H.trim();if(!me(r)){O({title:"Check the email address",description:"That is
17where the sample estimate goes.",variant:"destructive"}),U("address");return}let l=te;if(!l&&m&&m.length>0&&(l=m[0]),!l){O({title:"Starter jobs are still loading",description:"Give it a second and tap Send again.",variant:"destructive"});return}Y("Creating the estimate");try{const{data:{user:_}}=await w.auth.getUser();if(!_)throw new Error("You are signed out. Sign in and try again.");let g=h;if(g){const{error:P}=await w.from("estimates").update({client_name:S.trim()||r,client_email:r}).eq("id",g);if(P)throw new Error(`Could not update the estimate: ${P.message}`)}else{const P=await Et()??_.id,{data:z,error:Oe}=await w.from("user_preferences").select("default_materials_tax_rate, default_labor_tax_rate").eq("user_id",P).maybeSingle();if(Oe)throw new Error(`Could not read your tax defaults: ${Oe.message}`);const Ae=Number((z==null?void 0:z.default_materials_tax_rate)??0),wt=Number((z==null?void 0:z.default_labor_tax_rate)??0),Re=l.template.category,vt=Re==="Replacement"?"AC Replacement (Existing)":Re==="Installation"?"Central AC Installation (New)":"Custom Estimate",{data:jt,error:Le}=await w.from("estimates").insert({user_id:_.id,client_name:S.trim()||r,client_email:r,job_description:`Sample: ${l.template.name}`,template_type:vt,status:"draft",materials_tax_rate:Ae,labor_tax_rate:wt,tax_rate:Ae}).select("id").single();if(Le)throw new Error(`Could not create the estimate: ${Le.message}`);g=jt.id,y(g),L({estimateId:g,templateId:l.template.id,name:S,email:r})}Y("Pricing the three options");const{count:C,error:Fe}=await w.from("estimate_tiers").select("id",{count:"exact",head:!0}).eq("estimate_id",g);if(Fe)throw new Error(`Could not check the estimate: ${Fe.message}`);if(!C)try{await hs(g,l.template.id)}catch(P){throw new Error(`Could not price the options: ${P instanceof Error?P.message:"unknown error"}`)}Y("Building the PDF");let F;try{const{buildEstimatePdf:P}=await it(async()=>{const{buildEstimatePdf:z}=await import("./estimatePdf-BnRXCDbF.js");return{buildEstimatePdf:z}},__vite__mapDeps([3,1,2,4,5,6,7,8]));F=await P(g)}catch(P){throw new Error(`Could not build the PDF: ${P instanceof Error?P.message:"unknown error"}`)}Y("Emailing it to you");const{data:{session:Me}}=await w.auth.getSession();if(!Me)throw new Error("You are signed out. Sign in and try again.");const ve=await w.functions.invoke("send-estimate",{headers:{Authorization:`Bearer ${Me.access_token}`},body:{estimateId:g,recipientEmail:r,recipientName:S.trim()||void 0,pdfBase64:F.base64,pdfFileName:F.fileName,contractorBusinessName:F.contractor.companyName,contractorEmail:F.contractor.email,contractorPhone:F.contractor.phone||void 0,replyToEmail:F.contractor.replyTo,emailSubject:`Your sample estimate from ${F.contractor.companyName}`,personalMessage:"This is the sample estimate you sent yourself from EstimateKit. Open it, pick an option, and sign it to see what your customers see.",jobDescription:F.estimate.job_description||void 0,estimateTotal:F.totals.min,minTotal:F.totals.min,maxTotal:F.totals.max,optionCount:F.totals.optionCount,sendCopyToContractor:!1,items:F.items,settings:{subtotal:F.totals.subtotal,tax_amount:F.totals.tax,total:F.totals.total}}});if(ve.error){let P=ve.error.message||"The email service did not accept it.";try{const z=await((E=ve.error.context)==null?void 0:E.json());z&&typeof z.error=="string"&&(P=z.error)}catch{}throw new Error(`Could not send the email: ${P}`)}const{error:Pe}=await w.from("users").update({first_win_estimate_id:g}).eq("id",_.id);Pe&&console.error("Could not store first_win_estimate_id:",Pe),o.invalidateQueries({queryKey:["all-estimates"]}),o.invalidateQueries({queryKey:["first-win-gate"]}),T("firstwin_sent"),p(r),Y(null),L({email:r,name:S})}catch(_){Y(null),O({title:"That did not go through",description:_ instanceof Error?_.message:"Please try again.",variant:"destructive"})}},f=async()=>{if(!h)return;let r=R==null?void 0:R.approval_token;if(!r)try{const l=await fe(h);r=l==null?void 0:l.approval_token,l&&Z(l)}catch(l){O({title:"Could not open the approval page",description:l instanceof Error?l.message:"Please try again.",variant:"destructive"});return}if(!r){O({title:"No approval link yet",description:"The email has not finished sending. Try again in a few seconds.",variant:"destructive"});return}window.open(`${ps()}/approve/${h}?token=${encodeURIComponent(r)}`,"_blank","noopener")},W=async()=>{he(!0);try{const{error:r}=await w.from("users").update({first_win_completed_at:new Date().toISOString(),has_completed_onboarding:!0}).eq("id",n);if(r)throw r;T("firstwin_done"),Ne(n,null),await Promise.all([o.invalidateQueries({queryKey:["first-win-gate"]}),o.invalidateQueries({queryKey:["onboarding-flags"]})]),i()}catch(r){O({title:"Could not save your progress",description:r instanceof Error?r.message:"Please try again.",variant:"destructive"})}finally{he(!1)}},Q=c?ke.indexOf(c):0,B="first-win-title";return Ct.createPortal(e.jsxs("div",{className:"fixed inset-0 z-[120] flex items-end justify-center bg-black/70 sm:items-center sm:p-6",role:"presentation",children:[e.jsx("style",{children:oa}),e.jsxs("section",{role:"dialog","aria-modal":"true","aria-labelledby":B,className:"flex h-[100dvh] w-full flex-col overflow-y-auto bg-background sm:h-auto sm:max-h-[90vh] sm:max-w-lg sm:rounded-xl sm:border sm:border-ink/[0.08]",style:{paddingTop:"env(safe-area-inset-top)"},children:[e.jsxs("header",{className:"flex items-center justify-between px-5 pb-2 pt-5 sm:px-8 sm:pt-7",children:[e.jsx("div",{className:"flex items-center gap-2","aria-hidden":"true",children:ke.map((r,l)=>e.jsx("span",{"aria-hidden":"true",className:I("h-1.5 rounded-full transition-all",l<=Q?"w-6 bg-cta-orange":"w-1.5 bg-ink/[0.12]")},r))}),e.jsxs("span",{className:"text-xs font-medium text-muted-foreground",children:["Step ",Q+1," of ",ke.length]})]}),e.jsxs("div",{className:"flex-1 px-5 pb-6 sm:px-8 sm:pb-8",style:{paddingBottom:"max(1.5rem, env(safe-area-inset-bottom))"},children:[!c&&e.jsxs("div",{className:"space-y-3 py-6","aria-busy":"true",children:[e.jsx("div",{className:"h-7 w-2/3 animate-pulse rounded-lg bg-ink/[0.06]"}),e.jsx("div",{className:"h-4 w-full animate-pulse rounded-lg bg-ink/[0.06]"}),e.jsx("div",{className:"h-20 animate-pulse rounded-xl bg-ink/[0.06]"})]}),c==="pick"&&e.jsxs(le,{ref:V,titleId:B,title:"Pick a job",body:"We'll build a real estimate from this. You can change every line later.",children:[v?e.jsxs("div",{className:"rounded-xl border border-ink/[0.06] bg-card p-4 text-sm text-muted-foreground",children:[e.jsx("p",{children:v}),e.jsx(k,{variant:"secondary",className:"mt-3",onClick:re,children:"Try again"})]}):m?e.jsx("div",{role:"radiogroup","aria-label":"Starter jobs",className:"flex flex-col gap-px overflow-hidden rounded-xl border border-ink/[0.06] bg-ink/[0.05]",children:m.map(r=>{const l=r.template.id===N,E=r.tiers.map(_=>`${_.tier_name} ${Se(_.total)}`).join(" · ");return e.jsxs("button",{type:"button",role:"radio","aria-checked":l,onClick:()=>{b(r.template.id),L({templateId:r.template.id})},className:I("flex w-full cursor-pointer items-center gap-3 px-4 py-3.5 text-left transition-colors focus-visible:outline-none focus-visible:bg-ink/[0.04]",l?"bg-ink/[0.04]":"bg-card hover:bg-ink/[0.04]"),children:[e.jsx("span",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-ink/[0.06] text-cta-orange","aria-hidden":"true",children:e.jsx(fs,{category:r.template.category})}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"block text-[14px] font-semibold text-foreground",children:r.template.name}),e.jsx("span",{className:"block truncate text-[13px] text-foreground-secondary",children:E})]}),e.jsx("span",{"aria-hidden":"true",className:I("flex h-6 w-6 shrink-0 items-center justify-center rounded-full border",l?"border-foreground bg-foreground text-background":"border-ink/[0.12]"),children:l&&e.jsx(ye,{className:"h-3.5 w-3.5"})})]},r.template.id)})}):e.jsx("div",{className:"space-y-2","aria-busy":"true","aria-label":"Loading starter jobs",children:[0,1,2].map(r=>e.jsx("div",{className:"h-[76px] animate-pulse rounded-xl bg-ink/[0.06]"},r))}),e.jsx(k,{variant:"orange",className:"mt-6 w-full",disabled:!m||!N,onClick:()=>U("address"),children:"Use this one"}),e.jsx(xe,{onClick:se})]}),c==="address"&&e.jsxs(le,{ref:V,titleId:B,title:"Address it to yourself",body:"This one goes to you, so you can see exactly what your customer sees.",children:[e.jsxs("form",{className:"space-y-4",onSubmit:r=>{if(r.preventDefault(),!me(H)){O({title:"Check the email address",description:"That is
17where the sample estimate goes.",variant:"destructive"});return}L({name:S,email:H.trim()}),U("send")},children:[e.jsxs("div",{children:[e.jsx(ne,{htmlFor:"fw-name",className:"text-foreground-secondary",children:"Name"}),e.jsx($e,{id:"fw-name",value:S,onChange:r=>A(r.target.value),className:"mt-1.5",autoComplete:"name",placeholder:"Your name"})]}),e.jsxs("div",{children:[e.jsx(ne,{htmlFor:"fw-email",className:"text-foreground-secondary",children:"Email"}),e.jsx($e,{id:"fw-email",type:"email",inputMode:"email",value:H,onChange:r=>K(r.target.value),className:"mt-1.5",autoComplete:"email",required:!0,placeholder:"[email protected]"})]}),e.jsx(k,{type:"submit",variant:"orange",className:"mt-2 w-full",children:"Looks right"})]}),e.jsx(xe,{onClick:se})]}),c==="send"&&e.jsxs(le,{ref:V,titleId:B,title:D?`Sent to ${D}`:"Send it",body:D?"Check your inbox in a minute. Look in spam the first time, then mark it safe.":`We'll create the estimate, price all three options, build the PDF, and email it to ${H.trim()||"you"}.`,children:[te&&!D&&e.jsxs("div",{className:"rounded-xl border border-ink/[0.06] bg-card px-4 py-3 text-sm",children:[e.jsxs("p",{className:"font-semibold text-foreground",children:["Sample: ",te.template.name]}),e.jsx("p",{className:"text-muted-foreground",children:te.tiers.map(r=>`${r.tier_name} ${Se(r.total)}`).join(" · ")})]}),$?e.jsxs("div",{className:"mt-4 flex items-center gap-3 rounded-xl border border-ink/[0.06] bg-card px-4 py-3 text-sm text-foreground",role:"status","aria-live":"polite",children:[e.jsx(We,{className:"h-4 w-4 animate-spin text-foreground-secondary","aria-hidden":"true"}),$,"..."]}):D?e.jsxs("div",{className:"mt-4 flex items-center gap-3 rounded-xl border border-ink/[0.06] bg-card px-4 py-3 text-sm text-foreground",role:"status",children:[e.jsx("span",{className:"flex h-7 w-7 items-center justify-center rounded-full bg-success text-white",children:e.jsx(ye,{className:"h-4 w-4","aria-hidden":"true"})}),"On its way to ",D]}):null,D?e.jsx(k,{variant:"orange",className:"mt-6 w-full",onClick:()=>U("approve"),children:"Next: approve it"}):e.jsx(k,{variant:"orange",className:"mt-6 w-full",disabled:!!$||!m,onClick:s,children:$?"Sendingâ¦":"Send it to me"}),!D&&!$&&e.jsx("button",{type:"button",onClick:()=>U("address"),className:"mt-3 block w-full min-h-[44px] md:min-h-0 text-center text-sm text-muted-foreground hover:text-foreground",children:"Change the name or email"}),e.jsx(xe,{onClick:se})]}),c==="approve"&&e.jsxs(le,{ref:V,titleId:B,title:"Open it on your phone and approve it",body:"Your customer sees three options, picks one, and types their name to sign. Do the same.",children:[e.jsxs(k,{variant:"orange",className:"w-full",onClick:f,children:[e.jsx(xs,{className:"h-4 w-4","aria-hidden":"true"}),"Open the approval page"]}),e.jsx("p",{className:"mt-3 text-center text-sm text-muted-foreground",children:"or open the email on your phone and tap the button in it"}),e.jsx("div",{className:"mt-6 flex items-center gap-3 rounded-xl border border-ink/[0.06] bg-card px-4 py-3 text-sm",role:"status","aria-live":"polite",children:M?e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"min-w-0 flex-1 text-muted-foreground",children:"Come back any time, this step waits for you."}),e.jsx(k,{variant:"secondary",size:"sm",onClick:()=>we(r=>r+1),children:"Check again"})]}):e.jsxs(e.Fragment,{children:[e.jsx(We,{className:"h-4 w-4 animate-spin text-foreground-secondary","aria-hidden":"true"}),e.jsx("span",{className:"text-foreground",children:"Waiting for your approval. This updates on its own."})]})}),e.jsx(xe,{onClick:se})]}),c==="done"&&e.jsxs(le,{ref:V,titleId:B,title:"That's the moment",body:"Your customers get exactly this. Now do it for real.",children:[e.jsxs("div",{className:"flex flex-col items-center py-2",children:[e.jsxs("svg",{className:"fw-check",viewBox:"0 0 64 64",width:"88",height:"88","aria-hidden":"true",children:[e.jsx("circle",{className:"fw-check-ring",cx:"32",cy:"32",r:"29",fill:"none",stroke:"currentColor",strokeWidth:"3"}),e.jsx("path",{className:"fw-check-mark",d:"M19 33 L28 42 L46 23",fill:"none",stroke:"currentColor",strokeWidth:"4",strokeLinecap:"round",strokeLinejoin:"round"})]}),e.jsxs("div",{className:"mt-4 w-full overflow-hidden rounded-xl border border-ink/[0.06] bg-card divide-y divide-ink/[0.06]",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[e.jsx("span",{className:"text-[13.5px] text-foreground-secondary",children:"Approved option"}),e.jsx("span",{className:"font-semibold text-foreground",children:de?`${de.title} · ${Se(de.total)}`:"Loadingâ¦"})]}),e.jsxs("div",{className:"flex items-center justify-between px-4 py-3",children:[e.jsx("span",{className:"text-[13.5px] text-foreground-secondary",children:"Signed by"}),e.jsx("span",{className:"font-semibold text-foreground",children:(R==null?void 0:R.approved_by_name)||S||"You"})]})]})]}),e.jsx(k,{variant:"orange",className:"mt-6 w-full",onClick:W,disabled:ce,children:ce?"Savingâ¦":"Set up my account"})]})]})]})]}),document.body)},le=d.forwardRef(({titleId:t,title:a,body:i,children:o},n)=>e.jsxs("div",{className:"py-4",children:[e.jsx("h2",{id:t,ref:n,tabIndex:-1,
17className:"text-2xl font-semibold tracking-tight text-foreground outline-none",children:a}),e.jsx("p",{className:"mt-2 mb-6 text-[14px] leading-relaxed text-muted-foreground",children:i}),o]}));le.displayName="StepFrame";const xe=({onClick:t,label:a="Skip for now"})=>e.jsx("button",{type:"button",onClick:t,className:"mt-3 block w-full min-h-[44px] md:min-h-0 text-center text-sm text-muted-foreground hover:text-foreground",children:a}),oa=` 18.fw-check { color: hsl(var(--success)); } 19.fw-check-ring { stroke-dasharray: 183; stroke-dashoffset: 183; animation: fw-draw 0.6s ease-out forwards; } 20.fw-check-mark { stroke-dasharray: 40; stroke-dashoffset: 40; animation: fw-draw 0.4s ease-out 0.45s forwards; } 21@keyframes fw-draw { to { stroke-dashoffset: 0; } } 22@media (prefers-reduced-motion: reduce) { 23 .fw-check-ring, .fw-check-mark { animation: none; stroke-dashoffset: 0; } 24} 25`,q=()=>w,Ve=t=>`$${Math.round(t).toLocaleString("en-US")}`,Xe=t=>(t||"").trim().split(/\s+/)[0]||"",ae=(t,a=new Date)=>Math.max(0,Math.floor((a.getTime()-new Date(t).getTime())/864e5)),oe=t=>t===0?"today":t===1?"yesterday":`${t} days ago`,Ze=(t,a)=>{const i=(t||"").replace(/[^\d+]/g,"");return i.length>=10?`sms:${i}?&body=${encodeURIComponent(a)}`:void 0},et="id, estimate_number, client_name, client_phone, job_description, status, sent_at, viewed_at, valid_until, updated_at, approved_tier_id, estimate_settings(total), estimate_tiers!estimate_tiers_estimate_id_fkey(id, total, is_recommended)";async function la(t=new Date){var V,L,U,re,te,se,me;const a=ks(t),i=G(a,"yyyy-MM-dd"),o=Ns(t).toISOString(),{data:{session:n}}=await w.auth.getSession(),[c,u,m,x,v,j,N,b,S,A,H,K,h,y,D,p]=await Promise.all([q().from("estimates").select(et).in("status",["sent","viewed"]).not("sent_at","is",null).order("sent_at",{ascending:!0}).limit(60),q().from("estimates").select(et).eq("status","draft").lt("updated_at",Hs(t,1).toISOString()).order("updated_at",{ascending:!1}).limit(40),q().from("jobs").select("id, job_number, title, customer_name, estimated_total, created_at").eq("status","unscheduled").order("created_at").limit(30),q().from("jobs").select("id, job_number, title, customer_name, estimated_total, completed_at").eq("status","completed").order("completed_at",{ascending:!1}).limit(60),q().from("invoices").select("job_id").neq("kind","deposit").not("job_id","is",null),q().from("invoices").select("id, invoice_number, customer_id, total, amount_paid, deposit_credit, due_date").or(`status.eq.overdue,and(status.eq.partial,due_date.lt.${i})`).order("due_date").limit(30),q().from("maintenance_visits").select("id, due_date, label, agreement_id, maintenance_agreements!inner(id, status, accounts(client_name))").is("job_id",null).is("skipped_at",null).lte("due_date",G(je(a,ws),"yyyy-MM-dd")).eq("maintenance_agreements.status","active").order("due_date").limit(30),q().from("maintenance_agreements").select("id, status, price, billing, end_date, auto_renew, name, accounts(client_name), invoices(created_at, status)").eq("status","active"),q().from("customer_contacts").select("id, customer_id, follow_up_date, notes").lt("follow_up_date",i).eq("follow_up_completed",!1).order("follow_up_date").limit(20),q().from("jobs").select("id, job_number, title, customer_name, scheduled_date").gte("scheduled_date",i).lte("scheduled_date",G(je(a,2),"yyyy-MM-dd")).is("assigned_to",null).is("assigned_to_name",null).in("status",["scheduled"]).limit(20),q().from("jobs").select("id, job_number, title, customer_id, customer_name, address, customer_phone, scheduled_time, arrival_window_end, status, job_type").eq("scheduled_date",i).in("status",["scheduled","in_progress"]).order("scheduled_time",{ascending:!0,nullsFirst:!1}),q().from("estimates").select("approved_tier_id, estimate_settings(total), estimate_tiers!estimate_tiers_estimate_id_fkey(id, total, is_recommended)").gte("sent_at",o),q().from("estimates").select("approved_tier_id, estimate_settings(total), estimate_tiers!estimate_tiers_estimate_id_fkey(id, total, is_recommended)").gte("approved_at",o),q().from("invoices").select("total, deposit_credit, status").gte("created_at",o).neq("status","cancelled"),q().from("payments").select("amount").gte("paid_at",o.slice(0,10)),n?q().from("users").select("organization_id, first_win_estimate_id").eq("id",n.user.id).maybeSingle():Promise.resolve({data:null})]),{data:$}=(V=p.data)!=null&&V.organization_id?await q().from("organizations").select("company_name").eq("id",p.data.organization_id).maybeSingle():{data:null},Y=$!=null&&$.company_name&&$.company_name!=="My HVAC Company"?$.company_name:"us",R=((L=p.data)==null?void 0:L.first_win_estimate_id)??null,Z=Array.from(new Set([...(j.data||[]).map(s=>s.customer_id),...(S.data||[]).map(s=>
25s.customer_id)].filter(Boolean))),{data:de}=Z.length?await q().from("accounts").select("id, client_name, phone").in("id",Z):{data:[]},pe=new Map((de||[]).map(s=>[s.id,s])),M=[];for(const s of c.data||[]){const f=ue(s).value,W=s.client_name||"Customer",Q=s.job_description?`, ${s.job_description.replace(/\.$/,"")}`:"",B=Ze(s.client_phone,`Hi ${Xe(s.client_name)||"there"}, it's ${Y}. Just checking you got the quote${s.job_description?` for ${s.job_description.toLowerCase().replace(/\.$/,"")}`:""}. Happy to answer any questions.`),r=s.valid_until?Math.floor((new Date(`${s.valid_until}T23:59:59`).getTime()-t.getTime())/864e5):null,l=ae(s.sent_at,t),E=B?{label:"Text",href:B}:{label:"Resend",to:`/estimates/${s.id}/view?action=send`},_={label:"Open",to:`/estimates/${s.id}/view`};r!==null&&r>=0&&r<=5?M.push({key:`exp:${s.id}`,kind:"estimate_expiring",title:`${W}'s quote expires ${r===0?"today":r===1?"tomorrow":`in ${r} days`}`,detail:`${s.estimate_number||"Estimate"}${Q}`,amount:f||null,urgency:80,primary:E,secondary:_}):s.viewed_at&&l>=2?M.push({key:`viewed:${s.id}`,kind:"quote_viewed",title:`${W} opened your quote ${oe(ae(s.viewed_at,t))}`,detail:`${s.estimate_number||"Estimate"}${Q} · no answer yet`,amount:f||null,urgency:70,primary:E,secondary:_}):l>=3&&M.push({key:`wait:${s.id}`,kind:"quote_waiting",title:`No answer from ${W}`,detail:`${s.estimate_number||"Estimate"}${Q} · sent ${oe(l)}${s.viewed_at?"":", not opened"}`,amount:f||null,urgency:60,primary:E,secondary:_})}const ee=(u.data||[]).filter(s=>s.id!==R&&ue(s).value>0);for(const s of ee.slice(0,10))M.push({key:`draft:${s.id}`,kind:"draft_ready",title:`Quote for ${s.client_name||"a customer"} is ready to send`,detail:`${s.estimate_number||"Draft"}${s.job_description?`, ${s.job_description.replace(/\.$/,"")}`:""} · edited ${oe(ae(s.updated_at,t))}`,amount:ue(s).value,urgency:45,primary:{label:"Review",to:`/estimates/${s.id}/add-items`}});for(const s of m.data||[])M.push({key:`sched:${s.id}`,kind:"won_unscheduled",title:`${s.customer_name||"A customer"} said yes. Pick a date`,detail:`${s.job_number||"Job"}${s.title?`, ${s.title}`:""} · approved ${oe(ae(s.created_at,t))}`,amount:Number(s.estimated_total)||null,urgency:75,primary:{label:"Schedule",to:`/jobs/${s.id}?schedule=1`}});const be=new Set((v.data||[]).map(s=>s.job_id));for(const s of(x.data||[]).filter(f=>!be.has(f.id)))M.push({key:`inv:${s.id}`,kind:"job_not_invoiced",title:`${s.customer_name||"A customer"}'s job is done`,detail:`${s.job_number||"Job"}${s.title?`, ${s.title}`:""} · done ${s.completed_at?oe(ae(s.completed_at,t)):""}, no invoice`,amount:Number(s.estimated_total)||null,urgency:85,primary:{label:"Invoice",to:`/jobs/${s.id}`}});for(const s of j.data||[]){const f=s.customer_id?pe.get(s.customer_id):void 0,W=ae(`${s.due_date}T12:00:00`,t),Q=js(s),B=Ze(f==null?void 0:f.phone,`Hi ${Xe(f==null?void 0:f.client_name)||"there"}, it's ${Y}. A friendly reminder that invoice ${s.invoice_number||""} for ${Ve(Q)} is past due. Let me know if you have any questions.`);M.push({key:`late:${s.id}`,kind:"invoice_overdue",title:`${(f==null?void 0:f.client_name)||"A customer"} owes ${Ve(Q)}`,detail:`${s.invoice_number||"Invoice"} · ${W} day${W===1?"":"s"} late`,amount:Q,urgency:90+Math.min(W,30)/10,primary:{label:"Remind",to:`/invoices/${s.id}?send=1`},secondary:B?{label:"Text",href:B}:void 0})}for(const s of N.data||[]){const f=((re=(U=s.maintenance_agreements)==null?void 0:U.accounts)==null?void 0:re.client_name)||"A plan customer",W=G(new Date(`${s.due_date}T12:00:00`),"MMMM");M.push({key:`tune:${s.id}`,kind:"tune_up_due",title:`Book ${f}'s ${s.label.toLowerCase()}`,detail:`Due ${W} · maintenance plan`,amount:null,urgency:new Date(`${s.due_date}T12:00:00`)<a?66:55,primary:{label:"Book",to:`/maintenance/${s.agreement_id}`}})}const we=G(je(a,30),"yyyy-MM-dd");for(const s of b.data||[]){const f=Number(s.price)||0;vs({...s,price:f})?M.push({key:`bill:${s.id}`,kind:"plan_bill",title:`${s.name} is due for ${((te=s.accounts)==null?void 0:te.client_name)||"a plan customer"}`,detail:`${s.billing==="monthly"?"This month":"This term"} not billed yet`,amount:f||null,urgency:65,primary:{label:"Bill",to:`/maintenance/${s.id}`}}):s.end_date<=we&&M.push({key:`renew:${s.id}
25`,kind:"plan_renewal",title:`${((se=s.accounts)==null?void 0:se.client_name)||"A plan"}'s ${s.name} ${s.auto_renew?"renews":"ends"} ${G(new Date(`${s.end_date}T12:00:00`),"MMM d")}`,detail:s.auto_renew?"Renews on its own; a reminder email goes out 30 days before":"Offer a renewal before it lapses",amount:f||null,urgency:s.auto_renew?30:50,primary:{label:"Open",to:`/maintenance/${s.id}`}})}for(const s of S.data||[]){const f=pe.get(s.customer_id);M.push({key:`fu:${s.id}`,kind:"follow_up",title:`Follow up with ${(f==null?void 0:f.client_name)||"a customer"}`,detail:`${s.notes?`${s.notes.slice(0,60)}${s.notes.length>60?"â¦":""} · `:""}due ${oe(ae(`${s.follow_up_date}T12:00:00`,t))}`,amount:null,urgency:50,primary:{label:"Open",to:`/customers/${s.customer_id}`},secondary:f!=null&&f.phone?{label:"Call",href:`tel:${f.phone.replace(/[^\d+]/g,"")}`}:void 0})}for(const s of A.data||[]){const f=s.scheduled_date===i?"today":G(new Date(`${s.scheduled_date}T12:00:00`),"EEEE");M.push({key:`assign:${s.id}`,kind:"job_unassigned",title:`No tech on ${s.customer_name||"a job"} ${f}`,detail:`${s.job_number||"Job"}${s.title?`, ${s.title}`:""}`,amount:null,urgency:s.scheduled_date===i?88:72,primary:{label:"Assign",to:`/jobs/${s.id}?schedule=1`}})}M.sort((s,f)=>f.urgency-s.urgency||(f.amount??0)-(s.amount??0));const ce=s=>(s||[]).reduce((f,W)=>f+ue(W).value,0),he=y.data||[];return{items:M,today:H.data||[],drafts:{count:ee.length,value:ee.reduce((s,f)=>s+ue(f).value,0),firstId:((me=ee[0])==null?void 0:me.id)??null},money:{quoted:ce(K.data),won:ce(h.data),invoiced:he.reduce((s,f)=>s+(Number(f.total)||0)-(Number(f.deposit_credit)||0),0),collected:(D.data||[]).reduce((s,f)=>s+Number(f.amount),0)}}}const bt=(t,a)=>{const i=n=>{const[c,u]=n.split(":").map(Number),m=new Date;
25return m.setHours(c,u,0,0),G(m,u?"h:mm":"h")},o=n=>Number(n.split(":")[0])>=12?"pm":"am";return t?a?`${i(t)}â${i(a)}${o(a)}`:`${i(t)}${o(t)}`:"Anytime"},qe=t=>`$${Math.round(t).toLocaleString("en-US")}`,tt="font-mono text-[11px] uppercase tracking-[0.08em]",da={invoice_overdue:{icon:qs,cls:"bg-bad/10 text-bad"},job_not_invoiced:{icon:Fs,cls:"bg-[#22C55E]/[0.12] text-[#15803D]"},estimate_expiring:{icon:ft,cls:"bg-attn/10 text-attn"},job_unassigned:{icon:ct,cls:"bg-attn/10 text-attn"},won_unscheduled:{icon:dt,cls:"bg-[#14B8A6]/[0.12] text-[#0F766E]"},quote_viewed:{icon:Kt,cls:"bg-[#2F6BFF]/10 text-[#1E4FD8]"},quote_waiting:{icon:ht,cls:"bg-ink/[0.05] text-foreground-secondary"},plan_bill:{icon:Ms,cls:"bg-[#8B5CF6]/10 text-[#6D28D9]"},tune_up_due:{icon:xt,cls:"bg-[#8B5CF6]/10 text-[#6D28D9]"},follow_up:{icon:Ps,cls:"bg-[#2F6BFF]/10 text-[#1E4FD8]"},draft_ready:{icon:Os,cls:"bg-ink/[0.05] text-foreground-secondary"},plan_renewal:{icon:lt,cls:"bg-[#8B5CF6]/10 text-[#6D28D9]"}},st=({action:t,kind:a,variant:i,className:o})=>{const n=()=>void T("home_action",{kind:a,action:t.label.toLowerCase()}),c=I("h-9 min-h-0 px-3 text-[13px]",o);return t.href?e.jsx(k,{asChild:!0,size:"sm",variant:i,className:c,children:e.jsx("a",{href:t.href,onClick:n,children:t.label})}):e.jsx(k,{asChild:!0,size:"sm",variant:i,className:c,children:e.jsx(X,{to:t.to,onClick:n,children:t.label})})},ca=({data:t,now:a=new Date})=>{const i=a.getHours()*60+a.getMinutes(),o=m=>m.scheduled_time?Number(m.scheduled_time.slice(0,2))*60+Number(m.scheduled_time.slice(3,5)):null,n=t.today.find(m=>m.status==="in_progress")??t.today.find(m=>{const x=o(m);return x===null||x>=i-60}),c=a.getHours()>=16,{data:u}=J({queryKey:ys((n==null?void 0:n.customer_id)||""),queryFn:()=>_s(n.customer_id),enabled:!!(n!=null&&n.customer_id),staleTime:6e4});if(n&&(!c||t.drafts.count===0)){const m=u?bs(u):"",x=(n.customer_phone||"").replace(/[^\d+]/g,"");return e.jsx(He,{tone:"peach",className:"rounded-[16px] border border-[#f26a1b]/20 shadow-[0_1px_2px_rgba(24,24,27,0.04)]",children:e.jsxs("section",{className:"flex flex-col gap-4 p-5","data-next-card":"job",children:[e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsxs("p",{className:I(tt,"text-cta-orange"),children:[n.status==="in_progress"?"On now":"Next job"," · ",bt(n.scheduled_time,n.arrival_window_end)]}),e.jsx("p",{className:"text-[18px] font-semibold tracking-[-0.01em]",children:n.customer_name||"Customer"}),e.jsx("p",{className:"text-[13.5px] text-foreground-secondary",children:[n.title,n.address].filter(Boolean).join(" · ")}),m&&e.jsxs("p",{className:"flex items-center gap-1.5 text-[12.5px] text-foreground-tertiary",children:[e.jsx(xt,{className:"h-3.5 w-3.5 shrink-0",strokeWidth:1.8})," ",e.jsxs("span",{className:"truncate",children:["On site: ",m]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[n.address&&e.jsx(k,{asChild:!0,variant:"orange",size:"sm",className:"h-9 gap-1.5",children:e.jsxs("a",{href:gs(n.address),target:"_blank",rel:"noreferrer",onClick:()=>void T("home_action",{kind:"next_job",action:"directions"}),children:[e.jsx(Es,{className:"h-4 w-4",strokeWidth:1.8})," Directions"]})}),x.length>=10&&e.jsx(k,{asChild:!0,variant:"outline",size:"sm",className:"h-9 gap-1.5",children:e.jsxs("a",{href:`tel:${x}`,onClick:()=>void T("home_action",{kind:"next_job",action:"call"}),children:[e.jsx(Ts,{className:"h-4 w-4",strokeWidth:1.8})," Call"]})}),e.jsx(k,{asChild:!0,variant:"outline",size:"sm",className:"h-9",children:e.jsx(X,{to:`/jobs/${n.id}`,onClick:()=>void T("home_action",{kind:"next_job",action:"open"}),children:"Open job"})})]})]})})}if(t.drafts.count>0&&t.drafts.firstId){const m=t.drafts.count;return e.jsx(He,{tone:"peach",className:"rounded-[16px] border border-[#f26a1b]/20 shadow-[0_1px_2px_rgba(24,24,27,0.04)]",children:e.jsxs("section",{className:"flex flex-col gap-4 p-5 sm:flex-row sm:items-center","data-next-card":"drafts",children:[e.jsxs("div",{className:"flex min-w-0 flex-1 flex-col gap-1.5",children:[e.jsx("p",{className:I(tt,"text-cta-orange"),children:"Ready to send"}),e.jsxs("p",{className:"text-[18px] font-semibold tracking-[-0.01em]",children:[m," quote",m===1?" is":"s are"," priced and waiting"]}),e.jsxs("p",{className:"text-[13.5px] text-foreground-secondary",children:[e.jsx("span",{className:"font-mono text-foreground",children:qe(t.drafts.value)})," of work, one tap from the customer."]})]}),e.jsxs("div",{className:"flex shrink-0 gap-2",children:[e.jsx(k,{asChild:!0,variant:"orange",size:"sm",className:"h-9",children:e.jsxs(X,{to:`/estimates/${t.drafts.firstId}/add-items`,onClick:()=>void T("home_action",{kind:"next_drafts",action:"review"}),children:["Review ",m===1?"it":"the first"]})}),m>1&&e.jsx(k,{asChild:!0,variant:"outline",size:"sm",className:"h-9",children:e.jsx(X,{to:"/estimates?tab=draft",children:"All drafts"})})]})]})})}return null},at=({item:t,first:a,faded:i=!1})=>{var m;const o=_e(),n=t.primary.to??((m=t.secondary)==null?void 0:m.to),c=()=>{n&&(T("home_action",{kind:t.kind,action:"row"}),o(n))},u=da[t.kind];return e.jsxs("div",{className:I("flex items-center gap-3.5 bg-card px-4 py-3.5 md:px-[18px]",i&&"pointer-events-none [mask-image:linear-gradient(to_bottom,black_0%,transparent_95%)]"),"data-do-next":t.kind,"aria-hidden":i||void 0,children:[e.jsx("span",{className:I("flex h-8 w-8 shrink-0 items-center justify-center rounded-lg",u.cls),"aria-hidden":!0,
25children:e.jsx(u.icon,{className:"h-4 w-4",strokeWidth:1.9})}),e.jsxs("button",{type:"button",onClick:c,className:"flex min-w-0 flex-1 flex-col gap-0.5 text-left",children:[e.jsx("span",{className:"truncate text-[13.5px] font-medium text-foreground",children:t.title}),e.jsx("span",{className:"truncate text-[12.5px] text-foreground-tertiary",children:t.detail})]}),t.amount?e.jsx("span",{className:"hidden shrink-0 font-mono text-[13px] text-foreground sm:block",children:qe(t.amount)}):null,e.jsxs("div",{className:"flex shrink-0 items-center gap-1",children:[t.secondary&&e.jsx(st,{action:t.secondary,kind:t.kind,variant:"ghost",className:"hidden text-foreground-secondary sm:inline-flex"}),e.jsx(st,{action:t.primary,kind:t.kind,variant:a?"default":"outline"})]})]})},ma=({items:t})=>{const[a,i]=d.useState(!1),o=a?t:t.slice(0,5),n=!a&&t.length>5?t[5]:null;return e.jsx("div",{"data-do-next-list":!0,children:e.jsx(De,{icon:e.jsx("span",{className:I("h-[7px] w-[7px] shrink-0 rounded-full",t.length?"bg-cta-orange":"bg-[#12B76A]"),"aria-hidden":!0}),label:t.length?t.length===1?"1 thing needs you":`${t.length} things need you`:"Nothing needs you",children:t.length===0?e.jsx("p",{className:"px-4 py-3.5 text-[13px] text-foreground-secondary",children:"All caught up. Nothing is waiting on you."}):e.jsxs("div",{className:"flex flex-col divide-y divide-border",children:[o.map((c,u)=>e.jsx(at,{item:c,first:u===0},c.key)),n&&e.jsx(at,{item:n,first:!1,faded:!0},n.key),t.length>5&&e.jsxs("button",{type:"button",onClick:()=>i(c=>!c),className:"flex items-center justify-center gap-1.5 bg-card px-4 py-2.5 text-[12.5px] text-foreground-secondary hover:text-foreground",children:[a?"Show fewer":`Show all ${t.length}`," ",e.jsx(Is,{className:I("h-4 w-4 transition-transform",a&&"rotate-180")})]})]})})})},ua=({jobs:t})=>t.length===0?null:e.jsx("div",{"data-today-list":!0,children:e.jsx(De,{label:"Today",count:t.length,action:e.jsx(X,{to:"/jobs",className:"text-[12.5px] text-foreground-secondary hover:text-foreground",children:"Calendar"}),children:e.jsx("div",{className:"flex flex-col divide-y divide-border",children:t.map(a=>{var i;return e.jsxs(X,{to:`/jobs/${a.id}`,className:I("flex items-center gap-3 px-4 py-3 transition-colors hover:bg-ink/[0.03]",a.status==="in_progress"?"bg-[#FFFCFA]":"bg-card"),children:[e.jsx("span",{className:I("h-8 w-[3px] shrink-0 rounded-full",a.status==="in_progress"?"bg-cta-orange":"bg-ink/[0.08]"),"aria-hidden":!0}),e.jsx("span",{className:"ek-num w-16 shrink-0 text-[12.5px] text-foreground-secondary",children:bt(a.scheduled_time,null)}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"block truncate text-[13.5px] font-medium",children:a.customer_name||"Customer"}),e.jsx("span",{className:"block truncate text-[12px] text-foreground-tertiary",children:a.title||((i=a.job_type)==null?void 0:i.replace("_"," "))})]}),a.status==="in_progress"&&e.jsxs("span",{className:"flex items-center gap-1.5 rounded-md bg-attn/10 px-2 py-0.5 text-[11.5px] font-medium text-attn",children:[e.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-cta-orange"}),"In progress"]})]},a.id)})})})}),pa=({money:t})=>{if(!t.quoted&&!t.won&&!t.invoiced&&!t.collected)return null;const a=[{label:"Quoted",value:t.quoted,to:"/estimates"},{label:"Won",value:t.won,to:"/jobs"},{label:"Invoiced",value:t.invoiced,to:"/invoices"},{label:"Collected",value:t.collected,to:"/invoices?tab=paid"}];return e.jsx("div",{"data-money-line":!0,children:e.jsx(De,{label:"This month",action:e.jsxs(X,{to:"/reports",className:"flex items-center gap-1 text-[12.5px] text-foreground-secondary hover:text-foreground",children:["Reports ",e.jsx(Ds,{className:"h-3.5 w-3.5"})]}),children:e.jsx("div",{className:"grid grid-cols-2 gap-px bg-border md:grid-cols-4",children:a.map(i=>e.jsxs(X,{to:i.to,className:"flex min-w-0 flex-col gap-1 bg-card px-4 py-3.5 transition-colors hover:bg-ink/[0.04]",children:[e.jsx("span",{className:"text-[12px] text-foreground-tertiary",children:i.label}),e.jsx("span",{className:I("ek-num truncate text-[17px] font-semibold tracking-[-0.01em]",i.label==="Collected"&&i.value>0&&"text-ok"),children:qe(i.value)})]},i.label))})})})},ha=({open:t,onDone:a})=>{const i=d.useCallback(()=>a(),[a]);return e.jsx(Tt,{open:t,children:e.jsxs(It,{className:"gap-5 sm:max-w-md [&>button]:hidden",onPointerDownOutside:o=>o.preventDefault(),onEscapeKeyDown:o=>o.preventDefault(),onInteractOutside:o=>o.preventDefault(),children:[e.jsxs(Dt,{className:"text-left",children:[e.jsx(qt,{className:"text-[17px]",children:"Welcome to EstimateKit"}),e.jsx(Ft,{className:"text-[13px]",children:"Two quick things, then your first quote opens ready to send."})]}),e.jsx(Vt,{onDone:i,onNotOwner:i}
25)]})})},fa=()=>{const t=Mt(),{data:a}=ot();if(t.state==="loading"||t.state==="confirmed")return null;const i=(a==null?void 0:a.role)==="owner",o=t.state==="missing";return e.jsx("div",{className:`rounded-xl border bg-card px-4 py-3.5 text-[13px] text-ink/80 md:px-5 ${o?"border-ink/[0.06]":"border-warn/20"}`,"data-tax-rate-banner":!0,children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("p",{className:"flex min-w-0 items-start gap-2",children:[o?e.jsx(As,{className:"mt-0.5 h-4 w-4 shrink-0 text-foreground-tertiary",strokeWidth:1.8,"aria-hidden":!0}):e.jsx(Ce,{className:"mt-0.5 h-4 w-4 shrink-0 text-warn",strokeWidth:1.8,"aria-hidden":!0}),e.jsxs("span",{children:[e.jsx("span",{className:"font-semibold text-foreground",children:o?"Add the sales tax you charge.":"Confirm your sales tax rates."})," ",o?"We'll ask when you start your first real quote, or do it now.":`Your account is using ${t.materials}% on materials and ${t.labor}% on labor, and nobody here chose that. Quotes can't be sent until you confirm or change it.`,!i&&" Only the account owner can do this."]})]}),i&&e.jsx(k,{size:"sm",variant:o?"outline":"orange",onClick:()=>Pt("banner"),children:"Set tax rates"})]})})},xa=()=>{const{data:t}=J({queryKey:["mail-status"],queryFn:async()=>(await w.rpc("mail_status")).data,staleTime:6e4,refetchInterval:3e5});if(!t)return null;const a=!!t.health&&!t.health.ok,i=!!t.health&&Date.now()-new Date(t.health.checked_at).getTime()>2*60*6e4,o=t.failures_24h>0;return!a&&!o&&!i?null:e.jsx("div",{className:"rounded-xl border border-bad/25 bg-card px-4 py-3.5 text-[13px] text-ink/80 md:px-5","data-mail-health-bar":!0,children:e.jsxs("div",{className:"space-y-1.5",children:[a&&e.jsxs("p",{className:"flex items-start gap-2",children:[e.jsx(Ce,{className:"mt-0.5 h-4 w-4 shrink-0 text-bad",strokeWidth:1.8,"aria-hidden":!0}),e.jsxs("span",{children:[e.jsx("span",{className:"font-semibold text-foreground",children:"Mail DNS has drifted."})," ",t.health.problems.map(n=>`${n.record}: expected ${n.expected}, got ${n.actual}`).join(" · "),t.health.resend_status&&!["verified","unknown"].includes(t.health.resend_status)&&` · Resend says ${t.health.resend_status}`,e.jsx("span",{className:"text-foreground-tertiary",children:" Fix it in Cloudflare; the expected values are in supabase/functions/_shared/mailcheck.ts."})]})]}),o&&e.jsxs("p",{className:"flex items-start gap-2",children:[e.jsx(Ls,{className:"mt-0.5 h-4 w-4 shrink-0 text-bad",strokeWidth:1.8,"aria-hidden":!0}),e.jsxs("span",{children:[e.jsxs("span",{className:"font-semibold text-foreground",children:[t.failures_24h," email",t.failures_24h===1?"":"s"," failed in the last 24 hours"]}),t.failures_7d>t.failures_24h&&` (${t.failures_7d} this week)`,".",t.last_failure&&` Last: ${t.last_failure.fn} to ${t.last_failure.to_domain??"unknown"} ${Be(new Date(t.last_failure.created_at),{addSuffix:!0})}: ${t.last_failure.error??t.last_failure.kind}`]})]}),i&&!a&&e.jsxs("p",{className:"flex items-start gap-2",children:[e.jsx(Ce,{className:"mt-0.5 h-4 w-4 shrink-0 text-bad",strokeWidth:1.8,"aria-hidden":!0}),e.jsxs("span",{children:[e.jsx("span",{className:"font-semibold text-foreground",children:"The mail check hasn't run"})," since ",Be(new Date(t.health.checked_at),{addSuffix:!0}),". The mail-health-30m cron may be stopped."]})]})]})})},gn=()=>{const{data:t}=ot();_e();const a=Ie(),{data:i}=J({queryKey:["finish-setup-check"],queryFn:Xt,staleTime:1/0}),o=()=>a.setQueryData(["finish-setup-check"],!1),{data:n}=J({queryKey:["subscription-status"],queryFn:async()=>await Lt()}),c=n!=null&&n.trialEnd?Ot(n.trialEnd):0,u=(n==null?void 0:n.isTrialing)&&(n==null?void 0:n.trialEnd)&&c>0,{data:m}=J({queryKey:["home"],queryFn:()=>la(),enabled:!!t&&t.role!=="technician",refetchInterval:6e4});return d.useEffect(()=>{m&&T("home_shown",{items:Math.min(m.items.length,20),today:m.today.length})},[m]),(t==null?void 0:t.role)==="technician"?e.jsx(At,{to:"/my-day",replace:!0}):e.jsx(Ys,{onRefresh:async()=>{},children:e.jsxs("div",{className:"min-h-screen bg-background pb-20",children:[e.jsx(Yt,{}),e.jsx(Ut,{width:"narrow",className:"pb-8 md:pb-12 md:pt-10",children:e.jsxs("div",{className:"flex flex-col gap-6 md:gap-8",children:[e.jsxs("div",{className:"flex flex-col gap-3 empty:hidden",children:[u&&!Rt()&&e.jsx(ea,{daysRemaining:c}),e.jsx(xa,{}),e.jsx(fa,{})]}),e.jsx(Us,{}),(t==null?void 0:t.role)==="owner"&&e.jsx("section",{className:"empty:hidden",children:e.jsx(Js,{trialing:!!(n!=null&&n.isTrialing)})}),e.jsx("section",{className:"empty:hidden",children:e.jsx(Xs,{})}),m?e.jsxs("div",{className:"flex min-w-0 flex-col gap-7",children:[e.jsx(ca,{data:m}),e.jsx(ma,{items:m.items}),e.jsx(ua,{jobs:m.today}),e.jsx(pa,{money:m.money})]}):e.jsxs("div",{className:"flex flex-col gap-3","aria-busy":"true","aria-label":"Loading",children:[e.jsx("div",{className:"h-28 animate-pulse rounded-xl bg-ink/[0.04]"}),e.jsx("div",{className:"h-48 animate-pulse rounded-xl bg-ink/[0.04]"})]})]})}),i===!1&&e.jsx(ra,{}),e.jsx(ha,{open:i===!0,onDone:o})]})})};export{gn as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.