From a1a045fff8a4dc7ad9f723158b434fac3f545bf1 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 23:16:35 +0000 Subject: [PATCH 1/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/invoices.$invoiceId.tsx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/routes/invoices.$invoiceId.tsx b/src/routes/invoices.$invoiceId.tsx index a474882..983ff4a 100644 --- a/src/routes/invoices.$invoiceId.tsx +++ b/src/routes/invoices.$invoiceId.tsx @@ -497,9 +497,12 @@ function InvoiceDetail() { {canModify && ( -
- +
)} @@ -508,9 +511,14 @@ function InvoiceDetail() { ))} {canModify && groups.length === 0 && ( - +
+ + +
)} From 2c212337ada28bd79f6f7e0268a8dcd9f097ef89 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 23:17:15 +0000 Subject: [PATCH 2/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/trust.index.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/routes/trust.index.tsx b/src/routes/trust.index.tsx index 8b09ad8..423db03 100644 --- a/src/routes/trust.index.tsx +++ b/src/routes/trust.index.tsx @@ -5,10 +5,20 @@ import { PageContainer, PageHeader } from "@/components/app-shell"; import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; +import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { + Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, +} from "@/components/ui/dialog"; +import { + Select, SelectContent, SelectItem, SelectTrigger, SelectValue, +} from "@/components/ui/select"; import { supabase } from "@/integrations/supabase/client"; +import { useAuth } from "@/lib/auth"; import { formatCurrency, formatDate } from "@/lib/format"; -import { Search, Wallet, Download, ArrowDownToLine, ArrowUpFromLine } from "lucide-react"; +import { Search, Wallet, Download, ArrowDownToLine, ArrowUpFromLine, Loader2 } from "lucide-react"; +import { toast } from "sonner"; export const Route = createFileRoute("/trust/")({ component: () => ( From 429c659f05789f484a952b08d8cf87cf1bbd53ab Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 23:17:30 +0000 Subject: [PATCH 3/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/trust.index.tsx | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/routes/trust.index.tsx b/src/routes/trust.index.tsx index 423db03..9b8c14f 100644 --- a/src/routes/trust.index.tsx +++ b/src/routes/trust.index.tsx @@ -152,12 +152,28 @@ function TrustLedgerPage() { title="Trust accounting" description="All client trust balances and ledger activity." actions={ - +
+ + + +
} /> + setEntryDialog(null)} + onSaved={(e) => { setEntries((p) => [e, ...p]); setEntryDialog(null); }} + /> +
From a8169fc82aa6c3aa87ec693e36eaeba2846262b9 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 23:17:39 +0000 Subject: [PATCH 4/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/trust.index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/trust.index.tsx b/src/routes/trust.index.tsx index 9b8c14f..98d9639 100644 --- a/src/routes/trust.index.tsx +++ b/src/routes/trust.index.tsx @@ -57,6 +57,7 @@ function TrustLedgerPage() { const [loading, setLoading] = useState(true); const [search, setSearch] = useState(""); const [view, setView] = useState<"all" | "active" | "archived">("active"); + const [entryDialog, setEntryDialog] = useState(null); useEffect(() => { (async () => { From f75f2d5094d350676c1b0c44765f91344a4a37a2 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 23:18:05 +0000 Subject: [PATCH 5/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/trust.index.tsx | 125 ++++++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 1 deletion(-) diff --git a/src/routes/trust.index.tsx b/src/routes/trust.index.tsx index 98d9639..d7492cb 100644 --- a/src/routes/trust.index.tsx +++ b/src/routes/trust.index.tsx @@ -312,4 +312,127 @@ function TrustLedgerPage() { ); -} \ No newline at end of file +} +function RecordEntryDialog({ + open, type, clients, onClose, onSaved, +}: { + open: boolean; + type: "deposit" | "withdrawal"; + clients: ClientLite[]; + onClose: () => void; + onSaved: (entry: Entry) => void; +}) { + const { user } = useAuth(); + const [clientId, setClientId] = useState(""); + const [caseId, setCaseId] = useState("_pool"); + const [cases, setCases] = useState<{ id: string; case_number: string | null; title: string | null }[]>([]); + const [date, setDate] = useState(new Date().toISOString().slice(0, 10)); + const [amount, setAmount] = useState(""); + const [note, setNote] = useState(""); + const [saving, setSaving] = useState(false); + + useEffect(() => { + if (!open) { + setClientId(""); setCaseId("_pool"); setCases([]); + setAmount(""); setNote(""); setDate(new Date().toISOString().slice(0, 10)); + } + }, [open]); + + useEffect(() => { + if (!clientId) { setCases([]); return; } + (async () => { + const { data } = await supabase + .from("cases") + .select("id, case_number, title") + .eq("client_id", clientId) + .is("archived_at", null) + .order("opened_at", { ascending: false }); + setCases(data ?? []); + })(); + }, [clientId]); + + const sortedClients = useMemo( + () => [...clients].filter((c) => !c.archived_at).sort((a, b) => (a.name ?? "").localeCompare(b.name ?? "")), + [clients], + ); + + const save = async () => { + if (!clientId) return toast.error("Pick a client"); + const amt = Number(amount); + if (!amt || amt <= 0) return toast.error("Enter a valid amount"); + setSaving(true); + const { data, error } = await supabase + .from("trust_ledger_entries") + .insert({ + client_id: clientId, + case_id: caseId === "_pool" ? null : caseId, + entry_date: date, + entry_type: type, + amount: amt, + note: note || null, + created_by: user?.id ?? null, + }) + .select("*") + .single(); + setSaving(false); + if (error) return toast.error(error.message); + toast.success(`${type === "deposit" ? "Deposit" : "Withdrawal"} recorded`); + onSaved(data as Entry); + }; + + return ( + !v && onClose()}> + + + Record {type} + +
+
+ + +
+
+ + +
+
+
+ + setDate(e.target.value)} /> +
+
+ + setAmount(e.target.value)} /> +
+
+
+ +