No compliance tasks added yet.
';
return;
}
taskListContainer.innerHTML = ''; // Clear existing tasks
const header = `
Task
Due Date
Status
Actions
`;
taskListContainer.innerHTML += header;
complianceTasks.forEach(task => {
const taskRow = document.createElement('div');
taskRow.className = 'task-row grid grid-cols-6 gap-4 items-center px-4 py-3 border-b';
taskRow.innerHTML = `
${task.name}
${task.dueDate || 'N/A'}
`;
taskListContainer.appendChild(taskRow);
});
lucide.createIcons();
};
const handleAddTask = () => {
const taskNameInput = document.getElementById('taskName');
const taskDueDateInput = document.getElementById('taskDueDate');
const name = taskNameInput.value.trim();
if (!name) {
alert('Please enter a task description.'); // Replace with modal in real app
return;
}
complianceTasks.push({
id: taskIdCounter++,
name: name,
dueDate: taskDueDateInput.value,
status: 'Not Started'
});
taskNameInput.value = '';
taskDueDateInput.value = '';
renderTasks();
};
const updateTaskStatus = (id, newStatus) => {
const task = complianceTasks.find(t => t.id === id);
if (task) {
task.status = newStatus;
}
};
const deleteTask = (id) => {
complianceTasks = complianceTasks.filter(t => t.id !== id);
renderTasks();
};
taskListContainer.addEventListener('change', e => {
if (e.target.classList.contains('status-select')) {
const taskId = parseInt(e.target.dataset.taskId);
updateTaskStatus(taskId, e.target.value);
}
});
taskListContainer.addEventListener('click', e => {
const deleteBtn = e.target.closest('.delete-task-btn');
if (deleteBtn) {
const taskId = parseInt(deleteBtn.dataset.taskId);
deleteTask(taskId);
}
});
// --- DASHBOARD RENDERING ---
const renderDashboard = () => {
if (complianceTasks.length === 0) {
dashboardContainer.innerHTML = `
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));
});