`;
}
function renderChart() {
const ctx = document.getElementById('complianceChart').getContext('2d');
const compliant = complianceItems.filter(i => i.status === 'Compliant').length;
const inProgress = complianceItems.filter(i => i.status === 'In Progress').length;
const nonCompliant = complianceItems.filter(i => i.status === 'Non-Compliant').length;
if (complianceChartInstance) {
complianceChartInstance.destroy();
}
complianceChartInstance = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Compliant', 'In Progress', 'Non-Compliant'],
datasets: [{
data: [compliant, inProgress, nonCompliant],
backgroundColor: ['#22c55e', '#f59e0b', '#ef4444'],
hoverOffset: 4
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
plugins: {
legend: { position: 'bottom' }
}
}
});
}
window.prepareNewItem = () => {
document.getElementById('item-form-title').textContent = 'Add New Compliance Item';
itemForm.reset();
document.getElementById('editingItemId').value = '';
showTab(1);
};
window.editItem = (id) => {
const item = complianceItems.find(i => i.id === id);
if (item) {
document.getElementById('item-form-title').textContent = 'Edit Compliance Item';
document.getElementById('editingItemId').value = item.id;
document.getElementById('complianceArea').value = item.area;
document.getElementById('complianceRequirement').value = item.requirement;
document.getElementById('complianceStatus').value = item.status;
document.getElementById('reviewDate').value = item.reviewDate;
document.getElementById('itemOwner').value = item.owner;
showTab(1);
}
};
window.deleteItem = (id) => {
if (confirm('Are you sure you want to delete this compliance item?')) {
complianceItems = complianceItems.filter(i => i.id !== id);
renderDashboard();
}
};
itemForm.addEventListener('submit', (e) => {
e.preventDefault();
const editingId = document.getElementById('editingItemId').value;
const itemData = {
area: document.getElementById('complianceArea').value,
requirement: document.getElementById('complianceRequirement').value,
status: document.getElementById('complianceStatus').value,
reviewDate: document.getElementById('reviewDate').value,
owner: document.getElementById('itemOwner').value
};
if (editingId) {
const index = complianceItems.findIndex(i => i.id === parseInt(editingId));
complianceItems[index] = { ...complianceItems[index], ...itemData };
} else {
const newId = complianceItems.length > 0 ? Math.max(...complianceItems.map(i => i.id)) + 1 : 1;
complianceItems.push({ id: newId, ...itemData });
}
renderDashboard();
showTab(0);
});
function renderReport() {
const container = document.getElementById('report-output-container');
const today = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
let reportHTML = `
`;
container.innerHTML = reportHTML;
}
async function downloadPdf() {
const pdfLoader = document.getElementById('pdf-loader');
const downloadBtn = document.getElementById('downloadPdfBtn');
const content = document.getElementById('pdf-content');
if(!content) return;
pdfLoader.classList.remove('hidden');
downloadBtn.disabled = true;
try {
const canvas = await html2canvas(content, { scale: 2 });
const imgData = canvas.toDataURL('image/png');
const { jsPDF } = window.jspdf;
const pdf = new jsPDF('p', 'pt', 'letter');
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const margin = 40;
const imgProps = pdf.getImageProperties(imgData);
const imgWidth = pdfWidth - margin * 2;
const imgHeight = (imgProps.height * imgWidth) / imgProps.width;
let heightLeft = imgHeight;
let position = margin;
pdf.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight);
heightLeft -= (pdfHeight - margin * 2);
while (heightLeft > 0) {
position -= (pdfHeight - margin);
pdf.addPage();
pdf.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight);
heightLeft -= pdfHeight;
}
pdf.save('Compliance-Report.pdf');
} catch(error) {
console.error("PDF Generation Error:", error);
alert("There was an error generating the PDF.");
} finally {
pdfLoader.classList.add('hidden');
downloadBtn.disabled = false;
}
}
document.getElementById('downloadPdfBtn').addEventListener('click', downloadPdf);
// Initial setup
showTab(0);
renderDashboard();
lucide.createIcons();
});
Compliance Status Report
Generated on ${today}
`;
const areas = [...new Set(complianceItems.map(item => item.area))];
areas.forEach(area => {
reportHTML += `
Requirement
${item.requirement}
Status
${item.status}
Next Review / Due Date
${item.reviewDate}
Owner
${item.owner}
`;
});
});
reportHTML += `
