Supplier Contract Compliance Audit Tool
Track and manage key compliance checkpoints for all your suppliers.
Add New Audit Item
Manage Existing Audit Items
No audit items configured. Add items in the 'Item Configuration' tab.
`; return; } const suppliers = auditItems.reduce((acc, item) => { acc[item.supplierName] = acc[item.supplierName] || []; acc[item.supplierName].push(item); return acc; }, {}); for (const supplierName in suppliers) { const items = suppliers[supplierName]; items.sort((a,b) => calculateDaysRemaining(a.nextReview) - calculateDaysRemaining(b.nextReview)); const supplierCard = document.createElement('div'); supplierCard.className = 'border rounded-lg shadow-sm bg-white'; let itemsHTML = items.map(item => { const daysRemaining = calculateDaysRemaining(item.nextReview); const urgency = getUrgency(daysRemaining); return `${supplierName}
| Checkpoint | Next Review | Status |
|---|
No items to manage.
`; return; } auditItems.forEach(item => { const itemEl = document.createElement('div'); itemEl.className = 'flex justify-between items-center p-3 bg-gray-50 rounded-md border'; itemEl.innerHTML = `${item.supplierName} / ${item.checkpoint}
`; configList.appendChild(itemEl); }); }; // --- TAB NAVIGATION --- const showTab = (tabIndex) => { tabs.forEach((tab, index) => tab.classList.toggle('hidden', index !== tabIndex)); tabNavs.forEach((nav, index) => nav.classList.toggle('active', index === tabIndex)); prevBtn.style.visibility = tabIndex === 0 ? 'hidden' : 'visible'; nextBtn.textContent = tabIndex === tabs.length - 1 ? 'Go to Dashboard' : 'Next'; }; const nextPrev = (direction) => { const newTab = currentTab + direction; if (newTab >= 0 && newTab < tabs.length) { currentTab = newTab; showTab(currentTab); } else if (newTab === tabs.length) { currentTab = 0; showTab(currentTab); } }; // --- EVENT HANDLERS --- addItemForm.addEventListener('submit', (e) => { e.preventDefault(); const newItem = { id: Date.now(), supplierName: document.getElementById('supplier-name').value, checkpoint: document.getElementById('checkpoint-name').value, nextReview: document.getElementById('next-review-date').value, }; auditItems.push(newItem); renderAll(); addItemForm.reset(); }); configList.addEventListener('click', (e) => { if (e.target.matches('.delete-btn')) { const id = parseInt(e.target.dataset.id, 10); auditItems = auditItems.filter(p => p.id !== id); renderAll(); } }); const downloadPDF = () => { const { jsPDF } = window.jspdf; const content = document.getElementById('pdf-content'); if (!content || auditItems.length === 0) return; const pdfTitle = document.createElement('h1'); pdfTitle.textContent = 'Supplier Contract Compliance Audit Report'; pdfTitle.className = 'text-2xl font-bold text-gray-800 text-center mb-2'; const reportDate = document.createElement('p'); reportDate.textContent = `Report generated on ${new Date().toLocaleDateString('en-US')}`; reportDate.className = 'text-sm text-gray-500 text-center mb-8'; content.prepend(reportDate); content.prepend(pdfTitle); html2canvas(content, { scale: 2, backgroundColor: '#ffffff', useCORS: true }) .then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const ratio = canvasWidth / canvasHeight; const imgWidth = pdfWidth - 20; const imgHeight = imgWidth / ratio; pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight); pdf.save('Supplier-Compliance-Audit-Report.pdf'); }).finally(() => { content.removeChild(pdfTitle); content.removeChild(reportDate); }); }; // --- INITIALIZATION --- const renderAll = () => { renderDashboard(); renderConfig(); }; prevBtn.addEventListener('click', () => nextPrev(-1)); nextBtn.addEventListener('click', () => nextPrev(1)); downloadPdfBtn.addEventListener('click', downloadPDF); tabNavs.forEach((nav, index) => { nav.addEventListener('click', () => { currentTab = index; showTab(index); }); }); showTab(currentTab); renderAll(); });