From 76862e7a64a08a5c682d3f806b0c0e255b75c6c9 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 19 Apr 2026 20:08:42 +0000 Subject: [PATCH] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/invoices.$invoiceId.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/routes/invoices.$invoiceId.tsx b/src/routes/invoices.$invoiceId.tsx index 535eaae..d71eded 100644 --- a/src/routes/invoices.$invoiceId.tsx +++ b/src/routes/invoices.$invoiceId.tsx @@ -130,6 +130,19 @@ function InvoiceDetail() { const isDraft = invoice.status === "draft"; const balance = Number(invoice.total) - Number(invoice.amount_paid); + // Billable fees vs billable expenses subtotals (non-billable items have amount 0 and are excluded). + const { feesSubtotal, expensesSubtotal } = useMemo(() => { + let fees = 0; + let exp = 0; + for (const it of items) { + const amt = Number(it.amount) || 0; + if (amt === 0) continue; + if (it.kind === "expense") exp += amt; + else fees += amt; + } + return { feesSubtotal: fees, expensesSubtotal: exp }; + }, [items]); + const setStatus = async (status: string) => { if (status === "void") { if (!confirm("Void this invoice? Totals will be zeroed out and time/expenses will be unbilled.")) return;