diff --git a/src/routes/documents.templates.$templateId.tsx b/src/routes/documents.templates.$templateId.tsx index 31bd404..c038710 100644 --- a/src/routes/documents.templates.$templateId.tsx +++ b/src/routes/documents.templates.$templateId.tsx @@ -21,7 +21,40 @@ export const Route = createFileRoute("/documents/templates/$templateId")({ interface FieldDef { key: string; label: string; type: "text" | "textarea" | "date" | "number" } function mergeBody(body: string, values: Record) { - return body.replace(/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g, (_, k) => values[k] ?? `{{${k}}}`); + // Replace tokens, treating unknown tokens as empty so optional fields don't leak + const merged = body.replace(/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g, (_, k) => values[k] ?? ""); + // Collapse runs of 3+ blank lines down to 2 (one blank line of separation) + return merged.replace(/\n{3,}/g, "\n\n").replace(/[ \t]+\n/g, "\n"); +} + +function formatToday() { + return new Date().toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" }); +} + +interface FirmSettings { + company_name?: string | null; + address_line1?: string | null; + address_line2?: string | null; + city?: string | null; + state?: string | null; + postal_code?: string | null; + contact_phone?: string | null; + contact_email?: string | null; + website?: string | null; +} + +function buildFirmHeader(f: FirmSettings | null): string { + if (!f) return ""; + const lines: string[] = []; + if (f.company_name) lines.push(f.company_name); + if (f.address_line1) lines.push(f.address_line1); + if (f.address_line2) lines.push(f.address_line2); + const csz = [f.city, f.state, f.postal_code].filter(Boolean).join(", ").replace(/, (\d)/, " $1"); + if (csz) lines.push(csz); + const contact = [f.contact_phone, f.contact_email].filter(Boolean).join(" • "); + if (contact) lines.push(contact); + if (f.website) lines.push(f.website); + return lines.join("\n"); } function TemplateDetailPage() {