PageSourceSearch

https://landedglobal.ai/assets/QuotesPage-BUeAQZ_0.js

js landedglobal.ai collected 2026-10-05 16:11:37 UTC 7,187 bytes, 2 lines download raw bytes

1import{u as S,a as b,r as c,j as t,S as C,L as v,d as x}from"./index-CHhzuL3B.js";import{x as T,e as A,A as E,z as F,B as H,P as Q,m as U}from"./firebase-lib-CWUo0RKC.js";import{B as $}from"./Breadcrumb-FQjPNLIr.js";import{n as k,F as I}from"./quoteFollowup-ClkEDfc8.js";import"./react-vendor-CCXFnprz.js";import"./pdf-lib-DPbQAZCF.js";const O="_root_pve4u_1",M="_content_pve4u_7",P="_pageHeader_pve4u_14",V="_pageHeaderLeft_pve4u_22",z="_pageTitle_pve4u_24",W="_pageDesc_pve4u_31",Y="_newQuoteBtn_pve4u_37",G="_statsRow_pve4u_54",J="_statBox_pve4u_60",K="_statNum_pve4u_71",X="_statLabel_pve4u_77",Z="_filterRow_pve4u_85",ee="_searchInput_pve4u_93",te="_statusFilters_pve4u_108",se="_filterBtn_pve4u_114",ae="_filterBtnActive_pve4u_127",oe="_quoteList_pve4u_134",ne="_quoteRow_pve4u_140",ce="_quoteRowLeft_pve4u_157",ie="_quoteNumber_pve4u_164",le="_quoteBadge_pve4u_170",re="_quoteRowMid_pve4u_180",ue="_quoteClient_pve4u_185",de="_quoteDesc_pve4u_195",pe="_quoteRowRight_pve4u_204",me="_quoteTotal_pve4u_212",_e="_quoteDate_pve4u_218",he="_quoteRowActions_pve4u_224",ve="_actionBtn_pve4u_230",xe="_actionBtnDelete_pve4u_246",Ne="_emptyState_pve4u_252",fe="_emptyIcon_pve4u_262",ge="_emptyTitle_pve4u_264",we="_emptyDesc_pve4u_271",je="_emptyBtn_pve4u_278",ye="_spinner_pve4u_294",s={root:O,content:M,pageHeader:P,pageHeaderLeft:V,pageTitle:z,pageDesc:W,newQuoteBtn:Y,statsRow:G,statBox:J,statNum:K,statLabel:X,filterRow:Z,searchInput:ee,statusFilters:te,filterBtn:se,filterBtnActive:ae,quoteList:oe,quoteRow:ne,quoteRowLeft:ce,quoteNumber:ie,quoteBadge:le,quoteRowMid:re,quoteClient:ue,quoteDesc:de,quoteRowRight:pe,quoteTotal:me,quoteDate:_e,quoteRowActions:he,actionBtn:ve,actionBtnDelete:xe,emptyState:Ne,emptyIcon:fe,emptyTitle:ge,emptyDesc:we,emptyBtn:je,spinner:ye},N={draft:"Draft",sent:"Sent",viewed:"Viewed",accepted:"Accepted",declined:"Declined",expired:"Expired"},f={draft:"var(--color-fog)",sent:"var(--color-teal)",viewed:"#60a5fa",accepted:"#4ade80",declined:"#f87171",expired:"#f87171"};function g(i){if(!i)return"—";const[l,a,r]=i.split("-");return new Date(l,a-1,r).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}function be(){const{user:i}=S(),l=b(),[a,r]=c.useState([]),[w,j]=c.useState(!0),[d,y]=c.useState(""),[p,B]=c.useState("all"),[m,_]=c.useState(null);c.useEffect(()=>(document.title="Quotes — Landed",()=>{document.title="Landed"}),[]),c.useEffect(()=>{if(!i)return;async function e(){try{const o=T(A(x,"quotes"),E("uid","==",i.uid),F("createdAt","desc")),n=await H(o);r(n.docs.map(u=>({id:u.id,...u.data()})))}catch{}finally{j(!1)}}e()},[i]);async function q(e){if(window.confirm("Delete this quote? This cannot be undone.")){_(e);try{await Q(U(x,"quotes",e)),r(o=>o.filter(n=>n.id!==e))}finally{_(null)}}}const h=a.filter(e=>{if(p!=="all"&&e.status!==p)return!1;if(d){const o=d.toLowerCase();return(e.quoteNumber||"").toLowerCase().includes(o)||(e.clientName||"").toLowerCase().includes(o)||(e.clientCompany||"").toLowerCase().includes(o)}return!0}),D=a.reduce((e,o)=>e+(o.grandTotal||0),0),L=a.filter(e=>e.status==="sent"||e.status==="viewed"||e.status==="accepted").length,R=a.filter(e=>e.status==="accepted").length;return t.jsxs("div",{className:s.root,children:[t.jsx(C,{}),t.jsxs("div",{className:s.content,children:[t.jsxs("div",{className:s.pageHeader,children:[t.jsxs("div",{className:s.pageHeaderLeft,children:[t.jsx($,{crumbs:[{label:"Home",to:"/dashboard"},{label:"Dashboard",to:"/dashboard"},{label:"Quotes"}]}),t.jsx("h1",{className:s.pageTitle,children:"Freight Quotes"}),t.jsx("p",{className:s.pageDesc,children:"Create professional branded freight cost quotes to share with clients."})]}),t.jsx(v,{to:"/quotes/new",className:s.newQuoteBtn,children:"+ New Quote"})]}),a.length>0&&t.jsxs("div",{className:s.statsRow,children:[t.jsxs("div",{className:s.statBox,children:[t.jsx("span",{className:s.statNum,children:a.length}),t.jsx("span",{className:s.statLabel,children:"Total Quotes"})]}),t.jsxs("div",{className:s.statBox,children:[t.jsx("span",{className:s.statNum,children:L}),t.jsx("span",{className:s.statLabel,children:"Sent"})]}),t.jsxs("div",{className:s.statBox,children:[t.jsx("span",{className:s.statNum,children:R}),t.jsx("span",{className:s.statLabel,children:"Accepted"})]}),t.jsxs("div",{className:s.statBox,children:[t.jsxs("span",{className:s.statNum,children:["$",D.toLocaleStr
1ing("en-US",{maximumFractionDigits:0})]}),t.jsx("span",{className:s.statLabel,children:"Total Value"})]})]}),t.jsxs("div",{className:s.filterRow,children:[t.jsx("input",{className:s.searchInput,value:d,onChange:e=>y(e.target.value),placeholder:"Search quotes…"}),t.jsx("div",{className:s.statusFilters,children:["all","draft","sent","viewed","accepted","declined","expired"].map(e=>t.jsx("button",{className:`${s.filterBtn} ${p===e?s.filterBtnActive:""}`,onClick:()=>B(e),children:e==="all"?"All":N[e]},e))})]}),w?t.jsxs("div",{className:s.emptyState,children:[t.jsx("div",{className:s.spinner}),t.jsx("p",{children:"Loading quotes…"})]}):h.length===0?t.jsxs("div",{className:s.emptyState,children:[t.jsx("div",{className:s.emptyIcon,children:"📋"}),t.jsx("p",{className:s.emptyTitle,children:a.length===0?"No quotes yet":"No quotes match your filter"}),t.jsx("p",{className:s.emptyDesc,children:a.length===0?"Create a professional freight cost quote to share with clients.":"Try adjusting your search or filter."}),a.length===0&&t.jsx(v,{to:"/quotes/new",className:s.emptyBtn,children:"Create your first quote"})]}):t.jsx("div",{className:s.quoteList,children:h.map(e=>{const n=e.validUntil&&e.validUntil<new Date().toISOString().slice(0,10)&&e.status!=="accepted"&&e.status==="sent"?"expired":e.status||"draft";return t.jsxs("div",{className:s.quoteRow,onClick:()=>l(`/quotes/${e.id}`),children:[t.jsxs("div",{className:s.quoteRowLeft,children:[t.jsx("span",{className:s.quoteNumber,children:e.quoteNumber||"—"}),t.jsx("span",{className:s.quoteBadge,style:{background:f[n]+"22",color:f[n]},children:N[n]||n}),k(e)&&t.jsx("span",{className:s.quoteBadge,style:{background:"#f59e0b22",color:"#f59e0b"},title:`Sent ${I}+ business days ago, still unaccepted`,children:"Needs follow-up"})]}),t.jsxs("div",{className:s.quoteRowMid,children:[t.jsxs("p",{className:s.quoteClient,children:[e.clientName||"No client",e.clientCompany?` · ${e.clientCompany}`:""]}),t.jsx("p",{className:s.quoteDesc,children:e.serviceDescription?e.serviceDescription.slice(0,80)+(e.serviceDescription.length>80?"…":""):"—"})]}),t.jsxs("div",{className:s.quoteRowRight,children:[t.jsxs("span",{className:s.quoteTotal,children:["$",(e.grandTotal||0).toLocaleString("en-US",{minimumFractionDigits:2})]}),t.jsxs("span",{className:s.quoteDate,children:[g(e.quoteDate)," · Valid until ",g(e.validUntil)]})]}),t.jsxs("div",{className:s.quoteRowActions,onClick:u=>u.stopPropagation(),children:[t.jsx("button",{className:s.actionBtn,onClick:()=>l(`/quotes/${e.id}`),title:"Edit",children:"Edit"}),t.jsx("button",{className:`${s.actionBtn} ${s.actionBtnDelete}`,onClick:()=>q(e.id),disabled:m===e.id,title:"Delete",children:m===e.id?"…":"✕"})]})]},e.id)})})]})]})}export{be as default};
2//# sourceMappingURL=QuotesPage-BUeAQZ_0.js.map

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.