Release (Stable version)
This commit is contained in:
163
features/contracts/utils/export.utils.ts
Normal file
163
features/contracts/utils/export.utils.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
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`);
|
||||
};
|
||||
Reference in New Issue
Block a user