1import{e as I,d as S,r as d,j as e,L as u}from"./vendor-react-uOgp_wa2.js";import{g as E}from"./publicApiOrigin-rEWib8eQ.js";import{J as R,a as T}from"./JobBillsCard-DFWSy0_e.js";import{J as q,i as v,f as J,a as O}from"./jobLinks-XOrFH6Y6.js";import"./index-yU7OBVab.js";import"./vendor-ui-BxQmMfpj.js";const b=E();function g({children:t}){return e.jsxs("div",{className:"min-h-screen bg-slate-50",children:[e.jsx("header",{className:"border-b border-slate-200 bg-white px-4 py-3",children:e.jsxs(u,{to:"/",className:"inline-flex items-baseline gap-0 font-bold tracking-tight text-lg",children:[e.jsx("span",{className:"text-[var(--primary,#1e4fa3)]",children:"TECH"}),e.jsx("span",{className:"text-red-600",children:"XPERT"})]})}),e.jsx("main",{className:"max-w-xl mx-auto px-4 py-6 space-y-4",children:t})]})}function m({tone:t="info",children:n}){const s={success:"bg-emerald-50 border-emerald-100 text-emerald-900",error:"bg-red-50 border-red-100 text-red-900",info:"bg-blue-50 border-blue-100 text-blue-900"}[t];return e.jsx("div",{className:`rounded-xl border px-4 py-3 text-sm ${s}`,children:n})}function A({token:t,expired:n,message:s}){const[a,x]=d.useState("idle"),h=async()=>{x("sending");try{const p=await fetch(`${b}/api/public/job/${encodeURIComponent(t)}/refresh`,{method:"POST"});x(p.ok?"sent":"failed")}catch{x("failed")}};return e.jsx(g,{children:e.jsxs("div",{className:"rounded-2xl border border-gray-100 bg-white p-6 text-center",children:[e.jsx("h1",{className:"text-lg font-bold text-gray-900 mb-2",children:n?"This link has expired":"This link does not work"}),e.jsx("p",{className:"text-sm text-gray-600 mb-5",children:s}),n&&a!=="sent"&&e.jsx("button",{type:"button",onClick:h,disabled:a==="sending",className:"w-full rounded-full bg-green-600 px-5 py-3 text-sm font-semibold text-white hover:bg-green-700 disabled:opacity-60",children:a==="sending"?"Sendingâ¦":"Email me a fresh link"}),a==="sent"&&e.jsx(m,{tone:"success",children:"If we have an email address for this job, a fresh link is on its way. Check your inbox."}),a==="failed"&&e.jsx("p",{className:"mt-3 text-sm text-red-600",children:"Could not send right now. Please try again in a minute."}),e.jsxs("p",{className:"mt-5 text-xs text-gray-500",children:["You can also ",e.jsx(u,{to:"/profile/leads",className:"font-semibold text-green-700",children:"log in"})," to see all your jobs, or"," ",e.jsx(u,{to:"/contact",className:"font-semibold text-green-700",children:"contact us"}),"."]})]})})}function L({action:t,onOpenQuote:n,quoteBusy:s}){return t.type==="quote"?e.jsxs("div",{className:"rounded-2xl border border-green-200 bg-white p-4",children:[e.jsx("p",{className:"text-[11px] font-bold uppercase tracking-wide text-green-700 mb-1",children:"Needs your approval"}),e.jsx("p",{className:"text-sm font-semibold text-gray-900",children:t.label}),t.amount>0&&e.jsxs("p",{className:"text-xs text-gray-500 mt-0.5",children:["Quote total ",v(t.amount)]}),e.jsx("button",{type:"button",onClick:n,disabled:s,className:"mt-3 w-full rounded-full bg-green-600 px-5 py-3 text-sm font-semibold text-white hover:bg-green-700 disabled:opacity-60",children:s?"Openingâ¦":"Review quote"})]}):t.type==="pay"?e.jsxs("div",{className:`rounded-2xl border bg-white p-4 ${t.overdue?"border-red-200":"border-amber-200"}`,children:[e.jsx("p",{className:`text-[11px] font-bold uppercase tracking-wide mb-1 ${t.overdue?"text-red-700":"text-amber-800"}`,children:t.overdue?"Payment overdue":"Payment due"}),e.jsx("p",{className:"text-sm font-semibold text-gray-900",children:t.label}),t.due_date&&e.jsxs("p",{className:"text-xs text-gray-500 mt-0.5",children:["Due ",J(t.due_date)]}),e.jsxs("a",{href:O(t.pay_url),className:"mt-3 block w-full rounded-full bg-green-600 px-5 py-3 text-center text-sm font-semibold text-white hover:bg-green-700",children:["Pay ",v(t.amount)]})]}):e.jsxs("div",{className:"rounded-2xl border border-violet-200 bg-white p-4",children:[e.jsx("p",{className:"text-[11px] font-bold uppercase tracking-wide text-violet-700 mb-1",children:"Ready for your sign-off"}),e.jsxs("p",{className:"text-sm text-gray-800",children:[t.label,"."]}),e.jsx("p",{className:"text-xs text-gray-500 mt-1",children:"The completion code is in the email we sent when the work was handed over."})]})}function K(){const{token:t}=I(),[n]=S(),[s,a]=d.useState({status:"loading"}
1),[x,h]=d.useState(!1),[p,y]=d.useState(""),j=n.get("paid"),c=n.get("bill"),C=n.get("report");d.useEffect(()=>{let r=!0;return fetch(`${b}/api/public/job/${encodeURIComponent(t)}`).then(async o=>{const l=await o.json().catch(()=>({}));r&&(o.ok&&l.success?a({status:"ready",data:l}):o.status===410?a({status:"expired",message:l.message}):o.status===404?a({status:"invalid",message:l.message}):a({status:"error",message:l.message}))}).catch(()=>r&&a({status:"error"})),()=>{r=!1}},[t]),d.useEffect(()=>{if(s.status==="ready"){try{sessionStorage.setItem(q,t)}catch{}c&&document.getElementById(`bill-${c}`)?.scrollIntoView({behavior:"smooth",block:"center"})}},[s.status,t,c]);const P=d.useCallback(async r=>{const o=await fetch(`${b}/api/public/job/${encodeURIComponent(t)}/reports/${encodeURIComponent(r)}`),l=await o.json();if(!o.ok||!l.success)throw new Error(l.message||"Could not load this report");return l.report},[t]),_=async()=>{h(!0),y("");try{const r=await fetch(`${b}/api/public/job/${encodeURIComponent(t)}/quote-session`,{method:"POST",credentials:"include"}),o=await r.json().catch(()=>({}));if(!r.ok||!o.success)throw new Error(o.message);window.location.assign(o.redirect||"/quote-review")}catch(r){y(r.message||"Could not open the quote. Please try again."),h(!1)}};if(s.status==="loading")return e.jsx(g,{children:e.jsx("p",{className:"text-sm text-gray-500 text-center py-16",children:"Loading your jobâ¦"})});if(s.status==="expired"||s.status==="invalid")return e.jsx(A,{token:t,expired:s.status==="expired",message:s.message});if(s.status==="error")return e.jsx(g,{children:e.jsxs(m,{tone:"error",children:[s.message||"We could not load your job right now."," ",e.jsx("button",{type:"button",onClick:()=>window.location.reload(),className:"font-semibold underline",children:"Try again"})]})});const{job:i,actions:w,bills:f,progress:N}=s.data,$=i.category==="lead"?"/profile/leads":"/profile/bookings",k=c?f.find(r=>String(r.invoice_id)===String(c)):null;return e.jsxs(g,{children:[j==="success"&&e.jsxs(m,{tone:"success",children:["Payment received",k?` for ${k.invoice_no}`:"",". Thank you â a receipt is on its way to your email."]}),j==="failure"&&e.jsx(m,{tone:"error",children:"The payment did not go through and no money was taken. You can try again below."}),e.jsxs("div",{className:"rounded-2xl border border-gray-100 bg-white p-4",children:[e.jsxs("p",{className:"text-sm text-gray-500",children:["Hi ",i.customer_first_name||"there",","]}),e.jsxs("div",{className:"mt-1 flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("h1",{className:"text-lg font-bold text-gray-900 truncate",children:i.service_label||"Your job"}),e.jsxs("p",{className:"text-xs text-gray-400 mt-0.5",children:["Job ",i.ref]})]}),e.jsx("span",{className:"shrink-0 text-[11px] font-bold px-2.5 py-1 rounded-full bg-gray-100 text-gray-700",children:i.status_label})]})]}),w.map(r=>e.jsx(L,{action:r,onOpenQuote:_,quoteBusy:x},`${r.type}-${r.invoice_id||r.quote_id||""}`)),p&&e.jsx(m,{tone:"error",children:p}),e.jsx(R,{category:i.category,ticketId:i.ticket_id,progress:N,loadReport:P,initialReportDate:C}),e.jsx(T,{category:i.category,ticketId:i.ticket_id,bills:f,highlightId:c}),!w.length&&!N&&!f.length&&e.jsx("p",{className:"text-sm text-gray-500 text-center py-4",children:"Nothing needs your attention right now. We will email you at each step."}),e.jsxs("p",{className:"text-center text-xs text-gray-500 pt-2",children:["Anyone with this link can see this job, so please do not forward the email.",e.jsx("br",{}),e.jsx(u,{to:$,className:"font-semibold text-green-700",children:"Log in"})," to see all your jobs ·"," ",e.jsx(u,{to:"/contact",className:"font-semibold text-green-700",children:"Contact us"})]})]})}export{K 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.