Customer Advocacy Dashboard

Customer Advocacy Dashboard

Overall Advocacy Summary

Total Advocates

0

Average NPS

0

Total Referrals ($)

$0

Total Testimonials

0

NPS Distribution

Advocacy Type Breakdown

Testimonial Sentiment

Detailed Advocacy Records

ID Customer Name NPS Score Advocacy Type Date Referral Value ($) Sentiment Notes

No data to display.

'; return; } // Sort data by value descending for general charts, custom for NPS let sortedData = Object.entries(data); if (valueType === 'nps') { const npsOrder = ['Promoter', 'Passive', 'Detractor']; sortedData.sort(([labelA], [labelB]) => npsOrder.indexOf(labelA) - npsOrder.indexOf(labelB)); } else { sortedData.sort(([, valA], [, valB]) => valB - valA); } // Determine the maximum value for scaling bars const maxValue = Math.max(...Object.values(data), 1); // Avoid division by zero if all values are 0 sortedData.forEach(([label, value]) => { const barWidth = (value / maxValue) * 100; // Scale based on max value for visual representation const percentageOfTotal = totalValue > 0 ? ((value / totalValue) * 100).toFixed(1) : 0; let displayValue; let barClass = 'bg-blue-300'; // Default bar color if (valueType === 'currency') { displayValue = `$${value.toLocaleString('en-US')}`; } else if (valueType === 'nps') { displayValue = `${value} Customers`; if (label === 'Promoter') barClass = 'nps-promoter'; else if (label === 'Passive') barClass = 'nps-passive'; else if (label === 'Detractor') barClass = 'nps-detractor'; } else { // 'count' displayValue = `${value} Records`; } const barWrapper = document.createElement('div'); barWrapper.classList.add('chart-bar-wrapper'); barWrapper.innerHTML = ` ${label}:
${displayValue} (${percentageOfTotal}%)
`; targetElement.appendChild(barWrapper); }); } /** * Calculates and renders all distribution charts. */ function renderDistributionCharts() { const totalRecords = customerAdvocacyRecords.length; // NPS Distribution const npsCategoryCounts = { 'Promoter': 0, 'Passive': 0, 'Detractor': 0 }; customerAdvocacyRecords.forEach(record => { const category = getNPSCategory(record.npsScore); npsCategoryCounts[category]++; }); renderBarChart(npsDistributionChartElem, npsCategoryCounts, 'nps'); // Advocacy Type Breakdown const advocacyTypeCounts = customerAdvocacyRecords.reduce((acc, record) => { acc[record.advocacyType] = (acc[record.advocacyType] || 0) + 1; return acc; }, {}); renderBarChart(advocacyTypeChartElem, advocacyTypeCounts, 'count'); // Testimonial Sentiment const testimonialSentimentCounts = customerAdvocacyRecords .filter(record => ['Testimonial', 'Review', 'Social Mention'].includes(record.advocacyType) && record.sentiment !== 'N/A') .reduce((acc, record) => { acc[record.sentiment] = (acc[record.sentiment] || 0) + 1; return acc; }, {}); renderBarChart(testimonialSentimentChartElem, testimonialSentimentCounts, 'count'); } /** * Generates a PDF of the dashboard content. * Excludes non-essential UI elements like buttons and input forms. */ function generatePdf() { // Create a temporary div to hold only the content for PDF const pdfContentWrapper = document.createElement('div'); pdfContentWrapper.classList.add('pdf-content-wrapper'); // Apply PDF-specific styles // Add title const title = document.createElement('h2'); title.textContent = 'Customer Advocacy Dashboard Report'; title.classList.add('text-2xl', 'font-bold', 'mb-4'); pdfContentWrapper.appendChild(title); // Add summary cards const summarySection = document.createElement('div'); summarySection.classList.add('grid', 'grid-cols-4', 'gap-4', 'mb-6'); summarySection.innerHTML = `

Total Advocates

${totalAdvocatesCountElem.textContent}

Average NPS

${averageNPSElem.textContent}

Total Referrals ($)

${totalReferralValueElem.textContent}

Total Testimonials

${totalTestimonialsCountElem.textContent}

`; pdfContentWrapper.appendChild(summarySection); // Add distribution charts const chartsSection = document.createElement('div'); chartsSection.classList.add('grid', 'grid-cols-2', 'gap-6', 'mb-6'); chartsSection.innerHTML = `

