164 lines
4.9 KiB
TypeScript
164 lines
4.9 KiB
TypeScript
import jsPDF from "jspdf";
|
|
import autoTable from "jspdf-autotable";
|
|
import { type Contract, type Prisma } from "@prisma/client";
|
|
|
|
interface ContractKeyPoints {
|
|
guarantees?: string[];
|
|
exclusions?: string[];
|
|
franchise?: string | number | null;
|
|
[key: string]: any;
|
|
}
|
|
|
|
export const isContractKeyPoints = (
|
|
val: Prisma.JsonValue | null | undefined,
|
|
): val is ContractKeyPoints => {
|
|
if (!val || typeof val !== "object" || Array.isArray(val)) return false;
|
|
return true;
|
|
};
|
|
|
|
export const stripMarkdown = (text: string | null | undefined): string => {
|
|
if (!text) return "";
|
|
// Strip ** bold tags, __ italic tags, # headers, • bullets
|
|
return text
|
|
.replace(/\*\*/g, "")
|
|
.replace(/__/g, "")
|
|
.replace(/^#+\s+/gm, "")
|
|
.replace(/•\s+/g, "- ")
|
|
// replace any remaining markdown stars
|
|
.replace(/\*/g, "");
|
|
};
|
|
|
|
const formatValue = (val: any): string => {
|
|
if (val === null || val === undefined) return "N/A";
|
|
if (val instanceof Date) return val.toLocaleDateString();
|
|
if (Array.isArray(val)) {
|
|
return val.map((v) => stripMarkdown(String(v))).join("\n");
|
|
}
|
|
return stripMarkdown(String(val));
|
|
};
|
|
|
|
export const exportToCSV = (contract: Contract) => {
|
|
let guarantees = "N/A";
|
|
let exclusions = "N/A";
|
|
let franchise = "N/A";
|
|
|
|
if (isContractKeyPoints(contract.keyPoints)) {
|
|
if (Array.isArray(contract.keyPoints.guarantees)) {
|
|
guarantees = contract.keyPoints.guarantees.map(stripMarkdown).join("; ");
|
|
}
|
|
if (Array.isArray(contract.keyPoints.exclusions)) {
|
|
exclusions = contract.keyPoints.exclusions.map(stripMarkdown).join("; ");
|
|
}
|
|
if (contract.keyPoints.franchise) {
|
|
franchise = stripMarkdown(String(contract.keyPoints.franchise));
|
|
}
|
|
}
|
|
|
|
const exportData = [
|
|
["Field", "Value"],
|
|
["Title", formatValue(contract.title)],
|
|
["Provider", formatValue(contract.provider)],
|
|
["Policy Number", formatValue(contract.policyNumber)],
|
|
["Start Date", formatValue(contract.startDate)],
|
|
["End Date", formatValue(contract.endDate)],
|
|
["Status", formatValue(contract.status)],
|
|
["Summary", formatValue(contract.summary).replace(/\n/g, " ")],
|
|
["Guarantees", guarantees],
|
|
["Exclusions", exclusions],
|
|
["Deductible", franchise],
|
|
];
|
|
|
|
const csvContent = exportData
|
|
.map((row) =>
|
|
row
|
|
.map((cell) => {
|
|
const stringCell = String(cell);
|
|
if (stringCell.includes(",") || stringCell.includes("\"") || stringCell.includes("\n")) {
|
|
return `"${stringCell.replace(/"/g, "\"\"")}"`;
|
|
}
|
|
return stringCell;
|
|
})
|
|
.join(","),
|
|
)
|
|
.join("\n");
|
|
|
|
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
const downloadUrl = URL.createObjectURL(blob);
|
|
const link = document.createElement("a");
|
|
link.href = downloadUrl;
|
|
link.download = `Analysis_${contract.fileName || "Contract"}.csv`;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
URL.revokeObjectURL(downloadUrl);
|
|
};
|
|
|
|
export const exportToPDF = (contract: Contract) => {
|
|
const doc = new jsPDF();
|
|
|
|
// Title
|
|
doc.setFontSize(18);
|
|
doc.setTextColor(33, 43, 54);
|
|
doc.text("AI Contract Analysis", 14, 22);
|
|
|
|
// Subtitle
|
|
doc.setFontSize(11);
|
|
doc.setTextColor(100);
|
|
doc.text(`Filename: ${contract.fileName}`, 14, 30);
|
|
doc.text(`Exported: ${new Date().toLocaleDateString()}`, 14, 36);
|
|
|
|
let guarantees = "N/A";
|
|
let exclusions = "N/A";
|
|
let franchise = "N/A";
|
|
|
|
if (isContractKeyPoints(contract.keyPoints)) {
|
|
if (Array.isArray(contract.keyPoints.guarantees)) {
|
|
guarantees = contract.keyPoints.guarantees.map(stripMarkdown).join("\n• ");
|
|
if (guarantees) guarantees = "• " + guarantees;
|
|
}
|
|
if (Array.isArray(contract.keyPoints.exclusions)) {
|
|
exclusions = contract.keyPoints.exclusions.map(stripMarkdown).join("\n• ");
|
|
if (exclusions) exclusions = "• " + exclusions;
|
|
}
|
|
if (contract.keyPoints.franchise) {
|
|
franchise = stripMarkdown(String(contract.keyPoints.franchise));
|
|
}
|
|
}
|
|
|
|
const tableData = [
|
|
["Title", formatValue(contract.title)],
|
|
["Provider", formatValue(contract.provider)],
|
|
["Policy Number", formatValue(contract.policyNumber)],
|
|
["Start Date", formatValue(contract.startDate)],
|
|
["End Date", formatValue(contract.endDate)],
|
|
["Summary", formatValue(contract.summary)],
|
|
["Guarantees", guarantees],
|
|
["Exclusions", exclusions],
|
|
["Deductible", franchise],
|
|
];
|
|
|
|
autoTable(doc, {
|
|
startY: 45,
|
|
head: [["Information Field", "Extracted Detail"]],
|
|
body: tableData,
|
|
theme: "grid",
|
|
headStyles: {
|
|
fillColor: [30, 41, 59],
|
|
textColor: 255,
|
|
fontStyle: "bold",
|
|
},
|
|
styles: {
|
|
fontSize: 10,
|
|
cellPadding: 6,
|
|
overflow: "linebreak",
|
|
cellWidth: "wrap"
|
|
},
|
|
columnStyles: {
|
|
0: { cellWidth: 40, fontStyle: "bold", textColor: [50, 50, 50] },
|
|
1: { cellWidth: 140 }
|
|
},
|
|
});
|
|
|
|
doc.save(`Analysis_${contract.fileName || "Contract"}.pdf`);
|
|
};
|