import apiClient from './apiClient.js'; class AdminDashboard { constructor() { this.providersContainer = document.querySelector('[data-admin-providers]'); this.tableBody = document.querySelector('[data-admin-table]'); this.refreshBtn = document.querySelector('[data-admin-refresh]'); this.healthBadge = document.querySelector('[data-admin-health]'); this.latencyChartCanvas = document.querySelector('#provider-latency-chart'); this.statusChartCanvas = document.querySelector('#provider-status-chart'); this.latencyChart = null; this.statusChart = null; } init() { this.loadProviders(); if (this.refreshBtn) { this.refreshBtn.addEventListener('click', () => this.loadProviders()); } } async loadProviders() { if (this.tableBody) { this.tableBody.innerHTML = 'Loading providers...'; } const result = await apiClient.getProviders(); if (!result.ok) { this.providersContainer.innerHTML = `
${result.error}
`; this.tableBody.innerHTML = ''; return; } const providers = result.data || []; this.renderCards(providers); this.renderTable(providers); this.renderCharts(providers); } renderCards(providers) { if (!this.providersContainer) return; const healthy = providers.filter((p) => p.status === 'healthy').length; const failing = providers.length - healthy; const avgLatency = ( providers.reduce((sum, provider) => sum + Number(provider.latency || 0), 0) / (providers.length || 1) ).toFixed(0); this.providersContainer.innerHTML = `

Total Providers

${providers.length}

Healthy

${healthy}

Issues

${failing}

Avg Latency

${avgLatency} ms
`; if (this.healthBadge) { this.healthBadge.dataset.state = failing ? 'warn' : 'ok'; this.healthBadge.querySelector('span').textContent = failing ? 'degraded' : 'optimal'; } } renderTable(providers) { if (!this.tableBody) return; this.tableBody.innerHTML = providers .map( (provider) => ` ${provider.name} ${provider.category || '—'} ${provider.latency || '—'} ms ${provider.status} ${provider.endpoint || provider.url || ''} `, ) .join(''); } renderCharts(providers) { if (this.latencyChartCanvas) { const labels = providers.map((p) => p.name); const data = providers.map((p) => p.latency || 0); if (this.latencyChart) this.latencyChart.destroy(); this.latencyChart = new Chart(this.latencyChartCanvas, { type: 'bar', data: { labels, datasets: [ { label: 'Latency (ms)', data, backgroundColor: '#38bdf8', }, ], }, options: { plugins: { legend: { display: false } }, scales: { x: { ticks: { color: 'var(--text-muted)' } }, y: { ticks: { color: 'var(--text-muted)' } }, }, }, }); } if (this.statusChartCanvas) { const healthy = providers.filter((p) => p.status === 'healthy').length; const degraded = providers.length - healthy; if (this.statusChart) this.statusChart.destroy(); this.statusChart = new Chart(this.statusChartCanvas, { type: 'doughnut', data: { labels: ['Healthy', 'Degraded'], datasets: [ { data: [healthy, degraded], backgroundColor: ['#22c55e', '#f59e0b'], }, ], }, options: { plugins: { legend: { labels: { color: 'var(--text-primary)' } } }, }, }); } } } window.addEventListener('DOMContentLoaded', () => { const dashboard = new AdminDashboard(); dashboard.init(); });