PageSourceSearch

https://voiceexpense.com/assets/receipt-matching-CxyWr0Bs.js

js voiceexpense.com collected 2026-10-05 22:10:01 UTC 9,953 bytes, 1 lines download raw bytes

1import{r as d,u as P,z as E,R as T,j as e,C as h,B as x,y as L,k as b,a as I,L as n}from"./index-lpizoYms.js";import{P as F,R as U}from"./receipt-scanner-Cp3UgNNq.js";import{B as N}from"./badge-DG5Ti9w5.js";import{S as B}from"./separator-BRlxBOsD.js";import{u as $}from"./useMutation-B-4FeDqH.js";import{L as v}from"./loader-circle-CGq0y1ud.js";import{A as M}from"./arrow-left-CbbLeumO.js";import{R as y}from"./receipt-DnpXgF5Y.js";import{C as z}from"./circle-check-big-DG1ORyDS.js";import{C as q}from"./dropdown-menu-Cw6FPngR.js";import{f as w}from"./format-n7Cac3Pa.js";import{L as H}from"./loading-animation-Do6HHxBv.js";import{U as D}from"./user-menu-CPS_SltR.js";import{M as Q}from"./mic-C39B_pLi.js";import"./web-camera-D3zWQP2-.js";import"./camera-CIwT98eY.js";import"./file-text-CAE7ba_-.js";import"./index-CcRrwtbT.js";import"./chevron-right-Dt85OLvr.js";import"./protectedTokens-BtKqisjZ.js";import"./index-EBtNSbBa.js";import"./user-BuvD9Ze_.js";import"./circle-help-2EZJam0a.js";import"./life-buoy-DCrrIJpQ.js";import"./shield-check-DuKh6Qc3.js";import"./log-out-FIlBpGDh.js";import"./chevron-down-BWbUWsz9.js";function V({userId:l,receiptData:t,onBack:r,onComplete:c}){const[a,p]=d.useState([]),[i,j]=d.useState(null),[u,f]=d.useState(!0),{toast:m}=P(),R=E();T.useEffect(()=>{(async()=>{try{const k=await(await b("POST","/api/receipts/match",{userId:l,vendor:t.vendor,cost:t.cost,date:t.date,days:7})).json();p(k.matches)}catch{m({title:"Failed to find matches",description:"Could not search for matching expenses",variant:"destructive"})}finally{f(!1)}})()},[l,t,m]);const o=$({mutationFn:async s=>{if(!t.originalImageDataUrl)throw new Error("Receipt image data is missing");return(await b("PATCH",`/api/expenses/${s}/attach-receipt`,{receiptFileName:`receipt_${Date.now()}.jpg`,receiptFileSize:"Unknown",receiptFileType:"image/jpeg",receiptDataUrl:t.originalImageDataUrl})).json()},onSuccess:()=>{m({title:"Receipt attached successfully",description:"The receipt has been attached to the selected expense"}),R.invalidateQueries({queryKey:["/api/expenses"]}),c()},onError:s=>{m({title:"Failed to attach receipt",description:s.message||"Could not attach receipt to expense",variant:"destructive"})}}),C=()=>{i&&o.mutate(i)},A=s=>s>=.8?"bg-green-500":s>=.6?"bg-yellow-500":"bg-red-500",S=s=>s>=.8?"Excellent match":s>=.6?"Good match":"Possible match";return u?e.jsxs(h,{className:"p-6 space-y-6",children:[e.jsxs("div",{className:"text-center",children:[e.jsx(v,{className:"h-8 w-8 animate-spin mx-auto mb-4 text-primary"}),e.jsx("h2",{className:"text-2xl font-bold text-slate-900 mb-2",children:"Finding Matches"}),e.jsx("p",{className:"text-slate-600",children:"Searching for expenses that match your receipt..."})]}),e.jsx(F,{value:50,className:"w-full"})]}):e.jsxs(h,{className:"p-6 space-y-6",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs(x,{variant:"ghost",size:"sm",onClick:r,className:"text-slate-600 hover:text-slate-900",children:[e.jsx(M,{className:"h-4 w-4 mr-2"}),"Back"]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold text-slate-900",children:"Match Receipt to Expense"}),e.jsx("p",{className:"text-slate-600",children:"Select an expense to attach this receipt to"})]})]}),e.jsx(h,{className:"p-4 bg-blue-50 border-blue-200",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(y,{className:"h-6 w-6 text-blue-600 mt-1"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("h3",{className:"font-semibold text-blue-900 mb-2",children:"Receipt Details"}),e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-blue-700 font-medium",children:"Vendor:"}),e.jsx("p",{className:"text-blue-800",children:t.vendor})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-blue-700 font-medium",children:"Amount:"}),e.jsxs("p",{className:"text-blue-800",children:["$",t.cost]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-blue-700 font-medium",children:"Date:"}),e.jsx("p",{className:"text-blue-800",children:t.date&&!isNaN(Date.parse(t.date))?w(new Date(t.date+"T12:00:00"),"MMM dd, yyyy"):"Unknown"})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-blue-700 font-medium",children:"Confidence:"}),e.jsxs("p",{className:"text-blue-800",children:[Math.round(t.confidence*100),"%"]})]})]})]})]})}),e.jsx(B,{}),a.length===0?e.jsxs("div",{className:"text-center py-8",children:[e.jsx(L,{className:"h-12 w-12 text-yellow-500 mx-auto mb-4"}),e.jsx("h3",{className:"text-lg font-semibold text-slate-900 mb-2",children:"No Matching Expenses Found"}),e.jsx("p",{className:"text-slate-600 mb-4",children:"We couldn't find any expenses from the past week that match this receipt."}),e.jsx(x,{variant:"outline",onClick:r,children:"Try Another Receipt"})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("h3",{className:"text-lg font-semibold text-slate-900",children:["Potential Matches (",a.length,")"]}),e.jsx("div",{className:"space-y-3",children:a.map(s=>e.jsx(h,{className:`p-4 cursor-pointer transition-all ${i===s.expense.id?"ring-2 ring-primary bg-primary/5":"hover:bg-slate-50"} ${s.canAttach?"":"opacity-60"}`,onClick:()=>s.canAttach&&j(s.expense.id),children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"mt-1",children:s.canAttach?i===s.expense.id?e.jsx(z,{className:"h-5 w-5 text-primary"}):e.jsx(q,{className:"h-5 w-5 text-slate-400"}):e.jsx(y,{className:"h-5 w-5 text-slate-400"})}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("h4",{className:"font-semibold text-slate-900",children:s.expense.vendor}),e.jsx(N,{variant:"secondary",className:`text-white ${A(s.similarity)}`,children:S(s.similarity)})]}),e.jsxs("div",{className:"text-right",children:[e.jsxs("p",{className:"font-semibold text-slate-900",children:["$",s.expense.cost]}),e.jsx("p",{className:"text-sm text-slate-500",children:s.expense.date&&!isNaN(Date.parse(s.expense.date))?w(new Date(s.expense.date.length===10?s.expense.date+"T12:00:00":s.expense.date),"MMM dd, yyyy"):"Unknown"})]})]}),e.jsx("p",{className:"text-sm text-slate-600 mb-2",children:s.expense.description}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-4 text-xs text-slate-500",children:[e.jsxs("span",{children:["Match: ",Math.round(s.similarity*100),"%"]}),s.expense.category&&e.jsx(N,{variant:"outline",className:"text-xs",children:s.expense.category})]}),!s.canAttach&&e.jsx(N,{variant:"destructive",className:"text-xs",children:"Receipt Already Attached"})]})]})]})},s.expense.id))}),e.jsxs("div",{className:"flex gap-3 pt-4",children:[e.jsx(x,{onClick:C,disabled:!i||o.isPending,className:"flex-1",children:o.isPending?e.jsxs(e.Fragment,{children:[e.jsx(v,{className:"mr-2 h-4 w-4 animate-spin"}),"Attaching Receipt..."]}):"Attach Receipt to Selected Expense"}),e.jsx(x,{variant:"outline",onClick:r,disabled:o.isPending,children:"Back"})]})]})]})}
1function Ne(){const[l,t]=d.useState("scan"),[r,c]=d.useState(null),{user:a,loading:p}=I(),i=f=>{c(f),t("match")},j=()=>{t("scan"),c(null)},u=()=>{t("scan"),c(null)};return p?e.jsx("div",{className:"min-h-screen bg-nature flex items-center justify-center",children:e.jsx(H,{message:"Loading AI Receipt Matching...",size:"large"})}):a?e.jsxs("div",{className:"min-h-screen bg-nature",children:[e.jsx("header",{className:"bg-white shadow-sm border-b border-slate-200 sticky top-0 z-50",children:e.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:e.jsxs("div",{className:"flex justify-between items-center h-16",children:[e.jsx("div",{className:"flex items-center space-x-3",children:e.jsxs(n,{href:"/",className:"flex items-center space-x-3",children:[e.jsx("div",{className:"w-8 h-8 bg-primary rounded-lg flex items-center justify-center",children:e.jsx(Q,{className:"text-white text-sm"})}),e.jsx("h1",{className:"text-xl font-bold text-slate-900",children:"VoiceTrack"})]})}),e.jsxs("nav",{className:"flex items-center space-x-4",children:[e.jsx(n,{href:"/",className:"text-sm font-medium text-slate-600 hover:text-slate-900",children:"Home"}),e.jsx(n,{href:"/expenses",className:"text-sm font-medium text-slate-600 hover:text-slate-900",children:"Expenses"}),e.jsx(n,{href:"/jobs",className:"text-sm font-medium text-slate-600 hover:text-slate-900",children:"Jobs"}),e.jsx(n,{href:"/trends",className:"text-sm font-medium text-slate-600 hover:text-slate-900",children:"Data Trends"}),e.jsx(n,{href:"/receipt-matching",className:"text-sm font-medium text-primary border-b-2 border-primary",children:"Receipt Matching"})]}),e.jsx("div",{className:"flex items-center space-x-4",children:e.jsx(D,{})})]})})}),e.jsxs("main",{className:"max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("div",{className:"flex items-center gap-4 mb-4",children:e.jsx(n,{href:"/",children:e.jsxs(x,{variant:"ghost",size:"sm",className:"text-slate-600 hover:text-slate-900",children:[e.jsx(M,{className:"h-4 w-4 mr-2"}),"Back to Home"]})})}),e.jsx("h1",{className:"text-3xl font-bold text-slate-900 mb-2",children:"AI Receipt Matching"}),e.jsx("p",{className:"text-slate-600",children:"Upload a receipt photo and let AI find matching expenses from your voice entries"})]}),l==="scan"&&e.jsx(U,{userId:a.id,onReceiptParsed:i}),l==="match"&&r&&e.jsx(V,{userId:a.id,receiptData:r,onBack:j,onComplete:u})]})]}):e.jsx("div",{className:"min-h-screen bg-nature flex items-center justify-center",children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4"}),e.jsx("p",{className:"text-slate-600",children:"Please sign in to use AI Receipt Matching"})]})})}export{Ne 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.