Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-18 19:11:22 +00:00
co-authored by renee-png
parent 8d00f61f2c
commit dda1a3b574
+97
View File
@@ -308,6 +308,103 @@ function PleadingNewPage() {
}
/>
{/* Client / case linkage + variable picker */}
<Card className="mb-6">
<CardContent className="p-5 space-y-4">
<div className="flex items-start justify-between gap-4 flex-wrap">
<div>
<Label className="text-base flex items-center gap-2">
<Variable className="h-4 w-4 text-muted-foreground" /> Link client &amp; case
</Label>
<p className="text-xs text-muted-foreground mt-0.5">
Pick a client and/or case to expose variables (including custom fields). Insert tokens like{" "}
<code className="px-1 rounded bg-muted">{`{{client.name}}`}</code> anywhere in the body, caption, footnotes, or footer — they’ll be substituted on download &amp; save.
</p>
</div>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div className="space-y-1.5">
<Label className="text-xs">Client</Label>
<Select
value={clientId || "__none__"}
onValueChange={(v) => {
const next = v === "__none__" ? "" : v;
setClientId(next);
if (next && caseId) {
const k = caseOptions.find((x) => x.id === caseId);
if (k && k.client_id !== next) setCaseId("");
}
}}
>
<SelectTrigger><SelectValue placeholder="None" /></SelectTrigger>
<SelectContent className="max-h-72">
<SelectItem value="__none__">— None —</SelectItem>
{clientOptions.map((c) => (
<SelectItem key={c.id} value={c.id}>{c.name}</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-1.5">
<Label className="text-xs">Case</Label>
<Select value={caseId || "__none__"} onValueChange={(v) => setCaseId(v === "__none__" ? "" : v)}>
<SelectTrigger><SelectValue placeholder="None" /></SelectTrigger>
<SelectContent className="max-h-72">
<SelectItem value="__none__">— None —</SelectItem>
{filteredCases.map((k) => (
<SelectItem key={k.id} value={k.id}>
{k.case_number} — {k.title}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
{chips.length > 0 ? (
<div className="space-y-2">
<div className="flex items-center justify-between gap-2">
<Label className="text-xs">Available variables ({chips.length})</Label>
<Input
value={chipFilter}
onChange={(e) => setChipFilter(e.target.value)}
placeholder="Filter…"
className="h-8 max-w-[220px]"
/>
</div>
<div className="flex flex-wrap gap-1.5 max-h-48 overflow-auto p-2 border rounded bg-muted/20">
{filteredChips.length === 0 ? (
<span className="text-xs text-muted-foreground italic">No matching variables.</span>
) : (
filteredChips.map((c) => (
<button
key={c.token}
type="button"
onClick={() => copyChip(c.token)}
title={c.value ? `Click to copy · current value: ${c.value}` : `Click to copy · (empty)`}
className="group inline-flex items-center gap-1 rounded border bg-background px-2 py-1 text-xs hover:border-primary hover:bg-accent transition-colors"
>
<code className="font-mono">{c.token}</code>
<span className="text-muted-foreground">· {c.label}</span>
{!c.value && <Badge variant="secondary" className="ml-1 text-[10px] px-1 py-0">empty</Badge>}
<Copy className="h-3 w-3 opacity-0 group-hover:opacity-70 transition-opacity" />
</button>
))
)}
</div>
<p className="text-[11px] text-muted-foreground">
Click a chip to copy its token, then paste it where you want the value to appear.
</p>
</div>
) : (
<div className="text-xs text-muted-foreground italic border border-dashed rounded p-3">
Select a client or case to see available variables.
</div>
)}
</CardContent>
</Card>
{/* Top row: settings + caption preview */}
<div className="grid lg:grid-cols-2 gap-6">
<Card>