Potential Issues
${totalRules - compliantRules}
Compliance Status by Region
Identified Issues
${issues.length > 0 ? `
${issues.map(issue => `
-
${issue}
`).join('')}
` : `
No Compliance Issues Found
All configured prices appear to be compliant.
`
}
`;
// Render Chart
const chartCtx = document.getElementById('complianceByRegionChart').getContext('2d');
if (charts.compliance) charts.compliance.destroy();
charts.compliance = new Chart(chartCtx, {
type: 'bar',
data: {
labels: regions,
datasets: [{
label: 'Compliance Score',
data: complianceByRegion,
backgroundColor: complianceByRegion.map(score => score === 100 ? '#22c55e' : '#ef4444'),
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
indexAxis: 'y',
scales: { x: { max: 100, ticks: { callback: value => `${value}%` } } },
plugins: { legend: { display: false } }
}
});
lucide.createIcons();
document.getElementById('download-pdf-btn').addEventListener('click', generatePdf);
};
const renderDataConfig = () => {
const configContent = document.getElementById('content-data-config');
if (!configContent) return;
let productsHtml = appData.products.map((product, index) => `
`).join('');
let rulesHtml = appData.taxRules.map((rule, index) => `
`).join('');
configContent.innerHTML = `
Products & Pricing
${productsHtml}
Tax Rules & Compliance Status
RegionTypeRate %Is Compliant?
${rulesHtml}
`;
attachConfigListeners();
};
const attachConfigListeners = () => {
document.getElementById('add-product-btn').addEventListener('click', () => {
appData.products.push({ name: 'New Product', price: 0 });
renderDataConfig();
lucide.createIcons();
});
document.getElementById('add-rule-btn').addEventListener('click', () => {
appData.taxRules.push({ region: 'New Region', type: 'Tax', rate: 0, isCompliant: false });
renderDataConfig();
lucide.createIcons();
});
document.querySelectorAll('.remove-product-btn').forEach(btn => btn.addEventListener('click', e => {
appData.products.splice(parseInt(e.currentTarget.dataset.index), 1);
renderDataConfig();
lucide.createIcons();
}));
document.querySelectorAll('.remove-rule-btn').forEach(btn => btn.addEventListener('click', e => {
appData.taxRules.splice(parseInt(e.currentTarget.dataset.index), 1);
renderDataConfig();
lucide.createIcons();
}));
document.getElementById('update-data-btn').addEventListener('click', handleConfigUpdate);
};
const handleConfigUpdate = () => {
// Update products
const newProducts = [];
document.querySelectorAll('.product-row').forEach(row => {
newProducts.push({
name: row.querySelector('[data-field="name"]').value,
price: parseFloat(row.querySelector('[data-field="price"]').value) || 0,
});
});
appData.products = newProducts;
// Update tax rules
const newRules = [];
document.querySelectorAll('.rule-row').forEach(row => {
newRules.push({
region: row.querySelector('[data-field="region"]').value,
type: row.querySelector('[data-field="type"]').value,
rate: parseFloat(row.querySelector('[data-field="rate"]').value) || 0,
isCompliant: row.querySelector('[data-field="isCompliant"]').checked,
});
});
appData.taxRules = newRules;
complianceResult = null; // Force recalculation
renderDashboard();
alert('Configuration updated and compliance check re-run!');
switchTab(0);
};
const generatePdf = () => {
loadingOverlay.style.display = 'flex';
const { jsPDF } = window.jspdf;
const pdfContent = document.getElementById('pdf-content-area');
const pdfHeader = document.getElementById('pdf-header');
document.getElementById('pdf-generated-date').textContent = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
pdfHeader.classList.remove('hidden');
html2canvas(pdfContent, { scale: 2, useCORS: true, logging: false })
.then(canvas => {
pdfHeader.classList.add('hidden');
const imgData = canvas.toDataURL('image/jpeg', 0.95);
const pdf = new jsPDF({ orientation: 'landscape', unit: 'px', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const imgProps = pdf.getImageProperties(imgData);
const imgHeight = (imgProps.height * pdfWidth) / imgProps.width;
pdf.addImage(imgData, 'JPEG', 0, 0, pdfWidth, imgHeight);
pdf.save('Tax-Compliance-Report.pdf');
loadingOverlay.style.display = 'none';
}).catch(err => {
console.error("PDF generation failed:", err);
pdfHeader.classList.add('hidden');
loadingOverlay.style.display = 'none';
alert('An error occurred generating the PDF.');
});
};
// --- TAB NAVIGATION & INITIALIZATION ---
const switchTab = (tabIndex) => {
activeTabIndex = tabIndex;
document.querySelectorAll('.tab-btn').forEach((btn, i) => btn.classList.toggle('active', i === tabIndex));
document.querySelectorAll('.tab-content').forEach((content, i) => content.classList.toggle('hidden', i !== tabIndex));
updateNavButtons();
};
const updateNavButtons = () => {
prevTabBtn.disabled = activeTabIndex === 0;
nextTabBtn.disabled = activeTabIndex === tabIdentifiers.length - 1;
};
const initializeUI = () => {
const tabs = [
{ name: 'Compliance Dashboard', id: 'dashboard' },
{ name: 'Data Configuration', id: 'data-config' }
];
tabIdentifiers = tabs.map(t => t.id);
tabsContainer.innerHTML = tabs.map(tab => `
`).join('');
mainContent.innerHTML = tabs.map(tab => `
`).join('');
tabs.forEach((tab, index) => {
document.getElementById(`tab-${tab.id}`).addEventListener('click', () => switchTab(index));
});
renderDashboard();
renderDataConfig();
switchTab(0);
};
initializeUI();
lucide.createIcons();
prevTabBtn.addEventListener('click', () => { if (activeTabIndex > 0) switchTab(activeTabIndex - 1); });
nextTabBtn.addEventListener('click', () => { if (activeTabIndex < tabIdentifiers.length - 1) switchTab(activeTabIndex + 1); });
});