Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-18 21:38:18 +00:00
co-authored by renee-png
parent a7865d6b23
commit 01ae9f6c4c
+58 -24
View File
@@ -143,8 +143,8 @@ export function LetterGenerator() {
"firm.phone": firm?.contact_phone ?? "",
"firm.email": firm?.contact_email ?? "",
"firm.website": (firm as any)?.website ?? "",
"owner.name": homeowner ? `${homeowner.first_name} ${homeowner.last_name}`.trim() : "",
"client.name": client?.name ?? "",
"recipient.name": recipient?.name ?? "",
"recipient.company": recipient?.company ?? "",
attorney: attorneyName,
date: fmtDateLong(date),
};
@@ -244,21 +244,13 @@ export function LetterGenerator() {
doc.text(fmtDateLong(date), centerX, y, { align: "center" });
y += 28;
// ----- Recipient -----
// ----- Recipient (from selected contact) -----
doc.setFont(bodyFont, "normal");
doc.setFontSize(bodyFontSize);
ownerMailingLines(homeowner).forEach((l) => {
contactMailingLines(recipient).forEach((l) => {
doc.text(l, margin, y);
y += lh - 1;
});
if (!homeowner && client) {
doc.text(client.name, margin, y);
y += lh - 1;
clientAddressLines(client).forEach((l) => {
doc.text(l, margin, y);
y += lh - 1;
});
}
// Certified mail line (right-aligned, italic) — only when a number is provided
if (certifiedMailNumber.trim() && template.showCertifiedMail !== false) {
@@ -351,18 +343,60 @@ export function LetterGenerator() {
<div className="space-y-4">
<Card>
<CardContent className="pt-6 space-y-4">
<ClientHomeownerPicker
clientId={clientId}
homeownerId={homeownerId}
onClientChange={(id, c) => {
setClientId(id);
setClient(c);
}}
onHomeownerChange={(id, h) => {
setHomeownerId(id);
setHomeowner(h);
}}
/>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<Label>Case (optional)</Label>
<Select
value={caseId || "__none"}
onValueChange={(v) => setCaseId(v === "__none" ? "" : v)}
>
<SelectTrigger>
<SelectValue placeholder="Link to a case" />
</SelectTrigger>
<SelectContent>
<SelectItem value="__none">— No case —</SelectItem>
{cases.map((c) => (
<SelectItem key={c.id} value={c.id}>
{c.case_number} — {c.title}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div>
<Label>
Recipient (contact)
{caseId && sortedContacts.linked.length > 0 ? (
<span className="text-xs text-muted-foreground ml-2">
Case contacts shown first
</span>
) : null}
</Label>
<Select value={recipientId} onValueChange={setRecipientId}>
<SelectTrigger>
<SelectValue placeholder="Select a contact" />
</SelectTrigger>
<SelectContent>
{sortedContacts.linked.length > 0 && (
<>
{sortedContacts.linked.map((c) => (
<SelectItem key={c.id} value={c.id}>
★ {c.name}
{c.company ? ` — ${c.company}` : ""}
</SelectItem>
))}
</>
)}
{sortedContacts.others.map((c) => (
<SelectItem key={c.id} value={c.id}>
{c.name}
{c.company ? ` — ${c.company}` : ""}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<Label>Date</Label>