Smart Promo Code Performance Tracker

Promo Code Performance Tracker

Analyze the effectiveness of your promotional campaigns.

to

Code Comparison

Redemptions Over Time

Detailed Performance Data

$${totalRevenue.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})}

Total Redemptions

${totalRedemptions.toLocaleString()}

Total Discount

$${totalDiscount.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})}

Average Order Value

$${aov.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})}

`; } function renderComparisonChart(data) { const ctx = document.getElementById('comparisonChart').getContext('2d'); const metric = document.getElementById('metricSelector').value; const activeData = data.filter(p => promoCodes.find(pc => pc.code === p.code && pc.status === 'active')); const labels = activeData.map(p => p.code); const chartData = activeData.map(p => p[metric]); if (comparisonChart) comparisonChart.destroy(); comparisonChart = new Chart(ctx, { type: 'bar', data: { labels, datasets: [{ label: metric.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()), data: chartData, backgroundColor: '#4f46e5', }]}, options: { responsive: true, maintainAspectRatio: false } }); } function renderTrendChart(startDate, endDate) { const ctx = document.getElementById('trendChart').getContext('2d'); const dateMap = {}; for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) { dateMap[d.toISOString().split('T')[0]] = 0; } redemptions.forEach(r => { const rDate = new Date(r.timestamp); if (rDate >= startDate && rDate <= endDate) { const dateKey = rDate.toISOString().split('T')[0]; if (dateMap.hasOwnProperty(dateKey)) { dateMap[dateKey]++; } } }); const labels = Object.keys(dateMap); const data = Object.values(dateMap); if (trendChart) trendChart.destroy(); trendChart = new Chart(ctx, { type: 'line', data: { labels, datasets: [{ label: 'Redemptions', data, borderColor: '#6366f1', tension: 0.1, fill: false }]}, options: { responsive: true, maintainAspectRatio: false, scales: { x: { type: 'time', time: { unit: 'day' } } } } }); } function renderTable(data, sortBy = 'netRevenue', sortOrder = 'desc') { const headers = [ { key: 'code', name: 'Promo Code' }, { key: 'redemptions', name: 'Redemptions' }, { key: 'totalRevenue', name: 'Total Revenue' }, { key: 'totalDiscount', name: 'Total Discount' }, { key: 'netRevenue', name: 'Net Revenue' }, { key: 'aov', name: 'AOV' } ]; data.sort((a, b) => { const res = sortOrder === 'asc' ? a[sortBy] - b[sortBy] : b[sortBy] - a[sortBy]; if (typeof a[sortBy] === 'string') { return sortOrder === 'asc' ? a[sortBy].localeCompare(b[sortBy]) : b[sortBy].localeCompare(a[sortBy]); } return res; }); const headerRow = document.getElementById('table-header'); headerRow.innerHTML = headers.map(h => `${h.name}`).join(''); const tableBody = document.getElementById('table-body'); tableBody.innerHTML = data.map(p => ` ${p.code} ${p.redemptions.toLocaleString()} $${p.totalRevenue.toFixed(2)} $${p.totalDiscount.toFixed(2)} $${p.netRevenue.toFixed(2)} $${p.aov.toFixed(2)} `).join(''); } async function generatePdf() { const startDate = new Date(document.getElementById('startDate').value); const endDate = new Date(document.getElementById('endDate').value); document.getElementById('pdf-date-range').textContent = `${startDate.toLocaleDateString()} to ${endDate.toLocaleDateString()}`; document.getElementById('pdf-kpis').innerHTML = document.getElementById('kpi-cards').innerHTML; document.getElementById('pdf-chart-image').src = comparisonChart.toBase64Image(); const tableClone = document.querySelector('table').cloneNode(true); tableClone.classList.add("w-full", "text-xs"); document.getElementById('pdf-table-container').innerHTML = ''; document.getElementById('pdf-table-container').appendChild(tableClone); const reportEl = document.getElementById('pdf-report'); reportEl.classList.remove('hidden'); const canvas = await html2canvas(reportEl, { scale: 2 }); reportEl.classList.add('hidden'); const imgData = canvas.toDataURL('image/png'); const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'l', unit: 'in', format: 'letter' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = (canvas.height * pdfWidth) / canvas.width; pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight); pdf.save('Promo-Performance-Report.pdf'); } function setupEventListeners() { document.getElementById('startDate').addEventListener('change', updateDashboard); document.getElementById('endDate').addEventListener('change', updateDashboard); document.getElementById('metricSelector').addEventListener('change', updateDashboard); document.getElementById('downloadPdfBtn').addEventListener('click', generatePdf); document.getElementById('table-header').addEventListener('click', e => { if(e.target.dataset.sort) { const sortBy = e.target.dataset.sort; updateDashboard(sortBy); } }); } function initialize() { generateMockData(); const today = new Date(); const thirtyDaysAgo = new Date(new Date().setDate(today.getDate() - 30)); document.getElementById('endDate').value = today.toISOString().split('T')[0]; document.getElementById('startDate').value = thirtyDaysAgo.toISOString().split('T')[0]; setupEventListeners(); updateDashboard(); } initialize(); });
Scroll to Top