From e3cf7e2cd9de9452ec4790c8c6314ff02a86fb75 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 18:58:50 +0000 Subject: [PATCH] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/invoices.index.tsx | 57 ++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/routes/invoices.index.tsx b/src/routes/invoices.index.tsx index 2667cf5..7855ffc 100644 --- a/src/routes/invoices.index.tsx +++ b/src/routes/invoices.index.tsx @@ -53,25 +53,46 @@ function InvoicesIndex() { useEffect(() => { (async () => { - const { data } = await supabase - .from("invoices") - .select("*, client:clients(id, name), case:cases(id, case_number, title)") - .order("created_at", { ascending: false }); - setInvoices(data ?? []); - setLoading(false); + const fetchInvoices = async () => { + setLoading(true); + let query = supabase + .from("invoices") + .select("*, client:clients(id, name), case:cases(id, case_number, title)", { count: "exact" }) + .order("created_at", { ascending: false }); - // Track placeholder invoices so we can identify "marked-invoiced" items - const placeholders = new Set( - (data ?? []) - .filter((i: any) => - typeof i.invoice_number === "string" && - (i.invoice_number.startsWith("MARKED-INVOICED-") || i.invoice_number.startsWith("IMPORT-PREBILLED-")) - ) - .map((i: any) => i.id), - ); - setPlaceholderIds(placeholders); - })(); - }, []); + if (status !== "all") query = query.eq("status", status); + if (q.trim()) { + const s = q.trim().replace(/[%,]/g, " "); + query = query.or(`invoice_number.ilike.%${s}%`); + } + + const from = page * PAGE_SIZE; + const to = from + PAGE_SIZE - 1; + const { data, count } = await query.range(from, to); + + setInvoices(data ?? []); + setTotalCount(count ?? 0); + setLoading(false); + + const placeholders = new Set( + (data ?? []) + .filter((i: any) => + typeof i.invoice_number === "string" && + (i.invoice_number.startsWith("MARKED-INVOICED-") || i.invoice_number.startsWith("IMPORT-PREBILLED-")) + ) + .map((i: any) => i.id), + ); + setPlaceholderIds(placeholders); + }; + + useEffect(() => { fetchInvoices(); /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [page, status]); + + // Debounce search + useEffect(() => { + const t = setTimeout(() => { setPage(0); fetchInvoices(); }, 300); + return () => clearTimeout(t); + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + }, [q]); const loadUnbilled = async () => { const [{ data: t }, { data: e }] = await Promise.all([