document.addEventListener('DOMContentLoaded', async () => { try { const response = await apiFetch('api/movimientos.php'); if (!response) return; const data = await response.json(); if (data.status !== 'success') return; // Balance const balance = data.balance ?? 0; document.getElementById('ui-balance').textContent = formatMoney(balance); document.getElementById('ui-balance-resumen').textContent = balance >= 0 ? 'Saldo disponible' : 'Saldo negativo'; // Movimientos recientes const container = document.getElementById('ui-movimientos'); if (!data.movimientos.length) { container.innerHTML = `
receipt_long

Sin movimientos aún

`; } else { container.innerHTML = data.movimientos.map(mov => { const isGasto = mov.tipo === 'gasto'; const colorAmt = isGasto ? 'text-[#ba1a1a]' : 'text-[#005050]'; const signo = isGasto ? '-' : '+'; const icono = mov.categoria_icono || 'payments'; const titulo = mov.notas?.trim() ? mov.notas : (mov.categoria_nombre || '—'); const fecha = new Date(mov.fecha + 'T12:00:00') .toLocaleDateString('es-AR', { day:'2-digit', month:'short' }); return `
${icono}

${titulo}

${fecha} · ${mov.categoria_nombre || '—'}

${signo}${formatMoney(mov.monto)}

`; }).join(''); } // Donut if (data.grafico?.length) { const total = data.grafico.reduce((s, c) => s + parseFloat(c.total), 0); let svgCircles = '', legend = '', offset = 0; data.grafico.forEach(cat => { const pct = (parseFloat(cat.total) / total) * 100; svgCircles += ``; legend += `
${cat.nombre}
${pct.toFixed(1)}%
`; offset += pct; }); document.getElementById('ui-donut-chart').innerHTML = ` ${svgCircles}
${formatMoney(total)} Gastos
`; document.getElementById('ui-donut-legend').innerHTML = `
${legend}
`; } else { document.getElementById('ui-donut-chart').innerHTML = `
Sin gastos
`; document.getElementById('ui-donut-legend').innerHTML = ''; } } catch (e) { console.error('Dashboard error:', e); } }); function formatMoney(n) { return '$' + parseFloat(n).toLocaleString('es-AR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }