diff --git a/src/components/app-shell.tsx b/src/components/app-shell.tsx index da0c777..f5e88da 100644 --- a/src/components/app-shell.tsx +++ b/src/components/app-shell.tsx @@ -27,7 +27,7 @@ const NAV: NavItem[] = [ { to: "/inbox", label: "Inbox", icon: InboxIcon }, { to: "/status", label: "Status Updates", icon: Activity }, { to: "/collections", label: "Collections", icon: DollarSign }, - { to: "/documents", label: "Documents", icon: FolderOpen }, + { to: "/documents", label: "Pleadings", icon: FolderOpen }, { to: "/files", label: "Files", icon: FilesIcon }, { to: "/forms", label: "Forms & Letters", icon: ClipboardList }, { to: "/invoices", label: "Invoices", icon: Receipt }, diff --git a/src/routes/documents.index.tsx b/src/routes/documents.index.tsx index ed2a423..70a64f1 100644 --- a/src/routes/documents.index.tsx +++ b/src/routes/documents.index.tsx @@ -4,40 +4,38 @@ import { ProtectedLayout } from "@/components/protected-layout"; import { PageContainer, PageHeader } from "@/components/app-shell"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; -import { Badge } from "@/components/ui/badge"; import { supabase } from "@/integrations/supabase/client"; import { formatDate } from "@/lib/format"; -import { FilePlus2, FileText, Gavel, LayoutTemplate, Plus, Download, Trash2 } from "lucide-react"; +import { FileText, Gavel, Download, Trash2, FilePlus2 } from "lucide-react"; import { toast } from "sonner"; export const Route = createFileRoute("/documents/")({ - component: DocumentsIndex, + component: PleadingsIndex, }); -function DocumentsIndex() { - const [generated, setGenerated] = useState([]); - const [templates, setTemplates] = useState([]); +function PleadingsIndex() { + const [pleadings, setPleadings] = useState([]); const load = async () => { - const [g, t] = await Promise.all([ - supabase.from("generated_documents").select("*").order("created_at", { ascending: false }).limit(20), - supabase.from("document_templates").select("*").order("name"), - ]); - setGenerated(g.data ?? []); - setTemplates(t.data ?? []); + const { data } = await supabase + .from("generated_documents") + .select("*") + .eq("kind", "pleading") + .order("created_at", { ascending: false }); + setPleadings(data ?? []); }; useEffect(() => { load(); }, []); - const removeGenerated = async (row: any) => { + const removePleading = async (row: any) => { if (!confirm(`Delete ${row.name}?`)) return; if (row.storage_path) await supabase.storage.from("generated-documents").remove([row.storage_path]); const { error } = await supabase.from("generated_documents").delete().eq("id", row.id); if (error) toast.error(error.message); else { toast.success("Deleted"); load(); } }; - const downloadGenerated = async (row: any) => { - if (!row.storage_path) { toast.error("No file stored for this document"); return; } + const downloadPleading = async (row: any) => { + if (!row.storage_path) { toast.error("No file stored for this pleading"); return; } const { data, error } = await supabase.storage.from("generated-documents").createSignedUrl(row.storage_path, 60); if (error) { toast.error(error.message); return; } window.open(data.signedUrl, "_blank"); @@ -47,25 +45,18 @@ function DocumentsIndex() { - - - + } /> -
+
@@ -77,58 +68,51 @@ function DocumentsIndex() { - - - -
-
-
New template
-
Define custom merge fields and reuse them.
-
-
-
- - - - -
-
-
Template library
-
{templates.length} template{templates.length === 1 ? "" : "s"} available.
-
-
-
- + + +
+
+
Saved pleadings
+
{pleadings.length} saved ยท open any below as a new template.
+
+
+
- Recent documents + Saved pleadings - {generated.length === 0 ? ( -
No documents yet. Create a pleading or use a template.
+ {pleadings.length === 0 ? ( +
No pleadings yet. Create one to save it as a reusable template.
) : ( - - {generated.map((d) => ( + {pleadings.map((d) => ( - - + ))} diff --git a/src/routes/documents.pleading.new.tsx b/src/routes/documents.pleading.new.tsx index 324beb3..4cbda98 100644 --- a/src/routes/documents.pleading.new.tsx +++ b/src/routes/documents.pleading.new.tsx @@ -1,5 +1,5 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router"; -import { useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { ProtectedLayout } from "@/components/protected-layout"; import { PageContainer, PageHeader } from "@/components/app-shell"; import { Card, CardContent } from "@/components/ui/card"; @@ -22,11 +22,15 @@ import { Download, FileText, Save, Loader2, Plus, Trash2 } from "lucide-react"; export const Route = createFileRoute("/documents/pleading/new")({ component: PleadingNewPage, + validateSearch: (search: Record) => ({ + from: typeof search.from === "string" ? search.from : undefined, + }), }); function PleadingNewPage() { const { user } = useAuth(); const navigate = useNavigate(); + const { from } = Route.useSearch(); const [courtType, setCourtType] = useState<"CIRCUIT" | "COUNTY">("CIRCUIT"); const [circuit, setCircuit] = useState("ELEVENTH"); const [county, setCounty] = useState("Miami-Dade"); @@ -42,6 +46,33 @@ function PleadingNewPage() { const [docName, setDocName] = useState("Pleading"); const [saving, setSaving] = useState(false); + useEffect(() => { + if (!from) return; + (async () => { + const { data, error } = await supabase + .from("generated_documents") + .select("name, payload") + .eq("id", from) + .maybeSingle(); + if (error || !data) return; + const p = (data.payload || {}) as any; + if (p.courtType) setCourtType(p.courtType); + if (p.circuit) setCircuit(p.circuit); + if (p.county) setCounty(p.county); + if (typeof p.plaintiffs === "string") setPlaintiffs(p.plaintiffs); + if (typeof p.defendants === "string") setDefendants(p.defendants); + if (typeof p.caseNumber === "string") setCaseNumber(p.caseNumber); + if (typeof p.title === "string") setTitle(p.title); + if (typeof p.bodyHtml === "string") setBodyHtml(p.bodyHtml); + if (Array.isArray(p.footnotes)) setFootnotes(p.footnotes); + if (typeof p.footerLeft === "string") setFooterLeft(p.footerLeft); + if (typeof p.footerCenter === "string") setFooterCenter(p.footerCenter); + if (typeof p.footerRight === "string") setFooterRight(p.footerRight); + setDocName(`${data.name} (copy)`); + toast.success("Loaded saved pleading"); + })(); + }, [from]); + const counties = useMemo(() => { const c = FL_CIRCUITS.find((x) => x.value === circuit); return c?.counties ?? [];
NameType Created Actions
{d.name}
{d.kind} + + + {d.name} + + {formatDate(d.created_at)} + {d.storage_path && ( - + )} - +