PageSourceSearch

https://estimatekit.com/assets/Settings-C2gXXHXo.js

js estimatekit.com collected 2026-10-04 03:34:26 UTC 85,219 bytes, 34 lines download raw bytes

1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/onboarding-flags-izowS2nh.js","assets/index-CbvCveKN.js","assets/index-DK9kCj9D.css","assets/onboardingEvents-iM3xWPll.js"])))=>i.map(i=>d[i]);
2import{A as le,j as e,B as k,r as m,T as Qe,bs as lt,U as ze,V as ct,W as $e,K as b,g as q,z as te,o as P,Q as Y,a7 as qe,q as Z,X as dt,I as R,Z as Le,a0 as ut,_ as _e,Y as mt,k as Ne,bt as ht,N as ce,bu as xt,m as Ie,D as pt,$ as gt,bf as de,a8 as Ee}from"./index-CbvCveKN.js";import{E as re,R as ft,D as yt,P as bt,r as vt}from"./PageContainer-Bx7SVsdy.js";import{P as wt}from"./PageHeader-ohyr15TW.js";import{I as jt,D as kt,u as _t,r as Nt,l as Ct,d as Fe,W as St,s as Et,a as ae}from"./companySettings-B6WTPyrl.js";import{T as ee}from"./textarea-BGGCYgxW.js";import{S as H}from"./switch-DMLCXOMI.js";import{S as pe,a as ge,b as fe,c as ye,d as be}from"./select-C3XbO4_1.js";import{E as Ft,m as Tt,f as Mt}from"./EstimateDocument-D2NBvf9z.js";import{D as ve}from"./download-q_CUCbMH.js";import{E as Dt}from"./jspdf.es.min-CH-oufHI.js";import{C as Bt}from"./chevron-down-yKD6BMcU.js";import{E as Pt}from"./external-link-DtZsaCxu.js";import{U as Ot}from"./upload-BDKwK5D_.js";import{C as We,a as Ue,b as Ye,d as Ke,c as He}from"./card-IdKqTlSB.js";import{A as Ve,a as Xe,b as Ze,c as Ge,d as Je,e as et,f as tt,g as st}from"./alert-dialog-BsECSXvh.js";import{T as Rt}from"./triangle-alert-BJBV5PBt.js";import{f as At}from"./concierge-BidFqpW_.js";import{C as at,p as we}from"./parseISO-B0WEjCD3.js";import{S as nt}from"./save-gxAHJ6k7.js";import{P as Qt}from"./play-cOhvd8eb.js";import{T as zt}from"./trash-2-CEFy1AEt.js";import{f as je}from"./format-BZAqQT85.js";import{C as $t}from"./check-Bjw6cCk6.js";import{C as qt}from"./copy-Bx-FLJpv.js";import{F as Lt}from"./file-text-DDhZ7a0t.js";import{Z as It}from"./zap-CYbWfdbf.js";import{U as Wt}from"./users-BkZzL3s4.js";import{C as Ut}from"./chevron-right-f4vsMuAf.js";import"./index-Jf4OHjGl.js";import"./en-US-wdCzBwgh.js";import"./plus-kYCBPFxU.js";import"./layout-dashboard-rEexJXnQ.js";import"./ek-mark-light-Y4_w-cFG.js";import"./plug-BAhKXAxN.js";import"./index-DlFerWUd.js";import"./index-CKxf6gP2.js";import"./differenceInCalendarDays-BmAYwV3_.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 Yt=le("BadgeCheck",[["path",{d:"M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z",key:"3c2336"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);/**
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 Kt=le("Building2",[["path",{d:"M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z",key:"1b4qmf"}],["path",{d:"M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2",key:"i71pzd"}],["path",{d:"M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2",key:"10jefs"}],["path",{d:"M10 6h4",key:"1itunk"}],["path",{d:"M10 10h4",key:"tcdvrf"}],["path",{d:"M10 14h4",key:"kelpxr"}],["path",{d:"M10 18h4",key:"1ulq68"}]]);/**
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 ue=le("EyeOff",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);/**
18 * @license lucide-react v0.462.0 - ISC
19 *
20 * This source code is licensed under the ISC license.
21 * See the LICENSE file in the root directory of this source tree.
22 */const Ht=le("UserRound",[["circle",{cx:"12",cy:"8",r:"5",key:"1hypcn"}],["path",{d:"M20 21a8 8 0 0 0-16 0",key:"rfgkzh"}]]),ke=680,Vt=({children:s})=>{const r=m.useRef(null),t=m.useRef(null),[i,l]=m.useState(1),[o,d]=m.useState(0);return m.useEffect(()=>{const n=r.current,a=t.current;if(!n||!a)return;const g=()=>{const _=Math.min(1,n.clientWidth/ke);l(_),d(a.scrollHeight*_)};g();const u=new ResizeObserver(g);return u.observe(n),u.observe(a),()=>u.disconnect()}
22,[]),e.jsx("div",{ref:r,style:{height:o||void 0,overflow:"hidden"},children:e.jsx("div",{ref:t,style:{width:ke,transform:`scale(${i})`,transformOrigin:"top left"},children:s})})},Xt="data:image/svg+xml;utf8,"+encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80"><rect width="80" height="80" rx="10" fill="#e5e7eb"/><rect x="18" y="22" width="44" height="36" rx="4" fill="#9ca3af"/><rect x="24" y="28" width="32" height="4" fill="#e5e7eb"/><rect x="24" y="36" width="32" height="4" fill="#e5e7eb"/><rect x="24" y="44" width="32" height="4" fill="#e5e7eb"/></svg>'),V=(s,r,t,i,l,o=1,d=!1)=>({id:s,item_name:r,item_description:l,category:t,quantity:o,unit_price:i,total:i*o,...d?{image_url:Xt}:{}}),Te=(s,r,t,i,l,o)=>{const d=l.reduce((g,u)=>g+u.total,0),n=l.filter(g=>g.category!=="Labor").reduce((g,u)=>g+u.total,0),a=Math.round(n*o)/100;return{id:s,title:r,description:t,is_recommended:i,items:l,subtotal:d,tax_amount:a,total:d+a}},Zt=[Te("good","Good","14 SEER2 single-stage system",!1,[V("g1","Goodman 3-ton 14.3 SEER2 condenser","Equipment",2850,"R-410A, 10-year parts warranty with registration",1,!0),V("g2","Matched air handler with TXV","Equipment",1650,"Multi-position, ECM blower"),V("g3","Line set flush and new filter drier","Materials",185,"Existing line set reused"),V("g4","Installation labor (2 techs, 1 day)","Labor",1600,"Removal and disposal of the old equipment included")],6.25),Te("better","Better","16 SEER2 two-stage system with better humidity control",!0,[V("b1","Carrier 3-ton 16 SEER2 two-stage condenser","Equipment",3990,"Quiet two-stage operation, 10-year parts warranty",1,!0),V("b2","Matched air handler with TXV","Equipment",1890,"Variable-speed ECM blower"),V("b3","Line set flush and new filter drier","Materials",185,"Existing line set reused"),V("b4","Installation labor (2 techs, 1 day)","Labor",1600,"Removal and disposal of the old equipment included")],6.25)],Gt=({companyInfo:s,businessEmail:r,document:t={},onDownload:i,compact:l=!1})=>{const o=r||s.email,d=[s.address,[s.city,s.state].filter(Boolean).join(", "),s.zip].filter(Boolean).join(", "),n=new Date().toISOString(),a=()=>e.jsx("div",{className:"settings-pdf-preview bg-white text-black",style:{width:ke},children:e.jsx(Ft,{context:"internal",company:{name:s.company_name||"Your Company",phone:s.phone,email:o,logo_url:s.logo_url,address:d},estimate:{number:"EST-1024",customer_name:"Maria Delgado",customer_email:"[email protected]",customer_phone:"(508) 555-0142",customer_address:"18 Birchwood Lane, Fall River, MA 02720",job_description:"Replace 3-ton central AC system and air handler",service_date:n,sent_at:n},options:Zt,document:t})}),g=e.jsxs(Qe,{children:[e.jsx(lt,{asChild:!0,children:e.jsxs(k,{variant:l?"outline":"ghost",size:"sm",className:l?"h-11 md:h-9 w-full gap-2":"h-8 gap-1.5 px-2.5 text-xs",children:[e.jsx(re,{className:l?"h-4 w-4":"h-3.5 w-3.5",strokeWidth:1.8}),l?"Preview what customers see":"Full size"]})}),e.jsxs(ze,{className:"max-h-[90vh] max-w-3xl overflow-y-auto p-0",children:[e.jsx(ct,{className:"border-b border-ink/[0.06] p-4",children:e.jsx($e,{children:"Estimate preview"})}),e.jsx("div",{className:"overflow-x-auto bg-white",children:e.jsx(a,{})})]})]}),u=e.jsx("style",{children:`
23      .settings-pdf-preview,
24      .settings-pdf-preview * {
25        --background: 0 0% 100% !important;
26        --foreground: 222 47% 11% !important;
27        --card: 0 0% 100% !important;
28        --card-foreground: 222 47% 11% !important;
29        --muted: 210 40% 96% !important;
30        --muted-foreground: 215 20% 40% !important;
31        --border: 214 32% 91% !important;
32        color-scheme: light !important;
33      }
34    `});return l?e.jsxs(e.Fragment,{children:[u,e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row",children:[g,i&&e.jsxs(k,{variant:"outline",onClick:i,className:"h-11 md:h-9 w-full gap-2 sm:w-auto",children:[e.jsx(ve,{className:"h-4 w-4"}),"Sample PDF"]})]})]}):e.jsxs(e.Fragment,{children:[u,e.jsxs("div",{className:"overflow-hidden rounded-xl border border-ink/[0.06] bg-card",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 border-b border-ink/[0.06] px-[18px] py-3",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-[14px] font-semibold text-foreground",children:"Preview"}),e.jsx("span",{className:"ml-2 text-[12px] text-foreground-tertiary",children:"Updates as you change the settings"})]}),e.jsxs("div",{className:"flex gap-1",children:[g,i&&e.jsxs(k,{variant:"ghost",size:"sm",onClick:i,className:"h-8 gap-1.5 px-2.5 text-xs",children:[e.jsx(ve,{className:"h-3.5 w-3.5",
34strokeWidth:1.8}),"PDF"]})]})]}),e.jsx("div",{className:"bg-background p-3",children:e.jsx("div",{className:"max-h-[70vh] overflow-y-auto overflow-x-hidden rounded-md shadow-[0_8px_30px_rgba(0,0,0,0.45)]",children:e.jsx(Vt,{children:e.jsx(a,{})})})})]})]})};async function Jt(s,r){try{const t=new Dt,i=t.internal.pageSize.getWidth(),l=t.internal.pageSize.getHeight(),o=14,d=i-o*2,n={primary:{r:37,g:99,b:235},text:{r:31,g:41,b:55},textMuted:{r:107,g:114,b:128},border:{r:229,g:231,b:235},cardBg:{r:249,g:250,b:251}};let a=0;t.setFillColor(n.cardBg.r,n.cardBg.g,n.cardBg.b),t.rect(0,0,i,38,"F"),a=12;const g=o,u=16;if(s.logo_url)try{const M=new Image;M.crossOrigin="anonymous",await new Promise((A,I)=>{M.onload=A,M.onerror=I,M.src=s.logo_url}),t.addImage(M,"PNG",g,a-2,u,u)}catch{t.setFillColor(n.primary.r,n.primary.g,n.primary.b),t.roundedRect(g,a-2,u,u,2,2,"F"),t.setTextColor(255,255,255),t.setFont("helvetica","bold"),t.setFontSize(10);const A=(s.company_name||"YC").split(" ").slice(0,2).map(I=>I[0]).join("").toUpperCase();t.text(A,g+u/2,a+7,{align:"center"})}else if(s.company_name){t.setFillColor(n.primary.r,n.primary.g,n.primary.b),t.roundedRect(g,a-2,u,u,2,2,"F"),t.setTextColor(255,255,255),t.setFont("helvetica","bold"),t.setFontSize(10);const M=s.company_name.split(" ").slice(0,2).map(A=>A[0]).join("").toUpperCase();t.text(M,g+u/2,a+7,{align:"center"})}const _=g+u+6;t.setTextColor(n.text.r,n.text.g,n.text.b),t.setFont("helvetica","bold"),t.setFontSize(18),t.text(s.company_name||"Your Company Name",_,a+4),t.setFont("helvetica","normal"),t.setFontSize(8),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b);const j=r.business_email||s.email,D=[s.phone,j].filter(Boolean);D.length>0&&t.text(D.join("  •  "),_,a+12),s.address&&s.city&&t.text(`${s.address}, ${s.city}, ${s.state} ${s.zip}`,_,a+16);const N=i-o;t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.setFont("helvetica","bold"),t.setFontSize(7),t.text("ESTIMATE",N,a,{align:"right"}),t.setTextColor(n.text.r,n.text.g,n.text.b),t.setFontSize(14),t.text("#SAMPLE",N,a+8,{align:"right"}),t.setFont("helvetica","normal"),t.setFontSize(7),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.text(new Date().toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}),N,a+14,{align:"right"}),a=38,t.setDrawColor(n.border.r,n.border.g,n.border.b),t.setLineWidth(.5),t.line(0,a,i,a),a+=8,t.setFillColor(n.cardBg.r,n.cardBg.g,n.cardBg.b),t.roundedRect(o,a,d,28,2,2,"F"),t.setDrawColor(n.border.r,n.border.g,n.border.b),t.setLineWidth(.3),t.roundedRect(o,a,d,28,2,2,"S"),a+=5,t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.setFont("helvetica","bold"),t.setFontSize(7),t.text("PREPARED FOR",o+4,a),a+=6,t.setTextColor(n.text.r,n.text.g,n.text.b),t.setFont("helvetica","bold"),t.setFontSize(11),t.text("John Smith",o+4,a),a+=5,t.setFont("helvetica","normal"),t.setFontSize(9),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.text("Premium HVAC System Installation",o+4,a),a+=5,t.text("123 Main St, Dallas, TX",o+4,a),a+=15,t.setFillColor(n.cardBg.r,n.cardBg.g,n.cardBg.b),t.rect(o,a,d,6,"F"),t.setDrawColor(n.border.r,n.border.g,n.border.b),t.setLineWidth(.3),t.line(o,a,o+d,a),t.line(o,a+6,o+d,a+6),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.setFont("helvetica","bold"),t.setFontSize(7),t.text("SERVICES",o+4,a+4),a+=6,t.setFillColor(255,255,255),t.rect(o,a,d,6,"F"),t.line(o,a+6,o+d,a+6);const C=o+4,f=o+100,y=o+130,h=i-o-4;t.setFontSize(7),t.text("Description",C,a+4),t.text("Qty",f,a+4,{align:"center"}),t.text("Price",y,a+4,{align:"center"}),t.text("Amount",h,a+4,{align:"right"}),a+=6,t.setFillColor(255,255,255),t.rect(o,a,d,10,"F"),t.setTextColor(n.text.r,n.text.g,n.text.b),t.setFont("helvetica","bold"),t.setFontSize(9),t.text("Professional Installation",C,a+5),t.setFont("helvetica","normal"),t.setFontSize(7),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.text("Labor",C,a+9),t.setFontSize(8),t.text("8.00",f,a+6,{align:"center"}),t.text("$150.00",y,a+6,{align:"center"}),t.setTextColor(n.text.r,n.text.g,n.text.b),t.setFont("helvetica","bold"),t.text("$1,200.00",h,a+6,{align:"right"}),a+=10,t.setFillColor(n.cardBg.r,n.cardBg.g,n.cardBg.b),t.rect(o,a,d,6,"F"),t.line(o,a,o+d,a),t.setFont("helvetica","normal"),t.setFontSize(8),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.text("Services Subtotal",o+4,a+4),t.setTextColor(n.text.r,n.text.g,n.text.b),t.setFont("helvetica","bold"),t.text("$1,200.00",h,a+4,{align:"right"}),a+=12,t.setFillColor(n.cardBg.r,n.cardBg.g,n.cardBg.b),t.rect(o,a,d,6,"F"),t.setDrawColor(n.border.r,n.border.g,n.border.b),t.line(o,a,o+d,a),t.line(o,a+6,o+d,a+6),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.setFont("helvetica","bold"),t.setFontSize(7),t.text("MATERIALS",o+4,a+4),a+=6,t.setFillColor(255,255,255),t.rect(o,a,d,6,"F"),t.line(o,a+6,o+d,a+6),t.setFontSize(7),t.text("Description",C,a+4),t.text("Qty",f,a+4,{al
34ign:"center"}),t.text("Price",y,a+4,{align:"center"}),t.text("Amount",h,a+4,{align:"right"}),a+=6,[{name:"3-Ton HVAC System",category:"Equipment",qty:"1.00",price:"$4,500.00",amount:"$4,500.00"},{name:"Ducting & Supplies",category:"Materials",qty:"1.00",price:"$800.00",amount:"$800.00"}].forEach((M,A)=>{const I=A%2===1?n.cardBg:{r:255,g:255,b:255};t.setFillColor(I.r,I.g,I.b),t.rect(o,a,d,10,"F"),A>0&&(t.setDrawColor(n.border.r,n.border.g,n.border.b),t.line(o,a,o+d,a)),t.setTextColor(n.text.r,n.text.g,n.text.b),t.setFont("helvetica","bold"),t.setFontSize(9),t.text(M.name,C,a+5),t.setFont("helvetica","normal"),t.setFontSize(7),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.text(M.category,C,a+9),t.setFontSize(8),t.text(M.qty,f,a+6,{align:"center"}),t.text(M.price,y,a+6,{align:"center"}),t.setTextColor(n.text.r,n.text.g,n.text.b),t.setFont("helvetica","bold"),t.text(M.amount,h,a+6,{align:"right"}),a+=10}),t.setFillColor(n.cardBg.r,n.cardBg.g,n.cardBg.b),t.rect(o,a,d,6,"F"),t.line(o,a,o+d,a),t.setFont("helvetica","normal"),t.setFontSize(8),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.text("Materials Subtotal",o+4,a+4),t.setTextColor(n.text.r,n.text.g,n.text.b),t.setFont("helvetica","bold"),t.text("$5,300.00",h,a+4,{align:"right"}),a+=15;const O=60,E=i-o-O;t.setFont("helvetica","normal"),t.setFontSize(9),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.text("Subtotal:",E,a),t.setTextColor(n.text.r,n.text.g,n.text.b),t.text("$6,500.00",i-o,a,{align:"right"}),a+=3,t.setDrawColor(n.border.r,n.border.g,n.border.b),t.setLineWidth(.2),t.line(E,a,i-o,a),a+=5,t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.text("Tax (8.25%):",E,a),t.setTextColor(n.text.r,n.text.g,n.text.b),t.text("$536.25",i-o,a,{align:"right"}),a+=3,t.line(E,a,i-o,a),a+=6;const p=10;t.setFillColor(n.primary.r,n.primary.g,n.primary.b),t.roundedRect(E-2,a-5,O+4,p,2,2,"F"),t.setTextColor(255,255,255),t.setFont("helvetica","bold"),t.setFontSize(8),t.text("TOTAL:",E+2,a+1),t.setFontSize(12),t.text("$7,036.25",i-o-2,a+1,{align:"right"}),a+=15,t.setFillColor(n.cardBg.r,n.cardBg.g,n.cardBg.b),t.roundedRect(o,a,d,24,2,2,"F"),t.setDrawColor(n.border.r,n.border.g,n.border.b),t.setLineWidth(.3),t.roundedRect(o,a,d,24,2,2,"S"),a+=5,t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.setFont("helvetica","bold"),t.setFontSize(7),t.text("TERMS & CONDITIONS",o+4,a),a+=5,t.setFont("helvetica","normal"),t.setFontSize(8);const T=t.splitTextToSize(r.default_payment_terms||"50% deposit required to schedule. Final 50% due upon completion.",d-8);t.text(T,o+4,a),a+=6,t.setFontSize(7),t.setFont("helvetica","italic");const L=t.splitTextToSize(r.default_warranty_info||"1-year labor warranty. Equipment manufacturer warranty applies.",d-8);t.text(L,o+4,a),a=l-20,t.setDrawColor(n.border.r,n.border.g,n.border.b),t.setLineWidth(.2),t.line(o,a,i-o,a),a+=5,t.setFont("helvetica","italic"),t.setFontSize(7),t.setTextColor(n.textMuted.r,n.textMuted.g,n.textMuted.b),t.text(`This estimate is valid for ${r.default_valid_for_days||30} days from the date above.`,i/2,a,{align:"center"}),a+=4,t.setFont("helvetica","normal"),t.setFontSize(8),t.text(`Thank you for choosing ${s.company_name||"Your Company"}`,i/2,a,{align:"center"}),a+=5,t.setFontSize(6),t.setTextColor(200,200,200),t.text("Powered by EstimateKit",i/2,a,{align:"center"}),t.save(`${s.company_name||"Company"}_Sample-Estimate.pdf`),b({title:"Success",description:"PDF downloaded successfully!"})}catch(t){console.error("Error generating PDF:",t),b({title:"Error",description:"Failed to generate PDF",variant:"destructive"})}}const U=({title:s,description:r,children:t,action:i,id:l})=>e.jsxs("section",{className:"flex flex-col gap-2.5",id:l,children:[e.jsxs("div",{className:"flex items-end justify-between gap-3 px-0.5",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("h2",{className:"text-[15.5px] font-medium",children:s}),r&&e.jsx("p",{className:"mt-0.5 text-[12.5px] leading-snug text-foreground-tertiary",children:r})]}),i]}),e.jsx("div",{className:"flex flex-col divide-y divide-ink/[0.06] overflow-hidden rounded-xl border border-ink/[0.07] bg-card shadow-[0_1px_2px_rgba(24,24,27,0.04)]",children:t})]}),x=({label:s,help:r,htmlFor:t,children:i,stack:l=!1,className:o})=>e.jsxs("div",{className:q("flex gap-3 px-4 py-3 md:px-5",l?"flex-col":"flex-col sm:flex-row sm:items-center sm:justify-between sm:gap-6",o),children:[e.jsxs("div",{className:"min-w-0 sm:max-w-[60%]",children:[e.jsx(te,{htmlFor:t,className:"text-[13.5px] font-normal text-foreground",children:s}),r&&e.jsx("p",{className:"mt-0.5 text-[12.5px] leading-snug text-foreground-tertiary",children:r})]}),e.jsx("div",{className:q("min-w-0",l?"w-full":"w-full sm:w-auto 
34sm:shrink-0"),children:i})]}),ie=({label:s,changed:r=0,children:t,defaultOpen:i=!1})=>{const[l,o]=m.useState(i);return e.jsxs("div",{className:"flex flex-col",children:[e.jsxs("button",{type:"button",onClick:()=>o(d=>!d),"aria-expanded":l,className:"flex items-center justify-between gap-3 px-4 py-3 text-left text-[13px] text-foreground-secondary transition-colors hover:bg-ink/[0.04] hover:text-foreground md:px-5",children:[e.jsxs("span",{children:[s,r>0&&e.jsxs("span",{className:"ml-2 rounded-[5px] bg-ink/10 px-1.5 py-px text-[11.5px] font-medium text-foreground",children:[r," customised"]})]}),e.jsx(Bt,{className:q("h-4 w-4 shrink-0 transition-transform",l&&"rotate-180")})]}),l&&e.jsx("div",{className:"flex flex-col divide-y divide-ink/[0.06] border-t border-ink/[0.06]",children:t})]})},Me=({value:s,options:r,onChange:t,label:i})=>e.jsx("div",{role:"radiogroup","aria-label":i,className:"inline-flex w-full rounded-lg border border-ink/[0.06] bg-card p-[3px] sm:w-auto",children:r.map(l=>e.jsx("button",{type:"button",role:"radio","aria-checked":s===l.value,onClick:()=>t(l.value),className:q("h-8 min-h-0 flex-1 rounded-md px-3 text-[12.5px] font-medium transition-colors sm:flex-none",s===l.value?"bg-ink/[0.08] text-foreground":"text-foreground-secondary hover:text-foreground"),children:l.label},l.value))}),es=({canManage:s})=>{const[r,t]=m.useState(null),[i,l]=m.useState(!1);m.useEffect(()=>{let a=!0;return(s?P.functions.invoke("stripe-connect",{body:{action:"status"}}).then(({data:u})=>u):Promise.resolve(P.rpc("my_online_payments")).then(({data:u})=>u)).then(u=>a&&t(u??{connected:!1,charges_enabled:!1})).catch(()=>a&&t({connected:!1,charges_enabled:!1})),()=>{a=!1}},[s]);const o=async()=>{l(!0);const{data:a,error:g}=await P.functions.invoke("stripe-connect",{body:{action:"start"}});if(g||!(a!=null&&a.url)){l(!1),b({title:"Couldn't open Stripe",description:(a==null?void 0:a.error)||"Try again in a minute.",variant:"destructive"});return}window.location.href=a.url},d=(r==null?void 0:r.connected)&&r.charges_enabled,n=d?"Customers see a Pay now button on invoices. Money goes straight to your Stripe account at Stripe's rates. EstimateKit takes no cut.":r!=null&&r.connected?"Stripe still needs a few details before you can take payments.":"Customers pay by card or bank from the invoice page. Money goes straight to your own Stripe account. EstimateKit takes no cut.";return e.jsx(x,{label:"Card and bank payments online",help:n,stack:!0,children:e.jsxs("div",{className:"flex flex-col gap-3",children:[r?r.available===!1?e.jsx("span",{className:"w-fit rounded-[5px] bg-ink/10 px-1.5 py-px text-[11.5px] font-medium text-foreground-secondary",children:"Coming soon"}):d?e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-[13px] font-medium text-ok",children:[e.jsx(qe,{className:"h-4 w-4"})," Stripe connected"]}),r.live===!1&&e.jsx("span",{className:"rounded-[5px] bg-ink/10 px-1.5 py-px text-[11.5px] font-medium text-foreground-secondary",children:"Test mode"}),e.jsxs("a",{href:"https://dashboard.stripe.com",target:"_blank",rel:"noreferrer",className:"inline-flex items-center gap-1 text-[13px] text-foreground-secondary hover:text-foreground",children:["Stripe dashboard ",e.jsx(Pt,{className:"h-3.5 w-3.5"})]})]}):s&&Z()?e.jsx("span",{className:"text-[13px] text-foreground-secondary",children:"Connect Stripe from estimatekit.com in a web browser on your computer. Once it's connected, Pay now works on invoices you send from the app too."}):s?e.jsxs(k,{onClick:o,disabled:i,className:"h-10 w-fit gap-2",children:[i&&e.jsx(Y,{className:"h-4 w-4 animate-spin"}),r.connected?"Finish Stripe setup":"Connect Stripe"]}):e.jsx("span",{className:"text-[13px] text-foreground-tertiary",children:"Ask the owner to connect Stripe."}):e.jsx(Y,{className:"h-4 w-4 animate-spin text-foreground-tertiary"}),e.jsx("a",{href:"https://stripe.com",target:"_blank",rel:"noreferrer","aria-label":"Powered by Stripe",className:"w-fit opacity-80 transition-opacity hover:opacity-100",children:e.jsx("img",{src:"/brand/powered-by-stripe-white.svg",alt:"Powered by Stripe",width:119,height:27,className:"h-[27px] w-auto"})})]})})},De=(s,r)=>r.filter(t=>JSON.stringify(s[t]??"")!==JSON.stringify(kt[t]??"")).length,ts=s=>{const r=s.replace(/\D/g,"");return r.length<=3?r:r.length<=6?`(${r.slice(0,3)}) ${r.slice(3)}`:`(${r.slice(0,3)}) ${r.slice(3,6)}-${r.slice(6,10)}`},ss=s=>({presentation:s.document_presentation,showDescriptions:s.document_show_descriptions,showPhotos:s.document_show_photos,intro:s.document_intro,closing:s.document_closing,licenseNumber:s.license_number,signature:s.document_signature,validDays:s.default_valid_for_days,paymentTerms:s.default_payment_terms,warranty:s.default_warranty_info}),as=({profile:s,prefs:r,setProfile:t,setPref:i,onLogoChanged:l})=>{const o=m.useRef(null),[d,n]=m.useState(!1),a=async u=>
34{if(u){n(!0);try{const _=await _t(u);l(_);const{markOnboardingFlag:j}=await _e(async()=>{const{markOnboardingFlag:D}=await import("./onboarding-flags-izowS2nh.js");return{markOnboardingFlag:D}},__vite__mapDeps([0,1,2]));await j("has_added_logo"),b({title:"Logo saved",description:"It's on every new quote and invoice."})}catch(_){b({title:"Couldn't upload the logo",description:_ instanceof Error?_.message:"Try again.",variant:"destructive"})}finally{n(!1),o.current&&(o.current.value="")}}},g=async()=>{n(!0);try{await Nt(s.logo_url),l(null),b({title:"Logo removed"})}catch(u){b({title:"Couldn't remove the logo",description:u instanceof Error?u.message:"Try again.",variant:"destructive"})}finally{n(!1)}};return e.jsx("div",{className:"flex flex-col gap-8",children:e.jsxs(U,{title:"Business profile",description:"What customers see at the top of every quote, invoice and email.",children:[e.jsx(x,{label:"Logo",help:"PNG or JPG, under 2 MB. Saves right away.",children:e.jsxs("div",{className:"flex items-center gap-2",children:[s.logo_url?e.jsx("img",{src:s.logo_url,alt:"Company logo",className:"h-10 w-10 rounded-md border border-ink/[0.08] bg-white object-contain p-0.5"}):e.jsx("span",{className:"flex h-10 w-10 items-center justify-center rounded-md border border-dashed border-ink/[0.14] text-[11px] text-foreground-tertiary",children:"None"}),e.jsx("input",{ref:o,type:"file",accept:"image/*",className:"hidden",onChange:u=>{var _;return void a((_=u.target.files)==null?void 0:_[0])}}),e.jsxs(k,{type:"button",variant:"outline",size:"sm",disabled:d,onClick:()=>{var u;return(u=o.current)==null?void 0:u.click()},className:"gap-1.5",children:[d?e.jsx(Y,{className:"h-4 w-4 animate-spin"}):e.jsx(Ot,{className:"h-4 w-4",strokeWidth:1.8}),s.logo_url?"Replace":"Upload"]}),s.logo_url&&e.jsx(k,{type:"button",variant:"ghost",size:"sm",disabled:d,onClick:()=>void g(),"aria-label":"Remove logo",className:"w-9 px-0",children:e.jsx(dt,{className:"h-4 w-4"})})]})}),e.jsx(x,{label:"Company name",htmlFor:"s-company",children:e.jsx(R,{id:"s-company",value:s.company_name,onChange:u=>t("company_name",u.target.value),className:"sm:w-72",autoComplete:"organization"})}),e.jsx(x,{label:"Phone",htmlFor:"s-phone",children:e.jsx(R,{id:"s-phone",value:s.phone,onChange:u=>t("phone",ts(u.target.value)),inputMode:"tel",className:"font-mono sm:w-72"})}),e.jsx(x,{label:"Email on quotes",htmlFor:"s-bizemail",help:s.email?`Leave blank to use ${s.email}`:void 0,children:e.jsx(R,{id:"s-bizemail",type:"email",value:r.business_email,onChange:u=>i("business_email",u.target.value),placeholder:s.email||"[email protected]",className:"sm:w-72"})}),e.jsx(x,{label:"Address",stack:!0,children:e.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-[2fr_1.2fr_0.8fr_0.9fr]",children:[e.jsx(R,{"aria-label":"Street address",value:s.address,onChange:u=>t("address",u.target.value),placeholder:"Street",className:"col-span-2 sm:col-span-1"}),e.jsx(R,{"aria-label":"City",value:s.city,onChange:u=>t("city",u.target.value),placeholder:"City"}),e.jsx(R,{"aria-label":"State or province",value:s.state,onChange:u=>t("state",u.target.value.toUpperCase().slice(0,3)),placeholder:"State"}),e.jsx(R,{"aria-label":"ZIP or postal code",value:s.zip,onChange:u=>t("zip",u.target.value.toUpperCase().slice(0,10)),placeholder:"ZIP",className:"col-span-2 sm:col-span-1"})]})}),e.jsxs(ie,{label:"Website, license and reply-to email",changed:[s.website,r.license_number,r.use_same_email?"":r.reply_to_email].filter(Boolean).length,children:[e.jsx(x,{label:"Website",htmlFor:"s-web",children:e.jsx(R,{id:"s-web",value:s.website,onChange:u=>t("website",u.target.value),placeholder:"yourcompany.com",className:"sm:w-72"})}),e.jsx(x,{label:"License or insurance number",htmlFor:"s-license",help:"Printed on quotes.",children:e.jsx(R,{id:"s-license",value:r.license_number,onChange:u=>i("license_number",u.target.value),className:"font-mono sm:w-72"})}),e.jsx(x,{label:"Send customer replies somewhere else",help:"Off: replies go to the email on quotes.",children:e.jsx(H,{checked:!r.use_same_email,onCheckedChange:u=>i("use_same_email",!u)}
34)}),!r.use_same_email&&e.jsx(x,{label:"Reply-to email",htmlFor:"s-replyto",children:e.jsx(R,{id:"s-replyto",type:"email",value:r.reply_to_email,onChange:u=>i("reply_to_email",u.target.value),className:"sm:w-72"})})]})]})})},ns=["default_payment_terms","default_warranty_info","document_presentation","document_show_descriptions","document_show_photos","document_signature","document_intro","document_closing"],Be=["approval_step_1","approval_step_2","approval_step_3"],os=({profile:s,prefs:r,setPref:t})=>{const i=Le(),l=i.state==="loading"?"…":i.materials==null?"Not set":`${i.materials}% parts · ${i.labor??0}% labor`;return e.jsx("div",{className:"flex flex-col gap-8",children:e.jsxs(U,{title:"Quotes and invoices",description:"Defaults for new quotes and invoices. Each quote can still be changed on its own; saved quotes don't change.",children:[e.jsx(x,{label:"Sales tax you charge",help:i.state==="unconfirmed"?"Not confirmed yet. Quotes can't be sent until it is.":"On parts and equipment, and on labor.",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:q("font-mono text-[13px]",i.state==="confirmed"?"text-foreground":"text-warn"),children:l}),e.jsx(k,{type:"button",variant:"outline",size:"sm",onClick:()=>ut("banner"),children:"Change"})]})}),e.jsx(x,{label:"Quotes are valid for",htmlFor:"s-valid",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(R,{id:"s-valid",type:"number",inputMode:"numeric",min:1,max:365,value:r.default_valid_for_days,onChange:o=>t("default_valid_for_days",Math.max(1,Math.min(365,Number(o.target.value)||1))),className:"w-20 font-mono"}),e.jsx("span",{className:"text-[13px] text-foreground-secondary",children:"days"})]})}),e.jsx(x,{label:"Deposit when a customer approves",help:"Invoiced right away when set.",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(Me,{label:"Deposit",value:r.default_deposit_type,onChange:o=>t("default_deposit_type",o),options:[{value:"none",label:"None"},{value:"percent",label:"Percent"},{value:"fixed",label:"Fixed"}]}),r.default_deposit_type!=="none"&&e.jsxs("div",{className:"relative",children:[r.default_deposit_type==="fixed"&&e.jsx("span",{className:"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-[13px] text-foreground-tertiary",children:"$"}),e.jsx(R,{"aria-label":"Deposit amount",type:"number",inputMode:"decimal",min:0,value:r.default_deposit_value,onChange:o=>t("default_deposit_value",Number(o.target.value)||0),className:q("w-24 font-mono",r.default_deposit_type==="fixed"?"pl-6":"pr-7")}),r.default_deposit_type==="percent"&&e.jsx("span",{className:"pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-[13px] text-foreground-tertiary",children:"%"})]})]})}),e.jsx(x,{label:"Invoices are due",children:e.jsxs(pe,{value:r.invoice_payment_terms,onValueChange:o=>t("invoice_payment_terms",o),children:[e.jsx(ge,{className:"sm:w-44","aria-label":"Invoices are due",children:e.jsx(fe,{})}),e.jsx(ye,{children:jt.map(o=>e.jsx(be,{value:o.value,children:o.label},o.value))})]})}),e.jsxs(ie,{label:"What's printed on your quotes",changed:De(r,ns),children:[e.jsx(x,{label:"Pricing layout",help:"Detailed lists every line; summary shows totals by section; package shows one price per option.",children:e.jsx(Me,{label:"Pricing layout",value:r.document_presentation,onChange:o=>t("document_presentation",o),options:[{value:"detailed",label:"Detailed"},{value:"summary",label:"Summary"},{value:"package",label:"Package"}]})}),e.jsx(x,{label:"Item descriptions",children:e.jsx(H,{checked:r.document_show_descriptions,onCheckedChange:o=>t("document_show_descriptions",o)})}),e.jsx(x,{label:"Item photos",children:e.jsx(H,{checked:r.document_show_photos,onCheckedChange:o=>t("document_show_photos",o)})}),e.jsx(x,{label:"Signature line",children:e.jsx(H,{checked:r.document_signature,onCheckedChange:o=>t("document_signature",o)})}),e.jsx(x,{label:"Opening message",htmlFor:"s-intro",help:"Use {first_name} for the customer's first name.",stack:!0,children:e.jsx(ee,{id:"s-intro",value:r.document_intro,onChange:o=>t("document_intro",o.target.value),placeholder:"Hi {first_name}, thanks for having us out. Here are your options.",className:"min-h-[64px]"})}),e.jsx(x,{label:"Payment terms",htmlFor:"s-terms",stack:!0,children:e.jsx(ee,{id:"s-terms",value:r.default_payment_terms,onChange:o=>t("default_payment_terms",o.target.value),className:"min-h-[64px]"})}),e.jsx(x,{label:"Warranty",htmlFor:"s-warranty",stack:!0,children:e.jsx(ee,{id:"s-warranty",value:r.default_warranty_info,onChange:o=>t("default_warranty_info",o.target.value),className:"min-h-[64px]"})}),e.jsx(x,{label:"Closing note",htmlFor:"s-closing",stack:!0,children:e.jsx(ee,{id:"s-closing",value:r.document_closing,onChange:o=>t("document_closing",o.target.value),placeholder:"Questions? Call or text anytime.",className:"min-h-[64px]"})}),e.jsx("div",{className:"px-4 py-3 md:px-5",children:e.jsx(Gt,{compact:!0,companyInfo:s,businessEmail
34:r.business_email,document:ss(r),onDownload:()=>void Jt(s,{business_email:r.business_email,default_payment_terms:r.default_payment_terms,default_warranty_info:r.default_warranty_info,default_valid_for_days:r.default_valid_for_days})})})]}),e.jsxs(ie,{label:"Monthly payment on options",changed:r.financing_enabled?1:0,children:[e.jsx(x,{label:"Show “as low as $X/month”",help:"On the customer's options, for any option over the minimum. Display only: it's worked out from your rate and term, not a loan offer.",children:e.jsx(H,{checked:r.financing_enabled,onCheckedChange:o=>t("financing_enabled",o),"aria-label":"Show monthly payment on options"})}),r.financing_enabled&&e.jsxs(e.Fragment,{children:[e.jsx(x,{label:"APR",htmlFor:"s-apr",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(R,{id:"s-apr",type:"number",inputMode:"decimal",min:0,max:40,step:"0.01",value:r.financing_apr,onChange:o=>t("financing_apr",Math.max(0,Math.min(40,Number(o.target.value)||0))),className:"w-24 font-mono"}),e.jsx("span",{className:"text-[13px] text-foreground-secondary",children:"%"})]})}),e.jsx(x,{label:"Term",htmlFor:"s-months",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(R,{id:"s-months",type:"number",inputMode:"numeric",min:6,max:240,value:r.financing_months,onChange:o=>t("financing_months",Math.max(6,Math.min(240,Math.round(Number(o.target.value)||6)))),className:"w-24 font-mono"}),e.jsx("span",{className:"text-[13px] text-foreground-secondary",children:"months"})]})}),e.jsx(x,{label:"Only on options over",htmlFor:"s-fin-min",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[13px] text-foreground-secondary",children:"$"}),e.jsx(R,{id:"s-fin-min",type:"number",inputMode:"numeric",min:0,value:r.financing_min_total,onChange:o=>t("financing_min_total",Math.max(0,Number(o.target.value)||0)),className:"w-28 font-mono"})]})}),e.jsx(x,{label:"Lender or note (optional)",htmlFor:"s-fin-note",help:"Shown after the terms, e.g. “Financing through GreenSky.” Use the rate your lender actually offers.",stack:!0,children:e.jsx(R,{id:"s-fin-note",value:r.financing_note,onChange:o=>t("financing_note",o.target.value),placeholder:"Financing through …"})}),e.jsxs("div",{className:"px-4 py-3 text-[13px] text-foreground-secondary md:px-5",children:["A $12,000 option shows as ",e.jsxs("span",{className:"font-medium text-foreground",children:["as low as $",Tt(12e3,r.financing_apr,r.financing_months).toLocaleString("en-US"),"/mo"]}),".",e.jsx("div",{className:"mt-1 text-[12px]",children:Mt({apr:r.financing_apr,months:r.financing_months,min_total:r.financing_min_total,note:r.financing_note})})]})]})]}),e.jsx(ie,{label:"What the customer sees after approving",changed:De(r,Be),children:Be.map((o,d)=>e.jsx(x,{label:`Next step ${d+1}`,htmlFor:`s-${o}`,help:d===0?"Use {deposit_amount} for the deposit.":void 0,stack:!0,children:e.jsx(R,{id:`s-${o}`,value:r[o],onChange:n=>t(o,n.target.value)})},o))})]})})},rs=["E-Transfer","Cash","Cheque","Credit Card","Other"],is=({prefs:s,setPref:r,canManagePayments:t=!0})=>e.jsx("div",{className:"flex flex-col gap-8",children:e.jsxs(U,{title:"How customers pay you",description:"Printed on invoices so customers know how to pay.",children:[e.jsx(x,{label:"Payment methods you take",stack:!0,children:e.jsx("div",{className:"flex flex-wrap gap-1.5",role:"group","aria-label":"Payment methods",children:rs.map(i=>{const l=s.accepted_payment_methods.includes(i);return e.jsx("button",{type:"button","aria-pressed":l,onClick:()=>r("accepted_payment_methods",l?s.accepted_payment_methods.filter(o=>o!==i):[...s.accepted_payment_methods,i]),className:q("h-8 min-h-0 rounded-md px-3 text-[12.5px] font-medium transition-colors",l?"bg-foreground text-background":"bg-ink/[0.05] text-foreground-secondary hover:bg-ink/[0.09] hover:text-foreground"),children:i},i)})})}),s.accepted_payment_methods.includes("E-Transfer")&&e.jsx(x,{label:"E-Transfer email",htmlFor:"s-etransfer",children:e.jsx(R,{id:"s-etransfer",type:"email",value:s.etransfer_email,onChange:i=>r("etransfer_email",i.target.value),className:"sm:w-72"})}),e.jsx(x,{label:"Payment instructions",htmlFor:"s-payinst",help:"Optional. Up to 300 characters.",stack:!0,children:e.jsx(ee,{id:"s-payinst",maxLength:300,value:s.payment_instructions,onChange:i=>r("payment_instructions",i.target.value),placeholder:"Cheques payable to Summit Heating. Card payments by phone.",className:"min-h-[64px]"})}),e.jsx(es,{canManage:t})]})}),ls=[{key:"auto_create_job",label:"Create the job when a customer approves",help:"Lands in Needs scheduling with the approved option and any deposit."},{key:"estimate_followups",label:"Follow up on unanswered quotes",help:"Emails the customer on day 2 and day 5; stops when they answer."},{key:"invoice_reminders",label:"Remind customers about unpaid invoices",help:"3 days before due, on the due date, then 3, 7 and 14 days after."},{key:"maintenance_reminders",label:"Remind plan customers when a tune-up is due",help:"About two weeks before, and 30 days before a plan renews."}],cs=({prefs:s,setPref:r})=>e.jsx("div",{className:"flex flex-col gap-8",children:e.jsx(U,{title:"Automations",description:"Work EstimateKit does for you. All on by default.",children:ls.map(t=>e.jsx(x,{label:t.label,help:t.help,children:e.jsx(H,{checked:s[t.key],onCheckedChange:i=>r(t.key,i),"aria-label":t.label})},t.key))})}),ds=({open:s,onOpenChange:r,onConfirm:t,loading:i})=>e.jsx(Ve,{open:s,onOpenChange:r,children:e.jsxs(Xe,{className:"max-w-md",children:[e.jsxs(Ze,{children:[e.jsxs("div",{className:"flex items-center gap-3 mb-2",children:[e.jsx(Rt,{className:"h-5 w-5 text-bad",strokeWidth:1.8}),e.jsx(Ge,{children:"Cancel your free trial?"})]}),e.jsx(Je,{className:"text-[13.5px] text-foreground-secondary",children:"If you cancel now, you'll lose access immediately and won't be charged. You can always subscribe again later."})]}),e.jsxs(et,{children:[e.jsx(tt,{disabled:i,children:"Keep my trial"}),e.jsx(st,{onClick:l=>{l.preventDefault(),t()},disabled:i,className:"bg-red-600 hover:bg-red-700",children:i?"Canceling…":"Yes, cancel my trial"})]})]})}),us=()=>{const[s,r]=m.useState(null);if(m.useEffect(()=>{let i=!0;return(async()=>{const{data:{session:l}}=await P.auth.getSession();if(!l)return;const{data:o}=await P.from("users").select("mobile_phone, sms_opt_in_at, sms_opt_out_at").eq("id",l.user.id).maybeSingle();i&&(o!=null&&o.mobile_phone)&&r({id:l.user.id,mobile_phone:o.mobile_phone,on:!!o.sms_opt_in_at&&!o.sms_opt_out_at})})(),()=>{i=!1}},[]),!s)return null;const t=async i=>{const l=new Date().toISOString(),o=i?{sms_opt_in_at:l,sms_opt_out_at:null}:{sms_opt_out_at:l};r({...s,on:i});const{error:d}=await P.from("users").update(o).eq("id",s.id);d&&(r({...s,on:!i}),b({title:"Couldn't save that",description:d.message,variant:"destructive"}))};return e.jsxs(We,{className:"rounded-xl border-ink/[0.06] bg-card",children:[e.jsxs(Ue,{className:"space-y-1.5 p-5 pb-4",children:[e.jsx(Ye,{className:"text-[15px] font-semibold tracking-normal",children:"Texts from EstimateKit"}),e.jsx(Ke,{className:"text-[13px] leading-snug text-foreground-secondary",children:"To you, not your customers"})]}),e.jsx(He,{className:"p-5 pt-0",children:e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx(te,{htmlFor:"setup-texts",className:"text-[13.5px] font-medium",children:"Setup help and trial reminders"}),e.jsxs("p",{className:"mt-1 text-[12.5px] leading-snug text-foreground-secondary",children:["A few texts at most, to ",At(s.mobile_phone),". Replying STOP turns them off too."]})]}),e.jsx(H,{id:"setup-texts",checked:s.on,onCheckedChange:i=>void t(i)})]})})]})},ms=({open:s,onOpenChange:r})=>{const[t,i]=m.useState(null),[l,o]=m.useState(null),[d,n]=m.useState(""),[a,g]=m.useState(!1);m.useEffect(()=>{s&&(i(null),o(null),n(""),P.functions.invoke("delete-account",{body:{preview:!0}}).then(({data:j,error:D})=>{D||j!=null&&j.error?o((j==null?void 0:j.error)||"Couldn't check your account. Try again."):i(j)}))},[s]);const u=async()=>{g(!0);const{data:j,error:D}=await P.functions.invoke("delete-account",{body:{confirm:"DELETE"}}),N=j==null?void 0:j.error;if(D||N){g(!1),b({title:"Not deleted",description:N||"Something went wrong. Try again, or email [email protected].",variant:"destructive"});return}await P.auth.signOut().catch(()=>{}),Z()?window.location.hash="/login":window.location.assign("/login")},_=(t==null?void 0:t.scope)==="company";return e.jsx(Qe,{open:s,onOpenChange:j=>!a&&r(j),children:e.jsxs(ze,{className:"max-w-[440px]",children:[e.jsx($e,{className:"text-[19px] font-medium",children:"Delete your account?"}),e.jsx(mt,{asChild:!0,children:e.jsxs("div",{className:"flex flex-col gap-3 text-[13.5px] leading-relaxed text-foreground-secondary",children:[l&&e.jsx("p",{className:"text-destructive",children:l}),!t&&!l&&e.jsx("p",{children:"Checking your account…"}),t&&(_?e.jsxs(e.Fragment,{children:[e.jsxs("p",{children:["You own ",e.jsx("span",{className:"font-medium text-foreground",children:t.companyName||"this company"}),", so this closes the whole company account:"]}),e.jsxs("ul",{className:"list-disc space-y-1 pl-5",children:[e.jsxs("li",{children:[t.otherMembers===0?"Your login stops":t.otherMembers===1?"Your login and your team member's login stop":`Your login and your ${t.otherMembers} team members' logins stop`," working right away."]}),t.paidSubscription&&e.jsx("li",{children:"The paid plan is cancelled now, so nobody is charged again."}),e.jsxs("li",{children:["Every customer, quote, job, invoice and price book item is permanently deleted within ",t.purgeDays," days."]})]}),e.jsx("p",{children:"Want a copy first? Use Download my data before you continue."})]}):e.jsxs(e.Fragment,{children:[e.jsx("p",{children:"This closes your own login. You'll be signed out and won't be able to sign back in."}),e.jsxs("p",{children:["Quotes, jobs and customers you created stay with ",t.companyName||"your company",", because they belong to the company. Your personal details are removed within ",t.purgeDays," days."]})]}))]})}),t&&e.jsxs("div",{className:"mt-2 flex flex-col gap-2",children:[e.jsxs("label",{htmlFor:"del-confirm",className:"text-[13px] text-foreground",children:["Type ",e.jsx("span",{className:"font-mono font-semibold",children:"DELETE"})," to confirm"]}),e.jsx(R,{id:"del-confirm",value:d,onChange:j=>n(j.target.value),autoComplete:"off",autoCapitalize:"characters"}),e.jsxs("div",{className:"mt-2 flex gap-2",children:[e.jsx(k,{variant:"outline",className:"flex-1",onClick:()=>r(!1),disabled:a,children:"Keep my account"}),e.jsx(k,{variant:"destructive",className:"flex-1",onClick:()=>void u(),disabled:a||d.trim()!=="DELETE",children:a?"Deleting…":_?"Delete company":"Delete my login"})]})]})]})})},hs=()=>{const s=Ne(),[r,t]=m.useState(!1),[i,l]=m.useState(null),[o,d]=m.useState(!1),[n,a]=m.useState(!1);m.useEffect(()=>{g()},[]);const g=async()=>{try{t(!0);const{data:p,error:T}=await P.functions.invoke("check-subscription");if(T)throw T;l(p)}catch(p){console.error("Error checking subscription:",p)}finally{t(!1)}},u=async()=>
34{if(!ce())try{t(!0);const{data:p,error:T}=await P.functions.invoke("customer-portal");if(T)throw T;p!=null&&p.url&&window.open(p.url,"_blank")}catch(p){console.error("Portal error:",p),b({title:"Error",description:p.message||"Failed to open customer portal",variant:"destructive"})}finally{t(!1)}},_=async()=>{if(!ce())try{if(t(!0),(i==null?void 0:i.subscription_status)==="active"||(i==null?void 0:i.subscription_status)==="trialing"){b({title:"Already subscribed",description:"Your plan is already active."});return}const{data:{session:p}}=await P.auth.getSession();if(!p){s("/login");return}await P.functions.invoke("ensure-provisioned",{headers:{Authorization:`Bearer ${p.access_token}`}}),_e(()=>import("./onboardingEvents-iM3xWPll.js"),__vite__mapDeps([3,1,2])).then(M=>M.logOnboarding("checkout_started",{from:"settings"}));const{data:T,error:L}=await P.functions.invoke("create-checkout",{headers:{Authorization:`Bearer ${p.access_token}`}});if(L)throw L;T!=null&&T.url&&(window.location.href=T.url)}catch(p){console.error("Checkout error:",p),b({title:"Error",description:(p==null?void 0:p.message)||"Failed to start checkout",variant:"destructive"})}finally{t(!1)}},j=async()=>{if(!ce())try{a(!0);const{data:p,error:T}=await P.functions.invoke("cancel-subscription");if(T)throw T;b({title:"Trial Canceled",description:"Your trial has been canceled. You won't be charged."}),d(!1),xt(),await g(),setTimeout(()=>{s(Z()?"/dashboard":"/pricing")},3e3)}catch(p){console.error("Cancel error:",p),b({title:"Error",description:p.message||"Unable to cancel trial. Please try again or contact support.",variant:"destructive"})}finally{a(!1)}},D=p=>{const T=new Date,L=new Date(p);return Math.ceil((L.getTime()-T.getTime())/(1e3*60*60*24))},N=(i==null?void 0:i.subscription_status)??null,C=p=>new Date(p).toLocaleDateString("en-US",{month:"long",day:"numeric",year:"numeric"}),f=!!(i!=null&&i.is_stripe_subscription),y=N==="trialing",h=N==="trial"&&!!(i!=null&&i.trial_end),v=N==="active"||y,O=i!=null&&i.trial_end?Math.max(0,D(i.trial_end)):null,E=({tone:p,children:T})=>e.jsx("span",{className:p==="green"?"rounded-[5px] bg-emerald-500/15 px-1.5 py-px text-[11.5px] font-medium text-ok":p==="amber"?"rounded-[5px] bg-amber-500/15 px-1.5 py-px text-[11.5px] font-medium text-warn":"rounded-[5px] bg-ink/10 px-1.5 py-px text-[11.5px] font-medium text-foreground-secondary",children:T});return r&&!i?e.jsx("div",{className:"max-w-2xl",children:e.jsx("div",{className:"h-40 animate-pulse rounded-xl bg-ink/[0.04]","aria-busy":"true"})}):e.jsxs("div",{className:"flex max-w-2xl flex-col gap-8",children:[e.jsxs(U,{title:"Plan and billing",description:"One plan for the whole crew, up to 25 people.",children:[e.jsx(x,{label:"EstimateKit Pro",help:"$49 a month, or $69 CAD. Unlimited quotes, jobs and invoices.",children:v&&!y?e.jsx(E,{tone:"green",children:"Active"}):y||h?e.jsxs(E,{tone:"amber",children:["Free trial",O!==null?` · ${O} day${O===1?"":"s"} left`:""]}):e.jsx(E,{tone:"grey",children:N==="canceled"?"Canceled":N==="expired"?"Trial ended":"Not subscribed"})}),(y||h)&&(i==null?void 0:i.trial_end)&&e.jsx(x,{label:y?"First charge":"Trial ends",help:y?"Cancel before then and you won't be charged.":"Everything you make stays yours either way.",children:e.jsx("span",{className:"font-mono text-[13px] text-foreground",children:C(i.trial_end)})}),N==="active"&&(i==null?void 0:i.subscription_end)&&e.jsx(x,{label:"Next bill",children:e.jsx("span",{className:"font-mono text-[13px] text-foreground",children:C(i.subscription_end)})}),v&&f&&e.jsx(x,{label:"Card, invoices and cancelling",help:"Opens your secure billing page from Stripe.",children:e.jsxs(k,{variant:"outline",size:"sm",onClick:u,disabled:r,className:"gap-1.5",children:[e.jsx(at,{className:"h-4 w-4",strokeWidth:1.8})," Manage billing"]})}),v&&!f&&e.jsx(x,{label:"Billing",help:"Your plan is billed directly by EstimateKit. Questions or changes: [email protected]",children:e.jsx("span",{className:"text-[13px] text-foreground-tertiary",children:"No card on file"})}),(h||!v)&&e.jsx(x,{label:h?"Keep EstimateKit after the trial":"Subscribe",help:h?"Subscribe now and billing starts the day your trial would have ended. You keep every free day.":"Everything you made is still here. Subscribing turns creating and sending back on.",children:e.jsx(k,{variant:"orange",size:"sm",onClick:_,disabled:r,children:r?"Opening…":N==="c
34anceled"?"Subscribe again":"Subscribe"})}),y&&e.jsx(x,{label:"Cancel the trial",help:"You won't be charged.",children:e.jsx(k,{variant:"ghost",size:"sm",onClick:()=>d(!0),disabled:r,className:"text-destructive hover:bg-destructive/10 hover:text-destructive",children:"Cancel trial"})})]}),e.jsx(ds,{open:o,onOpenChange:d,onConfirm:j,loading:n})]})},xs=()=>{const s=Ne(),[r,t]=m.useState(""),[i,l]=m.useState(""),[o,d]=m.useState(""),[n,a]=m.useState(!1),[g,u]=m.useState(!1),[_,j]=m.useState(!1),[D,N]=m.useState(""),[C,f]=m.useState(""),[y,h]=m.useState(""),[v,O]=m.useState(!1),[E,p]=m.useState(!1),[T,L]=m.useState(!1),[M,A]=m.useState(!1);m.useEffect(()=>{let w=!0;return(async()=>{const{data:{session:Q}}=await P.auth.getSession();if(!Q||!w)return;l(Q.user.email||"");const{data:z}=await P.from("users").select("full_name").eq("id",Q.user.id).maybeSingle();w&&(t((z==null?void 0:z.full_name)||""),d((z==null?void 0:z.full_name)||""))})(),()=>{w=!1}},[]);const I=async()=>{a(!0);try{const{data:{session:w}}=await P.auth.getSession();if(!w)throw new Error("Not signed in");const{error:Q}=await P.from("users").update({full_name:r.trim()||null}).eq("id",w.user.id);if(Q)throw Q;d(r),b({title:"Name saved"})}catch(w){b({title:"Couldn't save",description:w instanceof Error?w.message:"Please try again.",variant:"destructive"})}finally{a(!1)}};return e.jsxs("div",{className:"flex max-w-2xl flex-col gap-8",children:[e.jsxs(U,{title:"You",description:"Your own login. Company settings are shared with the office.",children:[e.jsx(x,{label:"Your name",htmlFor:"s-fullname",help:"How you appear on jobs and in the team list.",children:e.jsxs("div",{className:"flex gap-2",children:[e.jsx(R,{id:"s-fullname",value:r,onChange:w=>t(w.target.value),className:"sm:w-56"}),r!==o&&e.jsx(k,{type:"button",variant:"orange",size:"sm",className:"h-9",disabled:n,onClick:()=>void I(),children:n?"Saving…":"Save"})]})}),e.jsx(x,{label:"Sign-in email",children:e.jsx("span",{className:"font-mono text-[13px] text-foreground-secondary",children:i})}),e.jsx(x,{label:"Dark mode",help:"Coming soon.",children:e.jsx(H,{checked:!1,disabled:!0,"aria-label":"Dark mode, coming soon"})})]}),e.jsx(us,{}),e.jsxs(We,{className:"rounded-xl border-ink/[0.06] bg-card",children:[e.jsxs(Ue,{className:"space-y-1.5 p-5 pb-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ht,{className:"h-[18px] w-[18px] text-foreground-tertiary",strokeWidth:1.8}),e.jsx(Ye,{className:"text-[15px] font-semibold tracking-normal",children:"Change password"})]}),e.jsx(Ke,{className:"text-[13px] leading-snug text-foreground-secondary",children:"At least 8 characters."})]}),e.jsxs(He,{className:"p-5 pt-0 space-y-4",children:[e.jsxs("div",{children:[e.jsx(te,{htmlFor:"current_password",children:"Current Password"}),e.jsxs("div",{className:"relative mt-1",children:[e.jsx(R,{id:"current_password",type:v?"text":"password",value:D,onChange:w=>N(w.target.value),placeholder:"Enter current password",className:"pr-10"}),e.jsx("button",{type:"button",onClick:()=>O(!v),className:"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",children:v?e.jsx(ue,{className:"h-4 w-4"}):e.jsx(re,{className:"h-4 w-4"})})]})]}),e.jsxs("div",{children:[e.jsx(te,{htmlFor:"new_password",children:"New Password"}),e.jsxs("div",{className:"relative mt-1",children:[e.jsx(R,{id:"new_password",type:E?"text":"password",value:C,onChange:w=>f(w.target.value),placeholder:"Enter new password",className:"pr-10"}),e.jsx("button",{type:"button",onClick:()=>p(!E),className:"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",children:E?e.jsx(ue,{className:"h-4 w-4"}):e.jsx(re,{className:"h-4 w-4"})})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Must be at least 8 characters"})]}),e.jsxs("div",{children:[e.jsx(te,{htmlFor:"confirm_password",children:"Confirm New Password"}),e.jsxs("div",{className:"relative mt-1",children:[e.jsx(R,{id:"confirm_password",type:T?"text":"password",value:y,onChange:w=>h(w.target.value),placeholder:"Confirm new password",className:"pr-10"}),e.jsx("button",{type:"button",onClick:()=>L(!T),className:"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",children:T?e.jsx(ue,{className:"h-4 w-4"}):e.jsx(re,{className:"h-4 w-4"})})]})]}),e.jsx(k,{onClick:async()=>
34{if(!D||!C||!y){b({title:"Error",description:"Please fill in all password fields",variant:"destructive"});return}if(C.length<8){b({title:"Error",description:"New password must be at least 8 characters",variant:"destructive"});return}if(C!==y){b({title:"Error",description:"New passwords do not match",variant:"destructive"});return}A(!0);try{const{data:{user:w}}=await P.auth.getUser();if(!(w!=null&&w.email))throw new Error("No user email found");const{error:Q}=await P.auth.signInWithPassword({email:w.email,password:D});if(Q){b({title:"Error",description:"Current password is incorrect",variant:"destructive"});return}const{error:z}=await P.auth.updateUser({password:C});if(z)throw z;b({title:"Success",description:"Password updated successfully"}),N(""),f(""),h("")}catch(w){console.error("Error updating password:",w),b({title:"Error",description:w.message||"Failed to update password",variant:"destructive"})}finally{A(!1)}},disabled:M||!D||!C||!y,className:"w-full sm:w-auto",children:M?e.jsx(e.Fragment,{children:"Saving…"}):e.jsxs(e.Fragment,{children:[e.jsx(nt,{className:"mr-2 h-4 w-4"}),"Update password"]})})]})]}),e.jsxs(U,{title:"Help and your data",children:[e.jsx(x,{label:"Replay the walkthrough",help:"Send yourself a sample quote and approve it on your phone.",children:e.jsxs(k,{variant:"outline",size:"sm",onClick:()=>s("/dashboard?firstwin=1"),className:"gap-1.5",children:[e.jsx(Qt,{className:"h-4 w-4",strokeWidth:1.8})," Replay"]})}),e.jsx(x,{label:"Download my data",help:"Every customer, quote, job, invoice, price book item and template, as spreadsheets.",children:e.jsxs(k,{variant:"outline",size:"sm",disabled:g,onClick:async()=>{u(!0);try{const{exportAllData:w}=await _e(async()=>{const{exportAllData:z}=await import("./index-CbvCveKN.js").then(c=>c.bI);return{exportAllData:z}},__vite__mapDeps([1,2])),{files:Q}=await w();b({title:Q.length?`Downloaded ${Q.length} spreadsheet${Q.length===1?"":"s"}`:"Nothing to export yet"})}catch(w){b({title:"Export failed",description:w instanceof Error?w.message:"Try again.",variant:"destructive"})}finally{u(!1)}},className:"gap-1.5",children:[e.jsx(ve,{className:"h-4 w-4",strokeWidth:1.8})," ",g?"Preparing…":"Download"]})}),e.jsx(x,{label:"Delete my account",help:"Closes your login. If you own the company, it closes the company account and deletes its data.",children:e.jsxs(k,{variant:"ghost",size:"sm",onClick:()=>j(!0),className:"gap-1.5 text-destructive hover:bg-destructive/10 hover:text-destructive",children:[e.jsx(zt,{className:"h-4 w-4",strokeWidth:1.8})," Delete"]})})]}),e.jsx(ms,{open:_,onOpenChange:j})]})},ot=({request:s,onClose:r})=>e.jsx(Ve,{open:!!s,onOpenChange:t=>{t||r()},children:e.jsxs(Xe,{className:"max-w-md",children:[e.jsxs(Ze,{children:[e.jsx(Ge,{children:s==null?void 0:s.title}),e.jsx(Je,{className:"text-[13.5px] text-foreground-secondary",children:s==null?void 0:s.body})]}),e.jsxs(et,{children:[e.jsx(tt,{children:"Cancel"}),e.jsx(st,{className:q((s==null?void 0:s.destructive)&&"bg-[#dc2626] text-white hover:bg-[#b91c1c]"),onClick:()=>{const t=s==null?void 0:s.run;r(),t==null||t()},children:s==null?void 0:s.action})]})]})}),rt=async(s,r="QuickBooks didn't answer. Try again.")=>{var t;try{const i=await((t=s.context)==null?void 0:t.json());if(i!=null&&i.error)return String(i.error)}catch{}return r},ps={invoice:"Invoice",payment:"Payment",customer:"Customer"},X=s=>s.label||ps[s.kind]||"Record",Pe=s=>({income:s.income_account_id??"",taxMap:Object.fromEntries(Object.entries(s.tax_map).map(([r,t])=>[r,t??""])),from:s.sync_from}),gs=(s,r)=>s.income===r.income&&s.from===r.from&&JSON.stringify(s.taxMap)===JSON.stringify(r.taxMap),ne=async s=>{const r=(()=>{try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return}})(),{data:t,error:i}=await P.functions.invoke("quickbooks-sync",{body:{...s,tz:r}});if(t!=null&&t.error)throw new Error(t.error);if(i)throw new Error(await rt(i));return t},fs=()=>{const[s,r]=m.useState(null),[t,i]=m.useState({income:"",taxMap:{},from:""}),[l,o]=m.useState({income:"",taxMap:{},from:""}),[d,n]=m.useState(null),[a,g]=m.useState(!1),[u,_]=m.useState(null),[j,D]=m.useState(null),[N,C]=m.useState(null),f=()=>ne({action:"log"}).then(n).catch(()=>{}),y=()=>{D(null),ne({action:"setup"}).then(c=>{r(c),i(Pe(c)),o(Pe(c))}).catch(c=>D(c.message))};m.useEffect(()=>{y(),f()},[]);const h=(d==null?void 0:d.waiting.some(c=>
34!c.parked&&new Date(c.next_at).getTime()-Date.now()<30*60*1e3))??!1,v=!!(s!=null&&s.enabled)&&h;if(m.useEffect(()=>{if(!v)return;const c=setInterval(()=>void f(),15e3);return()=>clearInterval(c)},[v]),j)return e.jsx(x,{label:"Sync settings",help:j,children:e.jsx(k,{variant:"outline",onClick:y,className:"h-9",children:"Try again"})});if(!s)return e.jsx(x,{label:"Sync settings",help:"Reading your QuickBooks setup…",children:e.jsx(Y,{className:"h-4 w-4 animate-spin text-foreground-tertiary"})});const O=!gs(l,t),E=Object.entries(l.taxMap).filter(([,c])=>!c).map(([c])=>c),p=async c=>{g(!0);try{const B=await ne({action:"save",income_account_id:l.income||void 0,tax_map:Object.fromEntries(Object.entries(l.taxMap).filter(([,$])=>$)),sync_from:l.from,...c===void 0?{}:{enabled:c}});i(l),c!==void 0&&r({...s,enabled:c});const G=je(we(l.from),"MMM d, yyyy");b({title:c===!0?"Sending to QuickBooks is on":c===!1?"Sending to QuickBooks is paused":"Saved",description:c===!0&&B.queued?`${B.queued} invoice${B.queued===1?"":"s"} sent since ${G} will copy over in the next minute or two.`:void 0}),setTimeout(f,1500)}catch(B){b({title:"Couldn't save",description:B instanceof Error?B.message:void 0,variant:"destructive"})}finally{g(!1)}},T=async(c,B,G=!1)=>{_(c.ek_id);try{await ne({action:B,kind:c.kind,ek_id:c.ek_id,force:G}),b({title:B==="dismiss"?"Left out of QuickBooks":G?"EstimateKit's version will replace the QuickBooks copy shortly":"Trying again in the next minute or two"}),setTimeout(f,B==="dismiss"?300:1500)}catch($){b({title:B==="dismiss"?"Couldn't dismiss it":"Couldn't try again",description:$ instanceof Error?$.message:void 0,variant:"destructive"})}finally{_(null)}},L=c=>C({title:`Leave ${X(c)} out of QuickBooks?`,body:"EstimateKit stops trying to send it. If it belongs in your books, enter it in QuickBooks by hand.",action:"Leave it out",run:()=>void T(c,"dismiss")}),M=c=>C({title:`Replace the QuickBooks copy of ${X(c)}?`,body:"EstimateKit's version replaces it. The change someone made in QuickBooks will be lost.",action:"Replace it",destructive:!0,run:()=>void T(c,"retry",!0)}),A=(d==null?void 0:d.waiting.filter(c=>c.parked))??[],I=(d==null?void 0:d.waiting.filter(c=>!c.parked&&c.last_error))??[],w=(d==null?void 0:d.waiting.filter(c=>!c.parked&&!c.last_error))??[],Q=new Set(((d==null?void 0:d.waiting)??[]).map(c=>c.ek_id)),z=((d==null?void 0:d.log)??[]).filter(c=>c.ok||!c.ek_id||!Q.has(c.ek_id));return e.jsxs(e.Fragment,{children:[e.jsx(x,{label:"Income account",help:"Where invoice lines are recorded in QuickBooks. Each EstimateKit category (Equipment, Labor, Materials…) gets its own QuickBooks product under this account.",stack:!0,children:e.jsxs(pe,{value:l.income,onValueChange:c=>o({...l,income:c}),children:[e.jsx(ge,{className:"sm:w-72","aria-label":"Income account",children:e.jsx(fe,{placeholder:"Choose an account"})}),e.jsx(ye,{children:s.accounts.map(c=>e.jsx(be,{value:c.id,children:c.name},c.id))})]})}),s.automated_tax&&e.jsx(x,{label:"Sales tax",help:"Your QuickBooks works US sales tax out automatically, and EstimateKit can't send invoices to that setup yet. It's coming soon.",children:e.jsx("span",{})}),Object.keys(l.taxMap).length>0&&e.jsxs(x,{label:"Sales tax codes",help:s.country==="CA"?"The QuickBooks tax code for each rate you charge. QuickBooks works the tax out from these, and EstimateKit checks its total matches to the cent.":"The QuickBooks sales tax rate that matches each rate you charge. Taxed lines are marked taxable in QuickBooks, and EstimateKit checks the total matches to the cent.",stack:!0,children:[e.jsx("div",{className:"flex flex-col gap-2",children:Object.keys(l.taxMap).map(c=>e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"w-16 shrink-0 font-mono text-[13px] text-foreground",children:[c,"%"]}),e.jsxs(pe,{value:l.taxMap[c],onValueChange:B=>o({...l,taxMap:{...l.taxMap,[c]:B}}),children:[e.jsx(ge,{className:"sm:w-72","aria-label":`Tax code for ${c}%`,children:e.jsx(fe,{placeholder:"Choose a tax code"})}),e.jsxs(ye,{children:[s.tax_codes.filter(B=>B.rate===Number(c)).map(B=>
34e.jsxs(be,{value:B.id,children:[B.name," (",B.rate,"%)"]},B.id)),s.tax_codes.filter(B=>B.rate===Number(c)).length===0&&e.jsxs("div",{className:"px-3 py-2 text-[13px] text-foreground-tertiary",children:["No ",c,"% code in QuickBooks. Add one there first."]})]})]})]},c))}),E.length>0&&e.jsx("p",{className:"mt-2 text-[12px] text-foreground-tertiary",children:"Rates left blank are fine if you no longer charge them. An invoice that uses one waits below until you choose a code."})]}),e.jsx(x,{label:"Start with invoices sent on or after",help:"Earlier invoices stay out of QuickBooks, so nothing you've already entered there by hand is doubled.",htmlFor:"qbo-from",children:e.jsx(R,{id:"qbo-from",type:"date",value:l.from,onChange:c=>o({...l,from:c.target.value}),className:"sm:w-48"})}),e.jsx(x,{label:"Send to QuickBooks",help:s.enabled?"On. Sent invoices, their customers and every payment copy over within a couple of minutes.":s.automated_tax?"Not available yet for automatic US sales tax.":l.income?"Off. Turn on to start copying.":"Choose an income account first.",children:e.jsxs("div",{className:"flex items-center gap-3",children:[O&&e.jsxs(k,{variant:"outline",onClick:()=>void p(),disabled:a,className:"h-9 gap-2",children:[a&&e.jsx(Y,{className:"h-4 w-4 animate-spin"}),"Save"]}),e.jsx(H,{checked:s.enabled,disabled:a||!l.income||!s.enabled&&!!s.automated_tax,onCheckedChange:c=>void p(c),"aria-label":"Send to QuickBooks"})]})}),d&&(d.waiting.length>0||z.length>0)&&e.jsxs("div",{className:"px-4 py-3 md:px-5",children:[e.jsx("p",{className:"text-[13.5px] font-medium text-foreground",children:"Sync activity"}),e.jsxs("ul",{className:"mt-2 divide-y divide-ink/[0.06]",children:[A.map(c=>e.jsxs("li",{className:"flex flex-col gap-1.5 py-2.5 sm:flex-row sm:items-center sm:gap-3",children:[e.jsxs("div",{className:"flex min-w-0 flex-1 items-start gap-3",children:[e.jsx("span",{className:"mt-1.5 h-2 w-2 shrink-0 rounded-full bg-[#F04438]","aria-hidden":!0}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"truncate text-[13px] text-foreground",children:X(c)}),e.jsx("p",{className:"text-[12px] leading-[1.45] text-bad",children:c.last_error})]})]}),e.jsxs("div",{className:"flex shrink-0 gap-1 pl-5 sm:pl-0",children:[u===c.ek_id&&e.jsx(Y,{className:"my-2 h-4 w-4 animate-spin text-foreground-tertiary","aria-label":"Working"}),c.edited?e.jsx(k,{variant:"ghost",onClick:()=>M(c),disabled:u===c.ek_id,"aria-label":`Overwrite QuickBooks: ${X(c)}`,className:"h-8 px-2.5 text-[12.5px]",children:"Overwrite QuickBooks"}):e.jsx(k,{variant:"ghost",onClick:()=>void T(c,"retry"),disabled:u===c.ek_id,"aria-label":`Try again: ${X(c)}`,className:"h-8 px-2.5 text-[12.5px]",children:"Try again"}),e.jsx(k,{variant:"ghost",onClick:()=>L(c),disabled:u===c.ek_id,"aria-label":`Dismiss: ${X(c)}`,className:"h-8 px-2 text-[12.5px] text-foreground-tertiary",children:"Dismiss"})]})]},`s-${c.kind}-${c.ek_id}`)),I.map(c=>e.jsxs("li",{className:"flex items-start gap-3 py-2.5",children:[e.jsx("span",{className:"mt-1.5 h-2 w-2 shrink-0 rounded-full bg-[#F79009]","aria-hidden":!0}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"truncate text-[13px] text-foreground",children:X(c)}),e.jsx("p",{className:"text-[12px] leading-[1.45] text-foreground-tertiary",children:c.last_error})]})]},`r-${c.kind}-${c.ek_id}`)),z.map((c,B)=>e.jsxs("li",{className:"flex items-start gap-3 py-2",children:[e.jsx("span",{className:q("mt-1.5 h-2 w-2 shrink-0 rounded-full",c.ok?"bg-[#12B76A]":"bg-[#F04438]"),"aria-hidden":!0}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"truncate text-[13px] text-foreground",children:X(c)}),e.jsxs("p",{className:q("text-[12px] text-foreground-tertiary",c.ok?"truncate":"line-clamp-2"),children:[je(we(c.created_at),"MMM d, h:mm a")," · ",c.message]})]})]},B))]}),w.length>0&&e.jsx("p",{className:"mt-2 text-[12px] text-foreground-tertiary",children:s.enabled?`${w.length} waiting to copy.`:`${w.length} waiting. They'll copy over when sending is turned back on.`})]}),e.jsx(ot,{request:N,onClose:()=>C(null)})]})},me="ek-qbo-nonce",he="ek-qbo-seen",Oe={get:()=>{try{return localStorage.getItem(he)==="1"}catch{return!1}},set:s=>{try{s?localStorage.setItem(he,"1"):localStorage.removeItem(he)}catch{}}},xe={get:()=>{try{return sessionStorage.getItem(me)}catch{return null}}
34,set:s=>{try{sessionStorage.setItem(me,s)}catch{}},clear:()=>{try{sessionStorage.removeItem(me)}catch{}}},Re={connected:["QuickBooks connected"],cancelled:["QuickBooks wasn't connected","You cancelled on the QuickBooks screen."],expired:["That took too long","Press Connect QuickBooks again."],failed:["QuickBooks didn't connect","Try again in a minute."]},oe=async(s,r={})=>{const{data:t,error:i}=await P.functions.invoke("quickbooks-oauth",{body:{action:s,...r}});if(i&&!t)throw new Error(await rt(i));if(t!=null&&t.error&&!(t!=null&&t.connected))throw new Error(t.error);return t},ys=()=>{const[s,r]=m.useState(null),[t,i]=m.useState(!1),[l,o]=m.useState(!1),[d,n]=m.useState(null),[a,g]=Ie(),u=()=>oe("status").then(f=>{Oe.set(f.available!==!1),r(f)}).catch(()=>r(f=>f!=null&&f.connected?{...f,working:!0,unreachable:!0}:{failed:!0,connected:!1}));m.useEffect(()=>{const f=a.get("qbo_state"),y=a.get("qbo_code"),h=a.get("qbo_realm");if(f&&y&&h){["qbo_state","qbo_code","qbo_realm"].forEach(E=>a.delete(E)),g(a,{replace:!0});const O=xe.get();xe.clear(),i(!0),o(!0),r({available:!0,connected:!1}),(O?oe("finish",{state:f,code:y,realm:h,nonce:O}):Promise.reject(new Error("Finish connecting in the same browser you started in. Press Connect QuickBooks again."))).then(()=>b({title:"QuickBooks connected"})).catch(E=>b({title:"QuickBooks didn't connect",description:E instanceof Error?E.message:void 0,variant:"destructive"})).finally(()=>{u().finally(()=>{i(!1),o(!1)})});return}const v=a.get("quickbooks");if(v&&Re[v]){const[O,E]=Re[v];b({title:O,description:E,variant:v==="connected"?void 0:"destructive"}),a.delete("quickbooks"),g(a,{replace:!0})}u()},[]),m.useEffect(()=>{const f=y=>{y.persisted&&i(!1)};return window.addEventListener("pageshow",f),()=>window.removeEventListener("pageshow",f)},[]);const _="QuickBooks Online",j="Connect your QuickBooks Online company. Customers, invoices and payments will copy across so nobody retypes them.";if(!s)return Oe.get()?e.jsx(U,{title:_,description:j,children:e.jsx(x,{label:"Checking QuickBooks…",children:e.jsx(Y,{className:"h-4 w-4 animate-spin text-foreground-tertiary","aria-label":"Loading"})})}):null;if(s.available===!1)return null;if(s.failed)return e.jsx(U,{title:_,description:j,children:e.jsx(x,{label:"Couldn't check QuickBooks",help:"Reload the page to try again.",children:e.jsx(k,{variant:"outline",onClick:()=>{r(null),u()},className:"h-9",children:"Try again"})})});const D=async(f=!1)=>{i(!0);try{const{url:y,nonce:h}=await oe("start",{origin:window.location.origin,...f?{sandbox:!0}:{}});xe.set(h),window.location.href=y}catch(y){i(!1),b({title:"Couldn't open QuickBooks",description:y instanceof Error?y.message:void 0,variant:"destructive"})}},N=()=>n({title:"Disconnect QuickBooks?",body:"Nothing already in QuickBooks changes. Sending stops, and you'll turn it back on after reconnecting.",action:"Disconnect",destructive:!0,run:()=>void C()}),C=async()=>{i(!0);try{await oe("disconnect"),b({title:"QuickBooks disconnected"}),await u()}catch(f){b({title:"Couldn't disconnect",description:f instanceof Error?f.message:void 0,variant:"destructive"})}finally{i(!1)}};return e.jsxs(U,{title:_,description:j,children:[s.connected?e.jsx(x,{label:s.working===!1?"Connection needs attention":`Connected to ${s.company_name||"QuickBooks"}`,help:s.working===!1?Z()?"QuickBooks was disconnected or its sign-in expired. Reconnect from EstimateKit in a web browser on your computer. Nothing waiting is lost.":"QuickBooks was disconnected or its sign-in expired. Press Reconnect. Nothing waiting is lost.":s.unreachable?"QuickBooks isn't answering right now. Syncing catches up on its own.":s.environment==="sandbox"?"Test (sandbox) company.":void 0,children:e.jsxs("div",{className:"flex items-center gap-3",children:[s.working!==!1&&e.jsx(qe,{className:"h-5 w-5 text-ok","aria-hidden":!0}),s.working===!1&&!Z()&&e.jsxs(k,{onClick:()=>void D(s.environment==="sandbox"),disabled:t,className:"h-9 gap-2",children:[t&&e.jsx(Y,{className:"h-4 w-4 animate-spin"}),"Reconnect"]}),e.jsx(k,{variant:"ghost",onClick:N,disabled:t,className:"h-9 text-foreground-tertiary hover:text-bad",children:"Disconnect"})]})}
34):null,s.connected&&s.working!==!1&&e.jsx(fs,{}),s.connected?null:e.jsx(x,{label:l?"Connecting to QuickBooks…":"Not connected",help:l?"Saving the connection. This takes a few seconds.":Z()?"Connect QuickBooks from EstimateKit in a web browser on your computer. Once it's connected, syncing works everywhere.":"You'll sign in to QuickBooks and pick your company. EstimateKit only asks for accounting access.",children:!Z()&&!l&&e.jsxs("div",{className:"flex items-center gap-2",children:[s.sandbox_allowed&&e.jsx(k,{variant:"ghost",onClick:()=>void D(!0),disabled:t,className:"h-10 text-foreground-tertiary",children:"Sandbox"}),e.jsxs(k,{onClick:()=>void D(),disabled:t,className:"h-10 gap-2",children:[t&&e.jsx(Y,{className:"h-4 w-4 animate-spin"}),"Connect QuickBooks"]})]})}),e.jsx(ot,{request:d,onClose:()=>n(null)})]})},J=async(s,r)=>{const{data:t,error:i}=await P.rpc(s,r);if(i)throw new Error(i.message);return t},bs=[["customer","name, email, phone, address"],["selected_option","the option they picked, with its total"],["line_items","every line: name, category, quantity, price (and internal_cost, your cost)"],["equipment","the equipment lines on the quote"],["customer_equipment","units already on file: brand, model, serial"],["totals","subtotal, tax, total, deposit due"],["job, deposit_invoice","the job and deposit invoice it made"],["summary","all of it as plain text, for one field"]],vs=()=>{const[s,r]=m.useState(null),[t,i]=m.useState(""),[l,o]=m.useState(null),[d,n]=m.useState(!1),a=()=>J("my_webhook").then(h=>{var v;r(h),i(((v=h.webhook)==null?void 0:v.url)??"")}).catch(h=>b({title:"Couldn't load integrations",description:h.message,variant:"destructive"}));m.useEffect(()=>{a()},[]);const g=async(h,v,O)=>{var E;o(h);try{const p=await v();p&&(r(p),i(((E=p.webhook)==null?void 0:E.url)??"")),O&&b({title:O})}catch(p){b({title:"That didn't work",description:p instanceof Error?p.message:"Try again.",variant:"destructive"})}finally{o(null)}},u=()=>g("save",()=>{var h;return J("save_webhook",{p_url:t.trim(),p_enabled:((h=s==null?void 0:s.webhook)==null?void 0:h.enabled)??!0})},"Webhook saved"),_=h=>(s==null?void 0:s.webhook)&&g("toggle",()=>J("save_webhook",{p_url:s.webhook.url,p_enabled:h}),h?"Webhook on":"Webhook paused"),j=()=>{confirm("Make a new signing secret? Anything checking the old one will start rejecting deliveries until you update it.")&&g("rotate",()=>J("rotate_webhook_secret"),"New secret made")},D=()=>{confirm("Remove the webhook? Approved quotes will stop being sent.")&&g("remove",()=>J("remove_webhook"),"Webhook removed")},N=(h,v)=>g(v??h,async()=>{const{data:O,error:E}=await P.functions.invoke("estimate-webhook",{body:{action:h,estimate_id:v}});if(E&&!O)throw new Error("The webhook service didn't answer. Try again.");const p=O;return p.ok?b({title:h==="test"?"Test delivered":"Sent again",description:p.used==="sample"?"Sent sample data; approve a real quote to see your own.":void 0}):b({title:"Delivery failed",description:p.error||"The address didn't accept it.",variant:"destructive"}),J("my_webhook")}),C=async()=>{if(s!=null&&s.webhook)try{await navigator.clipboard.writeText(s.webhook.secret),n(!0),setTimeout(()=>n(!1),1500)}catch{}};if(!s)return e.jsxs("div",{className:"flex flex-col gap-3","aria-busy":"true",children:[e.jsx("div",{className:"h-10 w-1/2 animate-pulse rounded-lg bg-ink/[0.04]"}),e.jsx("div",{className:"h-48 animate-pulse rounded-xl bg-ink/[0.04]"})]});const f=s.webhook,y=t.trim()!==((f==null?void 0:f.url)??"");return e.jsxs("div",{className:"flex flex-col gap-8",children:[e.jsx(ys,{}),e.jsxs(U,{title:"Send approved quotes to another system",description:"When a customer approves a quote, EstimateKit sends the whole thing to an address you choose. Use it with an automation tool like Make, n8n or Zapier to create the customer and job in your field-service software.",children:[e.jsx(x,{label:"Webhook address",htmlFor:"s-webhook",help:"The https:// address your automation tool or server gives you for incoming webhooks.",stack:!0,children:e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row",children:[e.jsx(R,{id:"s-webhook",type:"url",inputMode:"url",autoComplete:"off",spellCheck:!1,placeholder:"https://…",value:t,onChange:h=>i(h.target.value),className:"font-mono text-[13px] sm:flex-1"}),e.jsxs(k,{onClick:u,disabled:!t.trim()||!y||l==="save",className:"h-10 gap-2",children:[l==="save"&&e.jsx(Y,{className:"h-4 w-4 animate-spin"}),f?"Update":"Save"]})]})}),f&&e.jsxs(e.Fragment,{children:[e.jsx(x,{label:"Send approved quotes",help:f.enabled?"On. Every quote a customer approves is sent within seconds.":"Paused. Nothing is sent until you turn it back on.",children:e.jsx(H,{checked:f.enabled,disabled:l==="toggle",onCheckedChange:_,"aria-label":"Send approved quotes"})}),e.jsx(x,{label:"Signing secret",help:"Optional. Each delivery carries an X-EstimateKit-Signature header made with this secret, so your server can check it came from us. Automation tools don't need it.",stack:!0,children:e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("code",{className:"min-w-0 flex-1 truncate rounded-md bg-ink/[0.05] px-2.5 py-2 font-mono text-[12.5px] text-foreground-secondary",children:f.secret}),e.jsxs(k,{variant:"outline",onClick:C,className:"h-9 gap-1.5",children:[d?e.jsx($t,{className:"h-4 w-4"}):e.jsx(qt,{className:"h-4 w-4"}),d?"Copied":"Copy"]}),e.jsxs(k,{variant:"ghost",onClick:j,disabled:l==="rotate",className:"h-9 gap-1.5",children:[e.jsx(ft,{className:"h-4 w-4"}),"New secret"]}
34)]})}),e.jsx(x,{label:"Send a test",help:"Sends your most recent approved quote, marked as a test. With none yet, it sends sample data so you can map the fields.",children:e.jsxs(k,{variant:"outline",onClick:()=>void N("test"),disabled:l==="test",className:"h-10 gap-2",children:[l==="test"&&e.jsx(Y,{className:"h-4 w-4 animate-spin"}),"Send test"]})})]})]}),f&&e.jsx(U,{title:"Recent deliveries",description:"Failed deliveries are retried twice. You can send any approved quote again from here.",action:e.jsx(k,{variant:"ghost",onClick:()=>void D(),disabled:l==="remove",className:"h-8 text-[12.5px] text-foreground-tertiary hover:text-bad",children:"Remove webhook"}),children:s.deliveries.length===0?e.jsx("p",{className:"px-4 py-3 text-[13px] text-foreground-tertiary md:px-5",children:"Nothing sent yet. Send a test, or approve a quote."}):e.jsx("ul",{className:"divide-y divide-ink/[0.06]",children:s.deliveries.map(h=>e.jsxs("li",{className:"flex items-center gap-3 px-4 py-2.5 md:px-5",children:[e.jsx("span",{className:q("h-2 w-2 shrink-0 rounded-full",h.ok?"bg-[#12B76A]":"bg-[#F04438]"),"aria-hidden":!0}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("p",{className:"truncate text-[13px] text-foreground",children:[h.test?"Test":"Approved quote",h.estimate_number?` · ${h.estimate_number}`:"",h.client_name?` · ${h.client_name}`:""]}),e.jsxs("p",{className:"truncate text-[12px] text-foreground-tertiary",children:[je(we(h.created_at),"MMM d, h:mm a")," · ",h.ok?`Delivered (${h.status_code})`:h.error||"Failed",h.attempts>1?` · ${h.attempts} tries`:""]})]}),h.estimate_id&&!h.test&&e.jsx(k,{variant:"ghost",onClick:()=>void N("resend",h.estimate_id),disabled:l===h.estimate_id,className:"h-8 shrink-0 px-2.5 text-[12.5px]",children:l===h.estimate_id?e.jsx(Y,{className:"h-3.5 w-3.5 animate-spin"}):"Send again"})]},h.id))})}),e.jsx(U,{title:"What gets sent",description:"One JSON message per approved quote. Your automation tool shows each field so you can map it.",action:e.jsx("a",{href:"/developers/webhooks",target:"_blank",rel:"noreferrer",className:"text-[12.5px] text-cta-orange hover:underline",children:"Full reference"}),children:e.jsx("ul",{className:"divide-y divide-ink/[0.06]",children:bs.map(([h,v])=>e.jsxs("li",{className:"flex flex-col gap-0.5 px-4 py-2.5 sm:flex-row sm:items-baseline sm:gap-4 md:px-5",children:[e.jsx("code",{className:"w-44 shrink-0 font-mono text-[12.5px] text-foreground",children:h}),e.jsx("span",{className:"text-[13px] text-foreground-secondary",children:v})]},h))})})]})},Ae=[{id:"company",label:"Business profile",icon:Kt,group:"Company",roles:["owner","admin"]},{id:"quotes",label:"Quotes and invoices",icon:Lt,group:"Company",roles:["owner","admin"]},{id:"payments",label:"Payments",icon:at,group:"Company",roles:["owner","admin"]},{id:"automations",label:"Automations",icon:It,group:"Company",roles:["owner","admin"]},{id:"integrations",label:"Integrations",icon:St,group:"Company",roles:["owner","admin"]},{id:"team",label:"Team",icon:Wt,href:"/settings/team",group:"Company",roles:["owner","admin"]},{id:"plan",label:"Plan and billing",icon:Yt,group:"Company",roles:["owner"]},{id:"account",label:"My account",icon:Ht,group:"You"}],ws=["company","quotes","payments","automations"],js={estimate:"company",estimates:"quotes",payment:"payments"},ks=()=>typeof window<"u"&&window.matchMedia("(max-width: 1023px)").matches,ia=()=>{const[s,r]=Ie(),t=Ne(),i=pt(),{data:l}=gt(),o=(l==null?void 0:l.role)??null,d=Le(),n=Ae.filter(F=>(!F.roles||(o?F.roles.includes(o):!1))&&!(Z()&&(F.id==="plan"||F.id==="integrations"))),a=F=>n.some(S=>S.id===F),g=o==="owner"||o==="admin",u=s.get("tab"),_=js[u||""]||u||"",[j,D]=m.useState(()=>ks()&&!u),N=_&&(a(_)||!o)?_:g?"company":"account",[C,f]=m.useState(null),[y,h]=m.useState(null),[v,O]=m.useState(null),[E,p]=m.useState(null),[T,L]=m.useState(!1);m.useEffect(()=>{if(!g)return;let F=!0;return Ct().then(S=>{F&&(f(S),h(S.profile),O(S.prefs))}).catch(S=>{F&&p(S instanceof Error?S.message:"Couldn't load settings.")}),()=>{F=!1}},[g]);const M=m.useMemo(()=>C&&y&&v?{profile:Fe(C.profile,y),prefs:Fe(C.prefs,v)}:null,[C,y,v]),A=!!M&&(Object.keys(M.profile).length>0||Object.keys(M.prefs).length>0);m.useEffect(()=>{const F=S=>{A&&(S.preventDefault(),S.returnValue="")};return window.addEventListener("beforeunload",F),()=>window.removeEventListener("beforeunload",F)},[A]);const I=m.useCallback((F,S)=>h(W=>W&&{...W,[F]:S}),[]),w=m.useCallback((F,S)=>O(W=>W&&{...W,[F]:S}),[]),Q=m.useCallback(F=>{h(S=>S&&{...S,logo_url:F}),f(S=>S&&{...S,profile:{...S.profile,logo_url:F}}),i.invalidateQueries({queryKey:[...de.company]}),Ee()},[i]),z=async()=>
34{if(!(!M||!C||!y||!v)){if("company_name"in M.profile&&!y.company_name.trim()){b({title:"Add your company name",description:"It goes at the top of every quote.",variant:"destructive"});return}L(!0);try{await Et(M.profile,M.prefs),f({...C,profile:y,prefs:v}),Ee(),await Promise.all([i.invalidateQueries({queryKey:[...de.company]}),i.invalidateQueries({queryKey:[...de.preferences]}),i.invalidateQueries({queryKey:["user"]}),i.invalidateQueries({queryKey:["home"]})]),b({title:"Settings saved",description:"New quotes and invoices use them. Ones already sent don't change."})}catch(F){b({title:"Couldn't save",description:F instanceof Error?F.message:"Try again.",variant:"destructive"})}finally{L(!1)}}},c=F=>{var W;const S=Ae.find(K=>K.id===F);if(S!=null&&S.href){t(S.href);return}D(!1),r({tab:F}),window.scrollTo({top:0}),(W=document.getElementById("root"))==null||W.scrollTo({top:0})},B=d.materials==null?"Tax not set":`${d.materials}% tax`,G=F=>{if(!y||!v)return"";switch(F){case"company":return ae.company(y);case"quotes":return ae.quotes(v,B);case"payments":return ae.payments(v);case"automations":return ae.automations(v);case"integrations":return"QuickBooks, and approved quotes to Zapier or your own system";case"team":return"Invite techs, roles, what they see";case"plan":return"Subscription and invoices";case"account":return"Name, password, texts, your data"}},$=y&&v?{profile:y,prefs:v,setProfile:I,setPref:w,onLogoChanged:Q,isOwner:o==="owner"}:null,Ce=ws.includes(N),Se=({phone:F})=>e.jsx("nav",{"aria-label":"Settings sections",className:"flex flex-col gap-5",children:["Company","You"].map(S=>{const W=n.filter(K=>K.group===S);return W.length?e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx("p",{className:"px-1 text-[11px] font-medium uppercase tracking-[0.06em] text-foreground-tertiary",children:S}),e.jsx("div",{className:"flex flex-col divide-y divide-ink/[0.06] overflow-hidden rounded-xl border border-ink/[0.06] bg-card",children:W.map(K=>{const se=!F&&N===K.id,it=K.icon;return e.jsxs("button",{type:"button",onClick:()=>c(K.id),"aria-current":se?"page":void 0,className:q("flex w-full items-center gap-3 px-3.5 py-2.5 text-left transition-colors",se?"bg-ink/[0.04]":"hover:bg-ink/[0.04]"),children:[e.jsx(it,{className:q("h-4 w-4 shrink-0",se?"text-cta-orange":"text-foreground-tertiary"),strokeWidth:1.8}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:q("block text-[13.5px] font-medium",se?"text-foreground":"text-ink/80"),children:K.label}),F&&e.jsx("span",{className:"block truncate text-[12px] text-foreground-tertiary",children:G(K.id)})]}),(F||K.href)&&e.jsx(Ut,{className:"h-4 w-4 shrink-0 text-foreground-tertiary",strokeWidth:1.8})]},K.id)})})]},S):null})});return e.jsxs("div",{className:"min-h-screen bg-background",children:[e.jsx(yt,{}),e.jsxs(bt,{width:"full",children:[e.jsx(wt,{title:"Settings",description:g?"Your company's defaults and your own account. Most shops only need the first two.":"Your account."}),j?e.jsx("div",{className:"max-w-xl",children:e.jsx(Se,{phone:!0})}):e.jsxs("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-[14rem_minmax(0,1fr)] lg:gap-10",children:[e.jsx("div",{className:"hidden lg:block lg:sticky lg:top-24 lg:self-start",children:e.jsx(Se,{phone:!1})}),e.jsxs("div",{className:"flex min-w-0 max-w-3xl flex-col gap-4 pb-24",children:[e.jsxs("button",{type:"button",onClick:()=>{D(!0),r({})},className:"flex w-max items-center gap-1 text-[13px] text-foreground-secondary hover:text-foreground lg:hidden",children:[e.jsx(vt,{className:"h-4 w-4"})," All settings"]}),Ce&&E&&e.jsx("p",{className:"rounded-xl border border-ink/[0.06] bg-card px-4 py-3 text-[13px] text-foreground-secondary",children:E}),Ce&&!E&&!$&&e.jsxs("div",{className:"flex flex-col gap-3","aria-busy":"true",children:[e.jsx("div",{className:"h-10 w-1/2 animate-pulse rounded-lg bg-ink/[0.04]"}),e.jsx("div",{className:"h-64 animate-pulse rounded-xl bg-ink/[0.04]"})]}),$&&N==="company"&&e.jsx(as,{...$}),$&&N==="quotes"&&e.jsx(os,{...$}),$&&N==="payments"&&e.jsx(is,{...$}),$&&N==="automations"&&e.jsx(cs,{...$}),N==="integrations"&&a("integrations")&&e.jsx(vs,{}),N==="plan"&&(a("plan")?e.jsx(hs,{}):e.jsx("p",{className:"rounded-xl border border-ink/[0.06] bg-card px-4 py-3 text-[13px] text-foreground-secondary",children:"Billing is managed by the account owner."})),N==="account"&&e.jsx(xs,{})]})]})]}),A&&e.jsx("div",{className:"fixed inset-x-0 z-40 flex justify-center px-4 md:bottom-6 md:left-[var(--ek-sidebar-w)]",style:{bottom:"calc(var(--ek-tabbar-space) + 10px)"},children:e.jsxs("div",{className:"flex w-full max-w-md items-center justify-between gap-3 rounded-xl border border-ink/[0.08] bg-[#171717]/95 p-2 pl-4 shadow-[0_12px_32px_rgba(0,0,0,0.45)] backdrop-blur",children:[e.jsx("span",{className:"text-sm text-foreground-secondary",children:"Unsaved changes"}),e.jsxs("div",{className:"flex gap-1.5",children:[e.jsx(k,{variant:"ghost",className:"h-10",disabled:T,onClick:()=>{C&&(h(C.profile),O(C.prefs))},children:"Discard"}),e.jsxs(k,{variant:"orange",onClick:()=>void z(),disabled:T,className:"h-10",children:[e.jsx(nt,{className:"mr-2 h-4 w-4"}),T?"Saving…":"Save changes"]})]})]})})]})};export{ia 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.