Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-17 01:45:54 +00:00
co-authored by renee-png
parent 2236a45d91
commit 3483e065ec
7 changed files with 869 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
import { createFileRoute, Link } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { ProtectedLayout } from "@/components/protected-layout";
import { PageContainer, PageHeader } from "@/components/app-shell";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { supabase } from "@/integrations/supabase/client";
import { Plus, FileText, ChevronRight, Gavel } from "lucide-react";
import { formatDate } from "@/lib/format";
export const Route = createFileRoute("/documents/templates/")({
component: TemplatesIndex,
});
function TemplatesIndex() {
const [rows, setRows] = useState<any[]>([]);
useEffect(() => {
supabase.from("document_templates").select("*").order("name").then(({ data }) => setRows(data ?? []));
}, []);
return (
<ProtectedLayout>
<PageContainer>
<PageHeader
title="Templates"
description="Reusable document templates with custom merge fields."
actions={
<Button asChild><Link to="/documents/templates/new"><Plus className="h-4 w-4 mr-2" /> New template</Link></Button>
}
/>
<Card>
<CardContent className="p-0">
{rows.length === 0 ? (
<div className="text-center py-12 text-muted-foreground text-sm">No templates yet.</div>
) : (
<ul className="divide-y">
{rows.map((t) => (
<li key={t.id}>
<Link to="/documents/templates/$templateId" params={{ templateId: t.id }} className="flex items-center gap-3 px-4 py-3 hover:bg-muted/40">
<div className="h-9 w-9 rounded-md bg-muted flex items-center justify-center">
{t.kind === "pleading" ? <Gavel className="h-4 w-4" /> : <FileText className="h-4 w-4" />}
</div>
<div className="min-w-0 flex-1">
<div className="font-medium truncate">{t.name}</div>
<div className="text-xs text-muted-foreground truncate">
{t.description || "No description"} · {Array.isArray(t.fields) ? t.fields.length : 0} field{(t.fields?.length ?? 0) === 1 ? "" : "s"}
</div>
</div>
<Badge variant="outline" className="capitalize">{t.kind}</Badge>
<span className="text-xs text-muted-foreground hidden sm:inline">{formatDate(t.updated_at)}</span>
<ChevronRight className="h-4 w-4 text-muted-foreground" />
</Link>
</li>
))}
</ul>
)}
</CardContent>
</Card>
</PageContainer>
</ProtectedLayout>
);
}