Legal Risk Assessment Tool

${risk.mitigation || 'N/A'}

`; riskRegisterList.appendChild(card); }); }; const renderConfigList = () => { configRiskList.innerHTML = ''; if (risks.length === 0) { configRiskList.innerHTML = `
No risks to configure.
`; return; } risks.forEach(risk => { const item = document.createElement('div'); item.className = 'p-3 border rounded-md bg-white flex justify-between items-center'; item.innerHTML = `

${risk.description}

L: ${risk.likelihood}, I: ${risk.impact}

`; configRiskList.appendChild(item); }); }; // --- UI & TAB LOGIC --- const updateTabUI = () => { tabs.forEach(tab => tab.classList.toggle('active', tab.dataset.tab === currentTab)); tabContents.forEach(content => { if (content.id === `tab-${currentTab}`) { content.classList.add('active', 'fade-in'); } else { content.classList.remove('active', 'fade-in'); } }); const currentIndex = tabOrder.indexOf(currentTab); prevBtn.disabled = currentIndex === 0; nextBtn.disabled = currentIndex === tabOrder.length - 1; // Render content when tab is shown if (currentTab === 'dashboard') renderRiskMatrix(); if (currentTab === 'register') renderRiskRegister(); if (currentTab === 'config') renderConfigList(); }; const changeTab = (direction) => { const currentIndex = tabOrder.indexOf(currentTab); const newIndex = currentIndex + direction; if (newIndex >= 0 && newIndex < tabOrder.length) { currentTab = tabOrder[newIndex]; updateTabUI(); } }; // --- EVENT LISTENERS --- tabs.forEach(tab => tab.addEventListener('click', () => { currentTab = tab.dataset.tab; updateTabUI(); })); prevBtn.addEventListener('click', () => changeTab(-1)); nextBtn.addEventListener('click', () => changeTab(1)); riskForm.addEventListener('submit', (e) => { e.preventDefault(); const id = document.getElementById('risk-id').value; const newRisk = { id: id ? parseInt(id) : Date.now(), description: document.getElementById('risk-description').value, category: document.getElementById('risk-category').value, likelihood: parseInt(document.getElementById('risk-likelihood').value), impact: parseInt(document.getElementById('risk-impact').value), mitigation: document.getElementById('risk-mitigation').value, }; if (id) { // Editing risks = risks.map(r => r.id === newRisk.id ? newRisk : r); } else { // Adding risks.push(newRisk); } resetForm(); renderConfigList(); }); cancelEditBtn.addEventListener('click', resetForm); configRiskList.addEventListener('click', (e) => { const target = e.target; const id = parseInt(target.dataset.id); if (target.classList.contains('edit-btn')) { const riskToEdit = risks.find(r => r.id === id); if (riskToEdit) populateForm(riskToEdit); } if (target.classList.contains('delete-btn')) { risks = risks.filter(r => r.id !== id); renderConfigList(); } }); // --- FORM & DATA HANDLING --- function populateForm(risk) { formTitle.textContent = 'Edit Risk'; document.getElementById('risk-id').value = risk.id; document.getElementById('risk-description').value = risk.description; document.getElementById('risk-category').value = risk.category; document.getElementById('risk-likelihood').value = risk.likelihood; document.getElementById('risk-impact').value = risk.impact; document.getElementById('risk-mitigation').value = risk.mitigation; cancelEditBtn.classList.remove('hidden'); } function resetForm() { formTitle.textContent = 'Add New Risk'; riskForm.reset(); document.getElementById('risk-id').value = ''; cancelEditBtn.classList.add('hidden'); } // --- PDF DOWNLOAD --- downloadPdfBtn.addEventListener('click', () => { if (typeof window.jspdf === 'undefined') { console.error('PDF generation library (jsPDF) is not available.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF({ unit: 'pt', format: 'a4' }); if (typeof doc.autoTable === 'undefined') { console.error('The PDF autotable plugin is not available. PDF cannot be generated.'); return; } // Header doc.setFont('helvetica', 'bold'); doc.setFontSize(22); doc.setTextColor('#1e293b'); doc.text('Legal Risk Assessment Report', doc.internal.pageSize.getWidth() / 2, 60, { align: 'center' }); // Risk Matrix Drawing doc.setFont('helvetica', 'bold'); doc.setFontSize(16); doc.text('Risk Matrix', 40, 120); const matrixX = 40, matrixY = 140, matrixSize = 250, cellSize = matrixSize / 5; // Draw cells and colors for (let row = 0; row < 5; row++) { for (let col = 0; col < 5; col++) { const likelihood = 5 - row; const impact = col + 1; doc.setFillColor(getRiskColorHex(likelihood, impact).substring(1)); // Remove # doc.rect(matrixX + col * cellSize, matrixY + row * cellSize, cellSize, cellSize, 'F'); } } // Draw risk dots doc.setFont('helvetica', 'bold'); doc.setFontSize(8); risks.forEach((risk, index) => { const x = matrixX + (risk.impact - 0.5) * cellSize; const y = matrixY + (5.5 - risk.likelihood) * cellSize; doc.setFillColor(255, 255, 255); doc.circle(x, y, 7, 'F'); doc.setFillColor(0, 0, 0); doc.circle(x, y, 6, 'F'); doc.setTextColor(255, 255, 255); doc.text(String(index + 1), x, y, { align: 'center', baseline: 'middle' }); }); // Risk Register Table const tableData = risks.map((risk, index) => [ `#${index + 1}`, risk.description, risk.category, `${risk.likelihood} (L) x ${risk.impact} (I) = ${risk.likelihood * risk.impact}`, risk.mitigation ]); doc.autoTable({ head: [['ID', 'Description', 'Category', 'Score', 'Mitigation']], body: tableData, startY: matrixY + matrixSize + 40, theme: 'grid', headStyles: { fillColor: '#f1f5f9', textColor: '#334155', fontStyle: 'bold' }, styles: { cellPadding: 5, fontSize: 9, font: 'helvetica' }, columnStyles: { 0: { cellWidth: 30 }, 1: { cellWidth: 150 }, 2: { cellWidth: 80 }, 3: { cellWidth: 80 }, 4: { cellWidth: 'auto' } } }); doc.save('Legal-Risk-Assessment-Report.pdf'); }); // --- INITIALIZATION --- updateTabUI(); });
Scroll to Top