Account Health Dashboard

Health Score Configuration

Set the weight for each metric to calculate the overall health score. Total must equal 100%.

Total: 100%

Account Roster

Account NameMRR ($)Renewal DateProduct UsageSatisfaction (NPS)Critical TicketsRelationshipAction

Account Health Portfolio Overview

Health Distribution

All Accounts Overview

${key.charAt(0).toUpperCase() + key.slice(1)} (${buckets[key]})

`).join('')} `; } // --- Calculation Logic --- calculateHealthScore(account) { if (Object.values(this.state.weights).reduce((s,w) => s+w, 0) !== 100) return 0; const scores = { usage: { 'High': 100, 'Medium': 60, 'Low': 10 }[account.usage], satisfaction: Math.max(0, (account.satisfaction + 100) / 2), tickets: Math.max(0, 100 - (account.tickets * 20)), relationship: { 'Strong': 100, 'Neutral': 60, 'Weak': 20 }[account.relationship] }; let totalScore = 0; for (const key in this.METRICS) { totalScore += scores[key] * (this.state.weights[key] / 100); } return totalScore; } getHealthStatus(score) { if (score < 50) return { status: 'At Risk', color: 'var(--health-poor)' }; if (score < 80) return { status: 'Needs Attention', color: 'var(--health-ok)' }; return { status: 'Healthy', color: 'var(--health-good)' }; } // --- Navigation & PDF --- openTab(event, tabName) { this.state.activeTab = tabName; this.updateUI(); } navigateTabs(dir) { const i = this.TABS_ORDER.indexOf(this.state.activeTab); let n = i; if (dir === 'next' && i < this.TABS_ORDER.length - 1) n++; if (dir === 'prev' && i > 0) n--; this.openTab(null, this.TABS_ORDER[n]); } async generatePdf() { if (this.state.activeTab !== 'dashboard') { this.openTab(null, 'dashboard'); await new Promise(res => setTimeout(res, 50)); } const { jsPDF } = window.jspdf; this.dom.downloadPdfBtn.disabled = true; this.dom.downloadPdfBtn.textContent = 'Generating...'; try { const canvas = await html2canvas(this.dom.pdfOutput, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a4' }); const margin = 40; const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgWidth = pdfWidth - margin * 2; const imgHeight = canvas.height * imgWidth / canvas.width; let heightLeft = imgHeight; let position = margin; pdf.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight); heightLeft -= (pdfHeight - margin * 2); while (heightLeft > 0) { position = -heightLeft - margin; pdf.addPage(); pdf.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight); heightLeft -= pdfHeight; } pdf.save(`Account_Health_Dashboard.pdf`); } catch (e) { console.error(e); alert('Error generating PDF.'); } finally { this.dom.downloadPdfBtn.disabled = false; this.dom.downloadPdfBtn.textContent = 'Download Dashboard as PDF'; } } } const app = new AccountHealthDashboard();
Scroll to Top