Add tasks in Tab 2 to generate the dashboard.
`;
downloadBtnContainer.classList.add('hidden');
return;
}
const statusCounts = complianceTasks.reduce((acc, task) => {
acc[task.status] = (acc[task.status] || 0) + 1;
return acc;
}, {});
const notStarted = statusCounts['Not Started'] || 0;
const inProgress = statusCounts['In Progress'] || 0;
const completed = statusCounts['Completed'] || 0;
const totalTasks = complianceTasks.length;
const completionRate = totalTasks > 0 ? ((completed / totalTasks) * 100).toFixed(0) : 0;
const dashboardHtml = `
TOTAL TASKS
${totalTasks}
PENDING
${notStarted + inProgress}
Task List Summary
${complianceTasks.map(t => `
${t.name}
${t.status}
`).join('')}
Task Status Overview
`;
dashboardContainer.innerHTML = dashboardHtml;
downloadBtnContainer.classList.remove('hidden');
const ctx = document.getElementById('statusChart').getContext('2d');
if (myChart) myChart.destroy();
myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Completed', 'In Progress', 'Not Started'],
datasets: [{
data: [completed, inProgress, notStarted],
backgroundColor: ['#10b981', '#f59e0b', '#d1d5db'],
}]
},
options: { responsive: true, plugins: { legend: { position: 'bottom' } } }
});
};
// --- UI & NAVIGATION ---
const updateNavButtons = () => {
prevBtn.disabled = currentTab === '1';
nextBtn.disabled = currentTab === '3';
prevBtn.classList.toggle('opacity-50', prevBtn.disabled);
nextBtn.classList.toggle('opacity-50', nextBtn.disabled);
};
window.switchTab = (tabId) => {
currentTab = tabId;
if (currentTab === '3') {
renderDashboard();
}
tabs.forEach(id => {
document.getElementById(`tab-content-${id}`).classList.toggle('hidden', id !== currentTab);
document.getElementById(`tab-btn-${id}`).classList.toggle('tab-active', id === currentTab);
document.getElementById(`tab-btn-${id}`).classList.toggle('tab-inactive', id !== currentTab);
});
updateNavButtons();
};
const navigateTabs = (direction) => {
const currentIndex = tabs.indexOf(currentTab);
let nextIndex = currentIndex + direction;
if (nextIndex >= 0 && nextIndex < tabs.length) {
switchTab(tabs[nextIndex]);
}
};
// --- PDF GENERATION ---
downloadPdfBtn.addEventListener('click', () => {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
const contractName = document.getElementById('contractName').value || 'N/A';
const counterparty = document.getElementById('counterparty').value || 'N/A';
const effectiveDate = document.getElementById('effectiveDate').value || 'N/A';
const termDate = document.getElementById('terminationDate').value || 'N/A';
doc.setFontSize(18);
doc.text("Contract Compliance Report", 14, 22);
doc.setFontSize(11);
doc.setTextColor(100);
doc.text(`Report Date: ${new Date().toLocaleDateString()}`, 14, 30);
doc.autoTable({
startY: 40,
body: [
['Contract Name', contractName],
['Counterparty', counterparty],
['Effective Date', effectiveDate],
['Termination Date', termDate],
],
theme: 'striped',
styles: { cellPadding: 2 },
});
const taskData = complianceTasks.map(t => [t.name, t.dueDate, t.status]);
doc.autoTable({
head: [['Task Description', 'Due Date', 'Status']],
body: taskData,
startY: doc.previousAutoTable.finalY + 10,
theme: 'grid',
headStyles: { fillColor: [45, 102, 193] },
});
doc.save(`Compliance_Report_${contractName.replace(/\s/g, '_')}.pdf`);
});
// --- INITIALIZATION ---
updateNavButtons();
lucide.createIcons();
addTaskBtn.addEventListener('click', handleAddTask);
prevBtn.addEventListener('click', () => navigateTabs(-1));
nextBtn.addEventListener('click', () => navigateTabs(1));
});