Oleada UX 6: Reportes agrupados en familias con rango global persistente y favoritos; Configuracion con auditoria de cambios y simulador de comisiones

This commit is contained in:
2026-09-17 22:06:11 +00:00
parent cd945df6a5
commit 31c92ac419
21 changed files with 1325 additions and 137 deletions

View File

@@ -14,15 +14,10 @@ import { Card, Input, EmptyState, Skeleton, toast } from '../ui';
import { ExportButton } from '../ui/ExportButton';
import { exportToExcel } from '../../lib/exporter';
import { odooApi, type KpisReport as KpisData } from '../../services/odoo';
import { useReportRange } from '../../lib/reportRange';
const pct = (v: number) => `${Math.round(v * 100)}%`;
const inicioDeMes = () => {
const d = new Date();
d.setDate(1);
return d.toISOString().split('T')[0];
};
const hoy = () => new Date().toISOString().split('T')[0];
const Kpi: FC<{ label: string; value: React.ReactNode; icon: React.ReactNode; rose?: boolean }> = ({ label, value, icon, rose }) => (
<Card className="p-4 bg-theme-bg border-0">
@@ -35,8 +30,8 @@ const Kpi: FC<{ label: string; value: React.ReactNode; icon: React.ReactNode; ro
);
const KpisReport: FC = () => {
const [start, setStart] = useState(inicioDeMes());
const [end, setEnd] = useState(hoy());
// Rango global de Reportes; los campos Inicio/Fin fijan uno propio
const { start, end, setStart, setEnd } = useReportRange('kpis');
const [data, setData] = useState<KpisData | null>(null);
const [loading, setLoading] = useState(true);
const [exporting, setExporting] = useState(false);
@@ -102,6 +97,7 @@ const KpisReport: FC = () => {
<div className="flex flex-col sm:flex-row gap-3 items-end">
<Input label="Inicio" type="date" value={start} onChange={(e) => setStart(e.target.value)} className="sm:max-w-[160px]" />
<Input label="Fin" type="date" value={end} onChange={(e) => setEnd(e.target.value)} className="sm:max-w-[160px]" />
<div className="sm:ml-auto">
<ExportButton onClick={exportar} loading={exporting} />
</div>