feat: bulk XML upload, period selector, and session persistence

- Add bulk XML CFDI upload support (up to 300MB)
- Add period selector component for month/year navigation
- Fix session persistence on page refresh (Zustand hydration)
- Fix income/expense classification based on tenant RFC
- Fix IVA calculation from XML (correct Impuestos element)
- Add error handling to reportes page
- Support multiple CORS origins
- Update reportes service with proper Decimal/BigInt handling
- Add RFC to tenant view store for proper CFDI classification
- Update README with changelog and new features

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Consultoria AS
2026-01-22 06:51:53 +00:00
parent 0c10c887d2
commit c3ce7199af
37 changed files with 1680 additions and 216 deletions

View File

@@ -1,9 +1,11 @@
'use client';
import { useState } from 'react';
import { Header } from '@/components/layouts/header';
import { KpiCard } from '@/components/charts/kpi-card';
import { BarChart } from '@/components/charts/bar-chart';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { PeriodSelector } from '@/components/period-selector';
import { useKpis, useIngresosEgresos, useAlertas, useResumenFiscal } from '@/lib/hooks/use-dashboard';
import {
TrendingUp,
@@ -15,13 +17,13 @@ import {
} from 'lucide-react';
export default function DashboardPage() {
const currentYear = new Date().getFullYear();
const currentMonth = new Date().getMonth() + 1;
const [año, setAño] = useState(new Date().getFullYear());
const [mes, setMes] = useState(new Date().getMonth() + 1);
const { data: kpis, isLoading: kpisLoading } = useKpis(currentYear, currentMonth);
const { data: chartData, isLoading: chartLoading } = useIngresosEgresos(currentYear);
const { data: kpis, isLoading: kpisLoading } = useKpis(año, mes);
const { data: chartData, isLoading: chartLoading } = useIngresosEgresos(año);
const { data: alertas, isLoading: alertasLoading } = useAlertas(5);
const { data: resumenFiscal } = useResumenFiscal(currentYear, currentMonth);
const { data: resumenFiscal } = useResumenFiscal(año, mes);
const formatCurrency = (value: number) =>
new Intl.NumberFormat('es-MX', {
@@ -32,7 +34,14 @@ export default function DashboardPage() {
return (
<>
<Header title="Dashboard" />
<Header title="Dashboard">
<PeriodSelector
año={año}
mes={mes}
onAñoChange={setAño}
onMesChange={setMes}
/>
</Header>
<main className="p-6 space-y-6">
{/* KPIs */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">