// Dashboard JavaScript let categoryChart, monthlyChart; // Load dashboard data async function loadDashboardData() { try { const stats = await apiCall('/api/dashboard-stats'); // Update KPI cards document.getElementById('total-spent').textContent = formatCurrency(stats.total_spent, stats.currency); document.getElementById('active-categories').textContent = stats.active_categories; document.getElementById('total-transactions').textContent = stats.total_transactions; // Update percent change const percentChange = document.getElementById('percent-change'); const isPositive = stats.percent_change >= 0; percentChange.className = `${isPositive ? 'bg-red-500/10 text-red-400' : 'bg-green-500/10 text-green-400'} text-xs font-semibold px-2 py-1 rounded-full flex items-center gap-1`; percentChange.innerHTML = ` ${isPositive ? 'trending_up' : 'trending_down'} ${Math.abs(stats.percent_change)}% `; // Load charts loadCategoryChart(stats.category_breakdown); loadMonthlyChart(stats.monthly_data); // Load recent transactions loadRecentTransactions(); } catch (error) { console.error('Failed to load dashboard data:', error); } } // Category pie chart function loadCategoryChart(data) { const ctx = document.getElementById('category-chart').getContext('2d'); if (categoryChart) { categoryChart.destroy(); } if (data.length === 0) { const isDark = document.documentElement.classList.contains('dark'); ctx.fillStyle = isDark ? '#92adc9' : '#64748b'; ctx.font = '14px Inter'; ctx.textAlign = 'center'; ctx.fillText('No data available', ctx.canvas.width / 2, ctx.canvas.height / 2); return; } categoryChart = new Chart(ctx, { type: 'doughnut', data: { labels: data.map(d => d.name), datasets: [{ data: data.map(d => d.amount), backgroundColor: data.map(d => d.color), borderWidth: 0 }] }, options: { responsive: true, maintainAspectRatio: true, plugins: { legend: { position: 'bottom', labels: { color: document.documentElement.classList.contains('dark') ? '#92adc9' : '#64748b', padding: 15, font: { size: 12 } } } } } }); } // Monthly bar chart function loadMonthlyChart(data) { const ctx = document.getElementById('monthly-chart').getContext('2d'); if (monthlyChart) { monthlyChart.destroy(); } monthlyChart = new Chart(ctx, { type: 'bar', data: { labels: data.map(d => d.month), datasets: [{ label: 'Spending', data: data.map(d => d.total), backgroundColor: '#2b8cee', borderRadius: 8 }] }, options: { responsive: true, maintainAspectRatio: true, plugins: { legend: { display: false } }, scales: { y: { beginAtZero: true, ticks: { color: document.documentElement.classList.contains('dark') ? '#92adc9' : '#64748b' }, grid: { color: document.documentElement.classList.contains('dark') ? '#233648' : '#e2e8f0' } }, x: { ticks: { color: document.documentElement.classList.contains('dark') ? '#92adc9' : '#64748b' }, grid: { display: false } } } } }); } // Load recent transactions async function loadRecentTransactions() { try { const data = await apiCall('/api/recent-transactions?limit=5'); const container = document.getElementById('recent-transactions'); if (data.transactions.length === 0) { container.innerHTML = '
No transactions yet
'; return; } container.innerHTML = data.transactions.map(tx => `${tx.description}
${tx.category_name} • ${formatDate(tx.date)}
${formatCurrency(tx.amount, tx.currency)}
${tx.tags.length > 0 ? `${tx.tags.join(', ')}
` : ''}