Whistleblower Incident Management System

Whistleblower Incident Management System

A confidential system to log, track, and resolve whistleblower reports.

Open Cases

0

Investigating

0

Resolved Cases

0

Incidents by Type

Recently Updated Cases

No recent activity.

All Incidents

Case ID Date Reported Type of Misconduct Status Actions

Log a New Whistleblower Incident

Reported: ${c.date}

${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(); });
Scroll to Top