${c.status}
`).join('');
// Chart
const chartLabels = Object.keys(typeCounts);
const chartData = Object.values(typeCounts);
if (typeChart) {
typeChart.data.labels = chartLabels;
typeChart.data.datasets[0].data = chartData;
typeChart.update();
} else {
const ctx = document.getElementById('typeChart').getContext('2d');
typeChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: chartLabels,
datasets: [{
data: chartData,
backgroundColor: ['#ef4444', '#f59e0b', '#22c55e', '#3b82f6', '#6366f1'],
borderColor: '#f9fafb',
borderWidth: 4,
}]
},
options: { responsive: true, plugins: { legend: { position: 'bottom', labels: { boxWidth: 12 } } } }
});
}
}
// --- TAB NAVIGATION ---
function updateTabDisplay(tabNum) {
tabButtons.forEach(button => button.classList.toggle('active', parseInt(button.dataset.tab) === tabNum));
tabContents.forEach(content => content.style.display = 'none');
document.getElementById(`tab-content-${tabNum}`).style.display = 'block';
if (tabNum === 1) updateDashboard();
if (tabNum === 2) renderCasesTable();
}
// --- MODAL LOGIC ---
const modal = document.getElementById('edit-modal');
const modalContainer = modal.querySelector('.modal-container');
function openModal(caseId) {
const caseItem = DB.find(c => c.id === caseId);
if (!caseItem) return;
document.getElementById('modal-title').textContent = `Case Details - ID: ${caseItem.id}`;
document.getElementById('edit-case-id').value = caseItem.id;
document.getElementById('edit-incident-date').value = caseItem.date;
document.getElementById('edit-incident-type').value = caseItem.type;
document.getElementById('edit-incident-description').value = caseItem.description;
document.getElementById('edit-involved-parties').value = caseItem.parties;
document.getElementById('investigation-notes').value = caseItem.notes || '';
document.getElementById('edit-priority').value = caseItem.priority || 'Medium';
const statusSelect = document.getElementById('edit-status');
statusSelect.innerHTML = `
`;
modal.classList.remove('hidden');
setTimeout(() => {
modal.classList.remove('opacity-0');
modalContainer.classList.remove('scale-95');
}, 10);
}
function closeModal() {
modal.classList.add('opacity-0');
modalContainer.classList.add('scale-95');
setTimeout(() => modal.classList.add('hidden'), 300);
}
// --- PDF GENERATION ---
function generatePdfHtml(caseId) {
const caseItem = DB.find(c => c.id === caseId);
if(!caseItem) return '';
return `
Whistleblower Incident Report
Case ID:${caseItem.id}
Date Reported:${caseItem.date}
Status:${caseItem.status.toUpperCase()}
Incident Details
Type of Misconduct:${caseItem.type}
Involved Parties:${caseItem.parties || 'N/A'}
Description:
${caseItem.description.replace(/\n/g, '
')}
')}
Investigation & Resolution
Notes & Actions:
${(caseItem.notes || 'No notes entered.').replace(/\n/g, '
')}
')}
This document contains confidential information. Generated on ${new Date().toLocaleDateString('en-US')}.
`; } async function handlePdfDownload() { const caseId = parseInt(document.getElementById('edit-case-id').value); if (!caseId) return; document.getElementById('pdf-content').innerHTML = generatePdfHtml(caseId); const { jsPDF } = window.jspdf; const button = document.getElementById('downloadPdfBtn'); button.textContent = 'Generating...'; button.disabled = true; const pdfContainer = document.getElementById('pdf-container'); try { const canvas = await html2canvas(pdfContainer, { scale: 2 }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const imgProps = pdf.getImageProperties(imgData); const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width; pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight); pdf.save(`Incident_Report_${caseId}.pdf`); } catch (error) { console.error("PDF generation failed:", error); } finally { button.textContent = 'Download Report (PDF)'; button.disabled = false; } } // --- EVENT LISTENERS --- tabButtons.forEach(button => { button.addEventListener('click', () => updateTabDisplay(parseInt(button.dataset.tab))); }); document.getElementById('new-incident-form').addEventListener('submit', function(e) { e.preventDefault(); const newCase = { id: new Date().getFullYear() * 100 + (DB.length + 1), date: document.getElementById('incident-date').value, type: document.getElementById('incident-type').value, description: document.getElementById('incident-description').value, parties: document.getElementById('involved-parties').value, status: 'open', priority: 'Medium', notes: '' }; DB.push(newCase); this.reset(); updateTabDisplay(2); // Switch to case management view }); document.getElementById('cases-table-body').addEventListener('click', function(e) { if (e.target.classList.contains('view-details-btn')) { const caseId = parseInt(e.target.dataset.id); openModal(caseId); } }); document.getElementById('close-modal-btn').addEventListener('click', closeModal); modal.addEventListener('click', function(e) { if (e.target === this) closeModal(); }); document.getElementById('save-changes-btn').addEventListener('click', function() { const caseId = parseInt(document.getElementById('edit-case-id').value); const caseItem = DB.find(c => c.id === caseId); if (caseItem) { caseItem.status = document.getElementById('edit-status').value; caseItem.priority = document.getElementById('edit-priority').value; caseItem.notes = document.getElementById('investigation-notes').value; } closeModal(); if (document.getElementById('tab-content-2').style.display === 'block') { renderCasesTable(); } }); document.getElementById('downloadPdfBtn').addEventListener('click', handlePdfDownload); // --- INITIALIZATION --- updateDashboard(); });