1import{ab as F,k as J,aa as M,r as l,K as n,j as e,Q as N,g as m,B as x}from"./index-CbvCveKN.js";import{D as $,P as E,g as z,C as H}from"./PageContainer-Bx7SVsdy.js";import{P as K}from"./PageHeader-ohyr15TW.js";import{S as P}from"./switch-DMLCXOMI.js";import{A as q,a as Q,b as W,c as Y,d as G,e as X,f as Z,g as ee}from"./alert-dialog-BsECSXvh.js";import{I as se,f as te}from"./pipeline-57THQ7iX.js";import{i as ae,b as ie,v as ne,V as re,j as le,u as ce,e as oe,f as de,g as me,h as xe}from"./maintenance-D4U-TS6n.js";import{m as pe,M as he}from"./MonthPicker-CECADGLs.js";import{S as ue}from"./ScheduleJobSheet-EHs7Pgd_.js";import{R as fe}from"./users-BkZzL3s4.js";import{E as ge}from"./external-link-DtZsaCxu.js";import"./check-Bjw6cCk6.js";import"./index-Jf4OHjGl.js";import"./chevron-right-f4vsMuAf.js";import"./triangle-alert-BJBV5PBt.js";import"./en-US-wdCzBwgh.js";import"./plus-kYCBPFxU.js";import"./file-text-DDhZ7a0t.js";import"./layout-dashboard-rEexJXnQ.js";import"./ek-mark-light-Y4_w-cFG.js";import"./parseISO-B0WEjCD3.js";import"./plug-BAhKXAxN.js";import"./chevron-down-yKD6BMcU.js";import"./index-DlFerWUd.js";import"./calendar-NMNG2jcx.js";import"./isSameDay-m0yeLtak.js";import"./differenceInCalendarDays-BmAYwV3_.js";import"./isAfter-BG9KlOmt.js";import"./format-BZAqQT85.js";import"./startOfMonth-D-6yZJC1.js";import"./addDays-eG_rRTHr.js";import"./subDays-Bv3fF7No.js";import"./select-C3XbO4_1.js";import"./index-CKxf6gP2.js";import"./jobs-BslETRXA.js";import"./jobShared-Dn-iCgbr.js";import"./isToday-CHwM1qlQ.js";import"./calendar-DxoECvrb.js";const y=i=>`$${i.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}`,je=i=>new Date(`${i}T12:00:00`).toLocaleDateString("en-US",{month:"long",year:"numeric"}),p=i=>new Date(`${i}T12:00:00`).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}),v="rounded-xl border border-ink/[0.06] bg-card",w="rounded-[5px] px-1.5 py-px text-[11.5px] font-medium whitespace-nowrap",as=()=>{var A,D,I;const{id:i}=F(),c=J(),{requireWrite:h}=M(),[t,L]=l.useState(null),[u,o]=l.useState(null),[d,k]=l.useState(null),j=l.useRef(!1),[V,C]=l.useState(!1),r=l.useCallback(async()=>{if(i)try{L(await ae(i))}catch(s){n({title:"Couldn't load the plan",description:s.message,variant:"destructive"}),c("/maintenance")}},[i,c]);l.useEffect(()=>{r()},[r]);const b=async(s,a)=>{if(!(!t||!h()))try{await ce(t.id,s),await r(),a&&n({title:a})}catch(g){n({title:"Couldn't save",description:g.message,variant:"destructive"})}},R=async s=>{if(!(!t||!h())){o(s.id);try{const a=await oe(t,s);k({jobId:a,preset:s.due_date>new Date().toISOString().slice(0,10)?s.due_date:null}),await r()}catch(a){n({title:"Couldn't create the job",description:a.message,variant:"destructive"})}finally{o(null)}}},B=async s=>{if(h()){o(s.id);try{await de(s.id,!s.skipped_at),await r()}catch(a){n({title:"Couldn't update the visit",description:a.message,variant:"destructive"})}finally{o(null)}}},O=async()=>{if(!(!t||!h())){o("bill");try{const s=await me(t);n({title:"Draft invoice created",description:"Review it and send it to the customer."}),c(`/invoices/${s}`)}catch(s){n({title:"Couldn't create the invoice",description:s.message,variant:"destructive"}),o(null)}}};if(!t)return e.jsxs("div",{className:"min-h-screen bg-background",children:[e.jsx($,{}),e.jsx(E,{width:"default",children:e.jsx("div",{className:"flex h-40 items-center justify-center",children:e.jsx(N,{className:"h-5 w-5 animate-spin text-foreground-tertiary"})})})]});const U=new Date().toISOString().slice(0,10),f=t.status==="active",_=ie(t),S=f?{t:"Active",c:"bg-emerald-500/15 text-ok"}:t.status==="cancelled"?{t:"Cancelled",c:"bg-ink/[0.07] text-foreground-tertiary"}:{t:"Expired",c:"bg-ink/[0.07] text-foreground-tertiary"};return e.jsxs("div",{className:"min-h-screen bg-background",children:[e.jsx($,{}),e.jsxs(E,{width:"default",children:[e.jsx(K,{backTo:"/maintenance",backLabel:"Maintenance",area:"maintenance",icon:z,crumb:((A=t.account)==null?void 0:A.client_name)||"Plan",title:((D=t.account)==null?void 0:D.client_name)||"Customer",badge:e.jsx("span",{className:m(w,S.c),children:S.t}),description:`${t.name} · ${y(t.price)} ${t.billing==="monthly"?"a month":"a year"} · ${pe(t.visit_months)}`,actions:e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(x,{variant:"outline",onClick:()=>c(`/customers/${t.account_id}`),children:"Customer"}),f&&e.jsxs(x,{variant:_?"default":"outline",onClick:()=>void O(),disabled:u==="bill",children:[u==="bill"?e.jsx(N,{className:"h-4 w-4 animate-spin"}):e.jsx(fe,{className:"h-4 w-4"})," Create invoice"]})]})}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-[minmax(0,1fr)_300px]",children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-6",children:[e.jsxs("section",{className:"flex flex-col gap-3",children:[e.jsx("h2",{className:"text-[15px] font-semibold",children:"Visits this term"}),e.jsxs("div",{className:"flex flex-col gap-px overflow-hidden rounded-xl border border-ink/[0.06] bg-ink/[0.05]",children:[(t.visits||[]).map(s=>{var g,T;const a=ne(s,U);return e.jsxs("div",{className:"flex flex-wrap items-center gap-3 bg-card px-4 py-3 sm:flex-nowrap",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"text-[14px] font-medium",children:s.label}),e.jsxs("div",{className:"text-[12.5px] text-foreground-tertiary",children:["Due ",je(s.due_date),(g=s.job)!=null&&g.scheduled_date?` · booked ${p(s.job.scheduled_date)}`:"",(T=s.job)!=null&&T.job_number?` · ${s.job.job_number}`:""]})]}),e.jsx("span",{className:m(w,xe[a]),children:re[a]}),e.jsx("div",{className:"flex gap-1.5",children:s.job?e.jsxs(x,{variant:"outline",size:"sm",onClick:()=>c(`/jobs/${s.job.id}`),children:[e.jsx(ge,{className:"h-3.5 w-3.5"})," Open job"]}):f?e.jsxs(e.Fragment,{children:[e.jsx(x,{variant:"ghost",size:"sm",onClick:()=>void B(s),disabled:u===s.id,children:s.skipped_at?"Undo skip":"Skip"}),!s.skipped_at&&e.jsxs(x,{variant:"outline",size:"sm",onClick:()=>void R(s),disabled:u===s.id,children:[u===s.id?e.jsx(N,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(H,{className:"h-3.5 w-3.5"})," Book visit"]})]}):null})]},s.id)}),!(t.visits||[]).length&&e.jsx("div",{className:"bg-card px-4 py-6 text-center text-[13px] text-foreground-tertiary",children:"No visits in this term."})]})]}),e.jsxs("section",{className:"flex flex-col gap-3",children:[e.jsxs("div",{className:"flex items-baseline justify-between",children:[e.jsx("h2",{className:"text-[15px] font-semibold",children:"Invoices"}),_&&f&&e.jsxs("span",{className:"text-[12.5px] text-warn",children:["Nothing billed for this ",t.billing==="monthly"?"month":"term"," yet"]})]}),e.jsxs("div",{className:"flex flex-col gap-px overflow-hidden rounded-xl border border-ink/[0.06] bg-ink/[0.05]",children:[(t.invoices||[]).map(s=>e.jsxs("button",{type:"button",onClick:()=>c(`/invoices/${s.id}`),className:"flex items-center gap-3 bg-card px-4 py-3 text-left transition-colors hover:bg-ink/[0.04]",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-mono text-[13px]",children:s.invoice_number||"Draft"}),e.jsxs("div",{className:"text-[12.5px] text-foreground-tertiary",children:["Created ",p(s.created_at.slice(0,10))]})]}),e.jsx("span",{className:"font-mono text-[13.5px]",children:y(Number(s.total)||0)}),e.jsx("span",{className:m(w,se[s.status]||"bg-ink/10"),children:te[s.status]||s.status})]},s.id)),!(t.invoices||[]).length&&e.jsx("div",{className:"bg-card px-4 py-6 text-center text-[13px] text-foreground-tertiary",children:"No invoices yet. Payments are collected the same way as any invoice."})]})]})]}),e.jsxs("aside",{className:"flex min-w-0 flex-col gap-4",children:[e.jsxs("div",{className:m(v,"flex flex-col gap-3 p-4 text-[13.5px]"),children:[e.jsxs("div",{className:"flex justify-between gap-3",children:[e.jsx("span",{className:"text-foreground-secondary",children:"Term"}),e.jsxs("span",{className:"text-right",children:[p(t.start_date)," â ",p(t.end_date)]})]}),e.jsxs("div",{className:"flex justify-between gap-3",children:[e.jsx("span",{className:"text-foreground-secondary",children:"Price"}),e.jsxs("span",{className:"font-mono",children:[y(t.price),"/",t.billing==="monthly"?"mo":"yr"]})]}),t.discount_percent>0&&e.jsxs("div",{className:"flex justify-between gap-3",children:[e.jsx("span",{className:"text-foreground-secondary",children:"Repair discount"}),e.jsxs("span",{children:[t.discount_percent,"%"]})]}),t.perks&&e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-foreground-secondary",children:"Perks"}),e.jsx("span",{children:t.perks})]}),t.description&&e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("span",{className:"text-foreground-secondary",children:"Included"}),e.jsx("span",{className:"text-foreground-secondary",children:t.description})]})]}),f&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:m(v,"flex flex-col divide-y divide-ink/[0.06]"),children:[e.jsxs("label",{className:"flex items-center justify-between gap-3 px-4 py-3",children:[e.jsxs("span",{className:"flex flex-col",children:[e.jsx("span",{className:"text-[13.5px] font-medium",children:"Renew automatically"}),e.jsx("span",{className:"text-[12px] text-foreground-tertiary",children:t.auto_renew?`Extends a year on ${p(t.end_date)}`:`Ends ${p(t.end_date)}`})]}),e.jsx(P,{checked:t.auto_renew,onCheckedChange:s=>void b({auto_renew:s})})]}),e.jsxs("label",{className:"flex items-center justify-between gap-3 px-4 py-3",children:[e.jsxs("span",{className:"flex flex-col",children:[e.jsx("span",{className:"text-[13.5px] font-medium",children:"Visit reminder emails"}),e.jsx("span",{className:"text-[12px] text-foreground-tertiary",children:(I=t.account)!=null&&I.email?`To ${t.account.email}`:"Customer has no email on file"})]}),e.jsx(P,{checked:t.reminders_enabled,onCheckedChange:s=>void b({reminders_enabled:s})})]})]}),e.jsxs("div",{className:m(v,"flex flex-col gap-2 p-4"),children:[e.jsx("span",{className:"text-[13px] font-medium",children:"Visit months"}),e.jsx(he,{value:t.visit_months,onChange:s=>void b({visit_months:s},"Visit months updated")}),e.jsx("span",{className:"text-[12px] text-foreground-tertiary",children:"Upcoming visits without a job move to the new months."})]}),e.jsx(x,{variant:"ghost",className:"self-start text-foreground-tertiary hover:text-bad",onClick:()=>C(!0),children:"Cancel plan"})]})]})]})]}),e.jsx(q,{open:V,onOpenChange:C,children:e.jsxs(Q,{children:[e.jsxs(W,{children:[e.jsx(Y,{children:"Cancel this maintenance plan?"}),e.jsx(G,{children:"It stops renewing and no more reminder emails go out. Jobs already created stay as they are."})]}),e.jsxs(X,{children:[e.jsx(Z,{children:"Keep it"}),e.jsx(ee,{className:"bg-red-500/15 text-bad hover:bg-red-500/25",onClick:()=>{h()&&le(t.id).then(r).then(()=>n({title:"Plan cancelled"}))},children:"Cancel plan"})]})]})}),e.jsx(ue,{job:d?{id:d.jobId,scheduled_date:null,status:"unscheduled"}:null,presetDate:d==null?void 0:d.preset,open:!!d,onOpenChange:s=>{s||(setTimeout(()=>{j.current||n({title:"Job made",description:"It's waiting under Needs scheduling on Jobs."}),j.current=!1},0),k(null))},onSaved:()=>{j.current=!0,r()}})]})};export{as 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.