Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
194 lines
7.4 KiB
TypeScript
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);
|
|
}
|