Affiliates to Pay
${affiliatesToPay}
Total Sales Volume
$${totalSalesAll.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})}
`;
// Render Table
dashboardTableBody.innerHTML = '';
results.sort((a,b) => b.commission - a.commission).forEach(r => {
const tr = document.createElement('tr');
tr.className = 'bg-white border-b hover:bg-gray-50';
const statusClass = r.status.toLowerCase();
tr.innerHTML = `
${r.name} |
${r.paymentInfo} |
$${r.totalSales.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})} |
$${r.commission.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})} |
${r.status} |
`;
dashboardTableBody.appendChild(tr);
});
processPaymentsBtn.classList.toggle('btn-disabled', affiliatesToPay === 0);
processPaymentsBtn.disabled = affiliatesToPay === 0;
document.getElementById('dashboard-date').textContent = `Payment Cycle Ending: ${new Date().toLocaleDateString()}`;
};
const renderAll = () => {
renderConfig();
renderDashboard();
updateNavButtons();
};
// --- Row Creation for Config ---
const createAffiliateRow = (affiliate = {}) => {
const id = affiliate.id || nextId++;
const div = document.createElement('div');
div.className = 'affiliate-row flex items-center gap-2';
div.dataset.id = id;
div.innerHTML = `
`;
div.querySelector('.remove-btn').addEventListener('click', () => div.remove());
affiliatesList.appendChild(div);
};
const createSaleRow = (sale = {}) => {
const id = sale.id || nextId++;
const div = document.createElement('div');
div.className = 'sale-row flex items-center gap-2';
div.dataset.id = id;
const affiliateOptions = state.affiliates.map(a => `
`).join('');
div.innerHTML = `
`;
div.querySelector('.remove-btn').addEventListener('click', () => div.remove());
salesList.appendChild(div);
};
// --- Event Handlers ---
addAffiliateBtn.addEventListener('click', () => createAffiliateRow());
addSaleBtn.addEventListener('click', () => createSaleRow());
processPaymentsBtn.addEventListener('click', () => {
state.affiliates.forEach(aff => {
const hasSales = state.sales.some(s => s.affiliateId === aff.id);
if(hasSales) paymentStatus[aff.id] = 'Paid';
});
renderDashboard();
});
// --- Tab & Navigation Logic ---
function switchTab(targetTabId) {
if (currentTab === 'config') {
saveConfig();
}
currentTab = targetTabId;
tabs.forEach(tab => tab.classList.toggle('active', tab.dataset.tab === currentTab));
tabContents.forEach(content => content.classList.toggle('active', content.id === currentTab));
renderAll();
}
tabs.forEach(tab => tab.addEventListener('click', () => switchTab(tab.dataset.tab)));
nextBtn.addEventListener('click', () => currentTab === 'dashboard' ? switchTab('config') : switchTab('dashboard'));
prevBtn.addEventListener('click', () => currentTab === 'config' ? switchTab('dashboard') : switchTab('config'));
function updateNavButtons() {
if (currentTab === 'dashboard') {
nextBtn.textContent = 'Configure Data';
prevBtn.style.display = 'none';
pdfButtonContainer.style.display = 'block';
} else {
nextBtn.textContent = 'Update Dashboard';
prevBtn.style.display = 'inline-flex';
pdfButtonContainer.style.display = 'none';
}
}
// --- PDF Download ---
downloadPdfBtn.addEventListener('click', async () => {
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' });
const content = document.getElementById('pdf-content');
// Prepare for PDF rendering
document.querySelectorAll('.no-pdf').forEach(el => el.classList.add('pdf-hide'));
document.querySelectorAll('.pdf-only').forEach(el => el.classList.remove('pdf-hide'));
document.getElementById('pdf-date').textContent = `Report Generated: ${new Date().toLocaleString()}`;
await new Promise(r => setTimeout(r, 100));
const canvas = await html2canvas(content, { scale: 2 });
const imgData = canvas.toDataURL('image/jpeg', 1.0);
const imgProps = doc.getImageProperties(imgData);
const pdfWidth = doc.internal.pageSize.getWidth() - 28;
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
doc.addImage(imgData, 'JPEG', 14, 15, pdfWidth, pdfHeight);
// Revert to screen view
document.querySelectorAll('.no-pdf').forEach(el => el.classList.remove('pdf-hide'));
document.querySelectorAll('.pdf-only').forEach(el => el.classList.add('pdf-hide'));
doc.save(`Affiliate-Payment-Report-${new Date().toISOString().slice(0,10)}.pdf`);
});
// --- Initial Load ---
renderAll();
});