NPS Distribution

Advocacy Type Breakdown

Testimonial Sentiment

`; pdfContentWrapper.appendChild(chartsSection); // Populate PDF charts (re-use logic but target PDF elements) const totalRecords = customerAdvocacyRecords.length; const npsCategoryCounts = { 'Promoter': 0, 'Passive': 0, 'Detractor': 0 }; customerAdvocacyRecords.forEach(record => { const category = getNPSCategory(record.npsScore); npsCategoryCounts[category]++; }); renderBarChart(chartsSection.querySelector('#pdfNpsDistributionChart'), npsCategoryCounts, 'nps'); const advocacyTypeCounts = customerAdvocacyRecords.reduce((acc, record) => { acc[record.advocacyType] = (acc[record.advocacyType] || 0) + 1; return acc; }, {}); renderBarChart(chartsSection.querySelector('#pdfAdvocacyTypeChart'), advocacyTypeCounts, 'count'); const testimonialSentimentCounts = customerAdvocacyRecords .filter(record => ['Testimonial', 'Review', 'Social Mention'].includes(record.advocacyType) && record.sentiment !== 'N/A') .reduce((acc, record) => { acc[record.sentiment] = (acc[record.sentiment] || 0) + 1; return acc; }, {}); renderBarChart(chartsSection.querySelector('#pdfTestimonialSentimentChart'), testimonialSentimentCounts, 'count'); // Add detailed advocacy list table const advocacyListSection = document.createElement('div'); advocacyListSection.innerHTML = `

Detailed Advocacy Records

${dashboardAdvocacyTableBody.innerHTML}
ID Customer Name NPS Score Advocacy Type Date Referral Value ($) Sentiment Notes
`; pdfContentWrapper.appendChild(advocacyListSection); // Options for html2pdf const options = { margin: 10, filename: 'Customer_Advocacy_Dashboard.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, logging: true, dpi: 192, letterRendering: true }, jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }, pagebreak: { mode: ['avoid-all', 'css', 'legacy'] } }; // Generate PDF from the temporary content wrapper html2pdf().from(pdfContentWrapper).set(options).save(); // Clean up the temporary div (optional, as it's not appended to the DOM) pdfContentWrapper.remove(); } /** * Loads initial sample data for the dashboard. * Relevant to USA context. */ function loadSampleData() { customerAdvocacyRecords = [ { id: 'CA001', customerName: 'John Smith', npsScore: 9, advocacyType: 'Referral', date: '2024-06-01', referralValue: 1000, sentiment: 'Positive', notes: 'Referred new client ABC Corp' }, { id: 'CA002', customerName: 'Jane Doe', npsScore: 7, advocacyType: 'Testimonial', date: '2024-06-05', referralValue: 0, sentiment: 'Neutral', notes: 'Provided a written testimonial' }, { id: 'CA003', customerName: 'Peter Jones', npsScore: 4, advocacyType: 'Review', date: '2024-06-10', referralValue: 0, sentiment: 'Negative', notes: 'Left a 2-star review on G2' }, { id: 'CA004', customerName: 'Sarah Lee', npsScore: 10, advocacyType: 'Social Mention', date: '2024-06-12', referralValue: 0, sentiment: 'Positive', notes: 'Positive tweet about product launch' }, { id: 'CA005', customerName: 'Mike Brown', npsScore: 8, advocacyType: 'Referral', date: '2024-06-15', referralValue: 500, sentiment: 'Positive', notes: 'Referred two small businesses' }, { id: 'CA006', customerName: 'Emily White', npsScore: 6, advocacyType: 'Testimonial', date: '2024-06-18', referralValue: 0, sentiment: 'Neutral', notes: 'Provided video testimonial' }, { id: 'CA007', customerName: 'David Green', npsScore: 10, advocacyType: 'Case Study', date: '2024-06-20', referralValue: 0, sentiment: 'Positive', notes: 'Participated in a successful case study' }, { id: 'CA008', customerName: 'Olivia Black', npsScore: 2, advocacyType: 'Review', date: '2024-06-22', referralValue: 0, sentiment: 'Negative', notes: 'Left a critical review on Yelp' } ]; }
Scroll to Top