Flagged Event Log
| Timestamp | User | Amount | Device | Location | Reason |
${flaggedRows || `| No suspicious events found. |
`}
`;
const ctx = getElem('alertChart').getContext('2d');
if (alertChart) alertChart.destroy();
alertChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Object.keys(currentData.flagCounts),
datasets: [{
label: '# of Flags',
data: Object.values(currentData.flagCounts),
backgroundColor: ['#EF4444', '#F59E0B', '#3B82F6'],
}]
},
options: { responsive: true, maintainAspectRatio: false }
});
downloadSection.classList.remove('hidden');
showTab(1);
};
runValidationBtn.addEventListener('click', runValidation);
// --- PDF DOWNLOAD ---
const downloadPDF = () => {
if (!currentData) return;
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' });
const btnText = getElem('pdf-btn-text');
const btnSpinner = getElem('pdf-btn-spinner');
btnText.classList.add('hidden');
btnSpinner.classList.remove('hidden');
downloadPdfBtn.disabled = true;
try {
const pageWidth = pdf.internal.pageSize.getWidth();
const margin = 40;
let y = margin;
pdf.setFont('helvetica', 'bold');
pdf.setFontSize(22);
pdf.text("Security Validation Report", pageWidth / 2, y, { align: 'center' });
y += 15;
pdf.setFont('helvetica', 'normal');
pdf.setFontSize(10);
pdf.text(`Report Date: ${new Date().toLocaleDateString('en-US')}`, pageWidth / 2, y, { align: 'center' });
y += 35;
pdf.autoTable({
startY: y,
theme: 'grid',
head: [['Metric', 'Value']],
body: [
['Total Events Analyzed', `${currentData.events.length}`],
['Total Suspicious Events Flagged', { content: `${currentData.totalFlagged}`, styles: {textColor: '#DC2626', fontStyle: 'bold'} }],
['Total Value at Risk', `$${currentData.totalValueAtRisk.toLocaleString('en-US')}`],
],
didDrawPage: (data) => { y = data.cursor.y; }
});
y += 20;
pdf.setFont('helvetica', 'bold');
pdf.text("Flagged Event Details", margin, y);
y += 15;
const tableData = currentData.flagged.map(f => [
f.timestamp.toLocaleString('en-US', { timeZone: 'UTC' }),
f.user,
`$${f.amount.toFixed(2)}`,
f.device,
f.location,
f.reasons.join(', ')
]);
pdf.autoTable({
startY: y,
head: [['Timestamp (UTC)', 'User ID', 'Amount', 'Device', 'Location', 'Reason']],
body: tableData,
theme: 'striped',
headStyles: { fillColor: [220, 38, 38] }, // red-600
});
pdf.save(`Security-Validation-Report.pdf`);
} catch(e) { console.error("PDF Generation failed:", e); }
finally {
btnText.classList.remove('hidden');
btnSpinner.classList.remove('hidden');
downloadPdfBtn.disabled = false;
}
};
downloadPdfBtn.addEventListener('click', downloadPDF);
initialize();
});