`;
const notificationContainer = document.getElementById('notification-summary');
notificationContainer.innerHTML = '';
if(breachData.jurisdictions.size === 0){
notificationContainer.innerHTML = `
`;
});
}
};
const renderBreachDetails = () => {
// Set initial values from state
document.getElementById('records-breached').value = breachData.records;
document.getElementById('records-breached-value').textContent = Number(breachData.records).toLocaleString('en-US');
document.getElementById('data-type').value = breachData.dataType;
document.getElementById('industry').value = breachData.industry;
document.getElementById('detection-time').value = breachData.detectionTime;
document.getElementById('detection-time-value').textContent = breachData.detectionTime;
};
const renderJurisdictions = () => {
const container = document.getElementById('jurisdictions-list');
container.innerHTML = Object.keys(stateLaws).map(state => `
`).join('');
};
const renderAll = () => {
renderDashboard();
renderBreachDetails();
renderJurisdictions();
};
// --- EVENT HANDLERS & LOGIC ---
window.updateBreachDetails = (key, value) => {
breachData[key] = (typeof breachData[key] === 'number') ? Number(value) : value;
renderDashboard(); // Recalculate and re-render the dashboard in real time
};
window.toggleJurisdiction = (state) => {
if (breachData.jurisdictions.has(state)) {
breachData.jurisdictions.delete(state);
} else {
breachData.jurisdictions.add(state);
}
renderDashboard(); // Update notification summary in real time
};
// --- TAB NAVIGATION ---
window.changeTab = (tabIndex) => {
currentTab = tabIndex;
const tabs = document.querySelectorAll('.tab');
const tabContents = document.querySelectorAll('.tab-content');
tabs.forEach((tab, i) => {
tab.classList.toggle('tab-active', i === tabIndex);
tab.classList.toggle('tab-inactive', i !== tabIndex);
});
tabContents.forEach((content, i) => {
content.style.display = i === tabIndex ? 'block' : 'none';
});
};
window.navigateTab = (direction) => {
const numTabs = document.querySelectorAll('.tab').length;
let newTab = currentTab + direction;
if (newTab < 0) newTab = 0;
if (newTab >= numTabs) newTab = numTabs - 1;
changeTab(newTab);
};
// --- PDF DOWNLOAD FUNCTIONALITY ---
window.downloadPDF = () => {
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' });
const costs = calculateCosts();
const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0 });
// Header
doc.setFontSize(18);
doc.setFont(undefined, 'bold');
doc.text('Data Breach Consequence Report', 105, 22, { align: 'center' });
doc.setFontSize(11);
doc.setFont(undefined, 'normal');
doc.setTextColor(100);
doc.text(`Generated: ${new Date().toLocaleDateString('en-US')}`, 105, 28, { align: 'center' });
// Breach Summary
doc.autoTable({
startY: 35,
body: [
['Records Breached', Number(breachData.records).toLocaleString('en-US')],
['Data Type', breachData.dataType],
['Industry', breachData.industry],
['Days to Detect', breachData.detectionTime],
],
theme: 'plain',
styles: { fontSize: 10, cellPadding: 1.5 },
columnStyles: { 0: { fontStyle: 'bold' } }
});
// Financial Impact
doc.setFontSize(14);
doc.setFont(undefined, 'bold');
doc.text('Estimated Financial Impact', 14, doc.autoTable.previous.finalY + 15);
const financialBody = [
['Total Estimated Cost', { content: formatter.format(costs.totalCost), styles: { fontStyle: 'bold' } }],
['Regulatory Fines & Penalties', formatter.format(costs.regulatoryFines)],
['IT & Forensic Investigation', formatter.format(costs.forensicCosts)],
['Post-Breach Response', formatter.format(costs.postBreachResponse)],
['Notification Costs', formatter.format(costs.notificationCosts)],
];
doc.autoTable({
startY: doc.autoTable.previous.finalY + 18,
head: [['Cost Category', 'Estimated Amount (USD)']],
body: financialBody,
theme: 'striped',
headStyles: { fillColor: [190, 18, 60] } // rose-700
});
// Notification Requirements
if(breachData.jurisdictions.size > 0){
doc.setFontSize(14);
doc.setFont(undefined, 'bold');
doc.text('Notification Requirements Summary', 14, doc.autoTable.previous.finalY + 15);
const notificationBody = Array.from(breachData.jurisdictions).map(state => {
const law = stateLaws[state];
return [state, law.deadline, `> ${law.agThreshold.toLocaleString('en-US')} residents`];
});
doc.autoTable({
startY: doc.autoTable.previous.finalY + 18,
head: [['State', 'Notification Deadline', 'AG Notification Threshold']],
body: notificationBody,
theme: 'grid',
headStyles: { fillColor: [29, 78, 216] } // blue-600
});
}
// Disclaimer Footer
const pageCount = doc.internal.getNumberOfPages();
for (let i = 1; i <= pageCount; i++) {
doc.setPage(i);
doc.setFontSize(8);
doc.setTextColor(150);
doc.text('This report contains estimates for informational purposes only and does not constitute legal or financial advice.', 105, 285, { align: 'center' });
}
doc.save('Data_Breach_Consequence_Report.pdf');
};
// --- INITIAL RENDER ---
renderAll();
changeTab(0);
});
No jurisdictions selected.
`; } else { breachData.jurisdictions.forEach(state => { const law = stateLaws[state]; notificationContainer.innerHTML += `${state}
Notification Deadline: ${law.deadline}
Attorney General must be notified if over ${law.agThreshold.toLocaleString('en-US')} residents are affected.
