Files
mylegal-stage-law/src/lib/pleading-variables.ts
T
2026-04-18 20:13:27 +00:00

194 lines
7.4 KiB
TypeScript

import { supabase } from "@/integrations/supabase/client";
export type VarMap = Record<string, string>;
export type LoadedContext = {
client?: any;
cases?: any;
clientFields: { key: string; label: string; value: string }[];
caseFields: { key: string; label: string; value: string }[];
};
export type VarChip = { token: string; label: string; value: string };
export async function loadPleadingContext(
clientId: string | null,
caseId: string | null,
): Promise<LoadedContext> {
const result: LoadedContext = { clientFields: [], caseFields: [] };
if (clientId) {
const { data: client } = await supabase.from("clients").select("*").eq("id", clientId).maybeSingle();
if (client) result.client = client;
const [{ data: defs }, { data: vals }] = await Promise.all([
supabase.from("custom_client_fields").select("id, key, label").eq("active", true).order("sort_order"),
supabase.from("client_field_values").select("field_id, value").eq("client_id", clientId),
]);
const valMap = new Map((vals || []).map((v: any) => [v.field_id, v.value || ""]));
result.clientFields = (defs || []).map((d: any) => ({
key: d.key,
label: d.label,
value: valMap.get(d.id) || "",
}));
}
if (caseId) {
const { data: caseRow } = await supabase.from("cases").select("*").eq("id", caseId).maybeSingle();
if (caseRow) result.cases = caseRow;
const [{ data: defs }, { data: vals }] = await Promise.all([
supabase.from("custom_case_fields").select("id, key, label").eq("active", true).order("sort_order"),
supabase.from("case_field_values").select("field_id, value").eq("case_id", caseId),
]);
const valMap = new Map((vals || []).map((v: any) => [v.field_id, v.value || ""]));
result.caseFields = (defs || []).map((d: any) => ({
key: d.key,
label: d.label,
value: valMap.get(d.id) || "",
}));
}
return result;
}
function fmtAddress(o: any): string {
if (!o) return "";
const parts = [
o.address_line1,
o.address_line2,
[o.city, o.state, o.postal_code].filter(Boolean).join(", "),
].filter(Boolean);
return parts.join("\n");
}
export function buildVarMap(ctx: LoadedContext): VarMap {
const m: VarMap = {};
const c = ctx.client;
if (c) {
m["client.name"] = c.name || "";
m["clientName"] = c.name || "";
m["client.address"] = fmtAddress(c);
m["clientAddress"] = fmtAddress(c);
m["client.address_line1"] = c.address_line1 || "";
m["clientAddressLine1"] = c.address_line1 || "";
m["client.address_line2"] = c.address_line2 || "";
m["clientAddressLine2"] = c.address_line2 || "";
m["client.city"] = c.city || "";
m["client.state"] = c.state || "";
m["client.postal_code"] = c.postal_code || "";
m["client.contact_name"] = c.primary_contact_name || "";
m["clientContactName"] = c.primary_contact_name || "";
m["client.contact_email"] = c.primary_contact_email || "";
m["clientContactEmail"] = c.primary_contact_email || "";
m["client.contact_phone"] = c.primary_contact_phone || "";
m["clientContactPhone"] = c.primary_contact_phone || "";
m["client.management_company"] = c.management_company || "";
m["managementCompany"] = c.management_company || "";
}
const k = ctx.cases;
if (k) {
m["case.number"] = k.case_number || "";
m["caseNumber"] = k.case_number || "";
m["case.title"] = k.title || "";
m["caseTitle"] = k.title || "";
m["case.caption"] = k.case_caption || "";
m["caseCaption"] = k.case_caption || "";
m["case.court"] = k.court || "";
m["court"] = k.court || "";
m["case.court_case_number"] = k.court_case_number || "";
m["courtCaseNumber"] = k.court_case_number || "";
m["case.judge"] = k.judge || "";
m["judge"] = k.judge || "";
m["case.jurisdiction"] = k.jurisdiction || "";
m["jurisdiction"] = k.jurisdiction || "";
m["case.opposing_party"] = k.opposing_party || "";
m["opposingParty"] = k.opposing_party || "";
m["case.opposing_counsel"] = k.opposing_counsel || "";
m["opposingCounsel"] = k.opposing_counsel || "";
m["case.opposing_counsel_firm"] = k.opposing_counsel_firm || "";
m["opposingCounselFirm"] = k.opposing_counsel_firm || "";
m["case.opposing_counsel_email"] = k.opposing_counsel_email || "";
m["opposingCounselEmail"] = k.opposing_counsel_email || "";
m["case.opposing_counsel_phone"] = k.opposing_counsel_phone || "";
m["opposingCounselPhone"] = k.opposing_counsel_phone || "";
m["case.filing_date"] = k.filing_date || "";
m["filingDate"] = k.filing_date || "";
m["case.next_hearing_date"] = k.next_hearing_date || "";
m["nextHearingDate"] = k.next_hearing_date || "";
}
ctx.clientFields.forEach((f) => {
m[`client.field.${f.key}`] = f.value;
m[`client.custom.${f.key}`] = f.value;
});
ctx.caseFields.forEach((f) => {
m[`case.field.${f.key}`] = f.value;
m[`case.custom.${f.key}`] = f.value;
m[`custom.${f.key}`] = f.value;
});
return m;
}
export function buildChips(ctx: LoadedContext): VarChip[] {
const m = buildVarMap(ctx);
const out: VarChip[] = [];
const labelMap: Record<string, string> = {
"client.name": "Client name",
clientName: "Client name",
"client.address": "Client address (full)",
clientAddress: "Client address (full)",
"client.contact_name": "Client primary contact",
clientContactName: "Client primary contact",
"client.contact_email": "Client contact email",
clientContactEmail: "Client contact email",
"client.contact_phone": "Client contact phone",
clientContactPhone: "Client contact phone",
"client.management_company": "Management company",
managementCompany: "Management company",
"case.number": "Case number",
caseNumber: "Case number",
"case.title": "Case title",
caseTitle: "Case title",
"case.caption": "Case caption",
caseCaption: "Case caption",
"case.court": "Court",
court: "Court",
"case.court_case_number": "Court case number",
courtCaseNumber: "Court case number",
"case.judge": "Judge",
judge: "Judge",
"case.opposing_party": "Opposing party",
opposingParty: "Opposing party",
"case.opposing_counsel": "Opposing counsel",
opposingCounsel: "Opposing counsel",
"case.opposing_counsel_firm": "Opposing counsel firm",
opposingCounselFirm: "Opposing counsel firm",
"case.filing_date": "Filing date",
filingDate: "Filing date",
"case.next_hearing_date": "Next hearing date",
nextHearingDate: "Next hearing date",
};
for (const key of Object.keys(m)) {
let label = labelMap[key];
if (!label) {
if (key.startsWith("client.field.")) label = `Client · ${key.replace("client.field.", "")}`;
else if (key.startsWith("client.custom.")) label = `Client · ${key.replace("client.custom.", "")}`;
else if (key.startsWith("case.field.")) label = `Case · ${key.replace("case.field.", "")}`;
else if (key.startsWith("case.custom.")) label = `Case · ${key.replace("case.custom.", "")}`;
else if (key.startsWith("custom.")) label = `Case · ${key.replace("custom.", "")}`;
else label = key;
}
out.push({ token: `{{${key}}}`, label, value: m[key] });
}
return out;
}
const TOKEN_RE = /\{\{\s*([a-zA-Z0-9_.]+)\s*\}\}/g;
export function applyVars(text: string, map: VarMap): string {
if (!text) return text;
return text.replace(TOKEN_RE, (_, key) => (key in map ? map[key] : `{{${key}}}`));
}
export function applyVarsToHtml(html: string, map: VarMap): string {
return applyVars(html, map);
}