PageSourceSearch

https://getvsble.com/assets/EstimatesListPage-UrqOV3ur.js

js getvsble.com collected 2026-10-09 04:55:37 UTC 6,796 bytes, 6 lines download raw bytes

1import{d as D,u as C,b as T,r as h,s as m,j as e,B as f,aY as k,aZ as S,a_ as N,a$ as i,b0 as I,b1 as n,af as E,a3 as P,a4 as L,a6 as M,aK as c,cK as q}from"./index-ByYYWl6V.js";import{B as b}from"./badge-DuSeH5ON.js";import{p as A}from"./parse-user-agent-WQDVydgf.js";import{D as B,a as $,b as z,c as g}from"./dropdown-menu-BZRKspBv.js";import{a as F}from"./assignNumber-TYQll7FO.js";import{P as H}from"./plus-CwyWY8pM.js";import{I as R}from"./info-CA6lfwP8.js";import{E as K}from"./ellipsis-CAg5Wdfa.js";import{E as O}from"./external-link-CECnRthk.js";import{T as Q}from"./trash-2-250o4KTP.js";import"./index-CnBNeFET.js";import"./chevron-right-X_hlXzqd.js";import"./circle-DcpkfI2n.js";/**
2 * @license lucide-react v0.462.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const U=D("FilePenLine",[["path",{d:"m18 5-2.414-2.414A2 2 0 0 0 14.172 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2",key:"142zxg"}],["path",{d:"M21.378 12.626a1 1 0 0 0-3.004-3.004l-4.01 4.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z",key:"2t3380"}],["path",{d:"M8 18h1",key:"13wk12"}]]),V={draft:"bg-muted text-muted-foreground",sent:"bg-blue-500/15 text-blue-400",accepted:"bg-emerald-500/15 text-emerald-400",declined:"bg-red-500/15 text-red-400",expired:"bg-amber-500/15 text-amber-400",converted:"bg-violet-500/15 text-violet-400"};function ce(){const{user:s}=C(),r=T(),[j,u]=h.useState([]),[w,y]=h.useState(!0);return h.useEffect(()=>{if(!s)return;let t=!1;return(async()=>{const{data:l}=await m.from("inv_estimates").select("id, number, status, issue_date, valid_until, total_gross_cents, currency, client_snapshot, accepted_at, accepted_email, accepted_ip, accepted_user_agent, declined_at, declined_email, declined_ip, declined_user_agent").eq("user_id",s.id).order("created_at",{ascending:!1});t||(u(l??[]),y(!1))})(),()=>{t=!0}},[s]),e.jsxs("div",{className:"p-6 max-w-6xl mx-auto space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold tracking-tight",children:"Estimates"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Quotes you've sent to clients. Convert accepted ones to invoices."})]}),e.jsxs(f,{onClick:()=>r("/invoicing/estimates/new"),children:[e.jsx(H,{className:"h-4 w-4 mr-2"})," New estimate"]})]}),w?e.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading…"}):j.length===0?e.jsxs("div",{className:"border rounded-lg p-12 text-center space-y-3",children:[e.jsx(U,{className:"h-10 w-10 mx-auto text-muted-foreground"}),e.jsx("div",{className:"text-sm text-muted-foreground",children:"No estimates yet."}),e.jsx(f,{size:"sm",onClick:()=>r("/invoicing/estimates/new"),children:"Create your first estimate"})]}):e.jsx("div",{className:"border rounded-lg overflow-hidden",children:e.jsxs(k,{children:[e.jsx(S,{children:e.jsxs(N,{children:[e.jsx(i,{children:"Number"}),e.jsx(i,{children:"Client"}),e.jsx(i,{children:"Issued"}),e.jsx(i,{children:"Valid until"}),e.jsx(i,{children:"Status"}),e.jsx(i,{className:"text-right",children:"Total"}),e.jsx(i,{className:"w-12"})]})}),e.jsx(I,{children:j.map(t=>{var _,v;const l=t.valid_until&&t.status==="sent"&&new Date(t.valid_until)<new Date(new Date().toDateString());return e.jsxs(N,{className:"cursor-pointer",onClick:()=>r(`/invoicing/estimates/${t.id}`),children:[e.jsx(n,{className:"font-mono text-xs",children:t.number?t.number:e.jsx(b,{variant:"secondary",className:"bg-muted text-muted-foreground",children:"Draft"})}),e.jsx(n,{children:((_=t.client_snapshot)==null?void 0:_.display_name)??((v=t.client_snapshot)==null?void 0:v.company_name)??"—"}),e.jsx(n,{className:"text-xs",children:t.issue_date??"—"}),e.jsx(n,{className:`text-xs ${l?"text-red-400":""}`,children:t.valid_until??"—"}),e.jsx(n,{children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(b,{className:V[t.status]??"",variant:"secondary",children:l?"expired":t.status}),(t.status==="accepted"||t.status==="declined")&&e.jsx(E,{delayDuration:150,children:e.jsxs(P,{children:[e.jsx(L,{asChild:!0,children:e.jsx("button",{type:"button",onClick:a=>a.stopPropagation(),className:"text-muted-foreground hover:text-foreground","aria-label":"Acceptance details",children:e.jsx(R,{className:"h-3.5 w-3.5"})})}),e.jsx(M,{className:"max-w-xs",children:e.jsxs("div",{className:"text-xs space-y-0.5",children:[e.jsxs("div",{className:"font-medium",children:[t.status==="accepted"?"Accepted":"Declined"," ",(t.status==="accepted"?t.accepted_at:t.declined_at)?"on "+new Date(t.status==="accepted"?t.accepted_at:t.declined_at).toLocaleStr
6ing():""]}),e.jsxs("div",{children:["By ",(t.status==="accepted"?t.accepted_email:t.declined_email)||"—"]}),e.jsxs("div",{className:"font-mono",children:["IP ",(t.status==="accepted"?t.accepted_ip:t.declined_ip)||"—"]}),e.jsx("div",{className:"text-muted-foreground",children:A(t.status==="accepted"?t.accepted_user_agent:t.declined_user_agent)})]})})]})})]})}),e.jsxs(n,{className:"text-right font-medium",children:[t.currency," ",((t.total_gross_cents??0)/100).toFixed(2)]}),e.jsx(n,{className:"text-right",onClick:a=>a.stopPropagation(),children:e.jsxs(B,{children:[e.jsx($,{asChild:!0,children:e.jsx(f,{variant:"ghost",size:"icon",title:"Actions",children:e.jsx(K,{className:"h-4 w-4"})})}),e.jsxs(z,{align:"end",className:"w-48",children:[e.jsxs(g,{onSelect:()=>r(`/invoicing/estimates/${t.id}`),children:[e.jsx(O,{className:"h-4 w-4 mr-2"})," Open"]}),t.status==="draft"&&e.jsxs(g,{onSelect:async a=>{if(a.preventDefault(),!s)return;const d=await F({userId:s.id,table:"inv_estimates",rowId:t.id,kind:"estimate",currentNumber:t.number});if(!d){c.error("Could not assign estimate number");return}const{error:o}=await m.from("inv_estimates").update({status:"sent",sent_at:new Date().toISOString()}).eq("id",t.id).eq("user_id",s.id);if(o){c.error(o.message||"Failed to mark as sent");return}u(x=>x.map(p=>p.id===t.id?{...p,number:d,status:"sent"}:p)),c.success(`Marked as sent — ${d}`)},children:[e.jsx(q,{className:"h-4 w-4 mr-2"})," Mark as sent"]}),t.status==="draft"&&e.jsxs(g,{className:"text-destructive focus:text-destructive",onSelect:async a=>{if(a.preventDefault(),!s||!window.confirm("Delete this draft estimate? This cannot be undone."))return;await m.from("inv_estimate_items").delete().eq("estimate_id",t.id);const{error:d}=await m.from("inv_estimates").delete().eq("id",t.id).eq("user_id",s.id).eq("status","draft");if(d){c.error(d.message||"Could not delete");return}u(o=>o.filter(x=>x.id!==t.id)),c.success("Draft deleted")},children:[e.jsx(Q,{className:"h-4 w-4 mr-2"})," Delete draft"]})]})]})})]},t.id)})})]})})]})}export{ce 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.