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:
@@ -1,12 +1,14 @@
|
||||
import type { FC } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { Phone, MapPin, Mail, Globe, Save, Building2, ArrowRightLeft, Percent, Check } from 'lucide-react';
|
||||
import { Phone, MapPin, Mail, Globe, Save, Building2, ArrowRightLeft, Percent, Check, Calculator } from 'lucide-react';
|
||||
import Layout from '../components/Layout';
|
||||
import UsuariosPanel from '../components/UsuariosPanel';
|
||||
import RolesPanel from '../components/RolesPanel';
|
||||
import RecetasPanel from '../components/RecetasPanel';
|
||||
import CatalogoPanel from '../components/CatalogoPanel';
|
||||
import AuditoriaPanel from '../components/AuditoriaPanel';
|
||||
import ImpactoModal from '../components/ImpactoModal';
|
||||
import { Card, Button, Input, PageHeader, toast } from '../components/ui';
|
||||
import { odooApi, type Doctor } from '../services/odoo';
|
||||
|
||||
@@ -16,6 +18,7 @@ const TABS = [
|
||||
{ key: 'roles', label: 'Roles' },
|
||||
{ key: 'recetas', label: 'Recetas' },
|
||||
{ key: 'catalogos', label: 'Catálogos' },
|
||||
{ key: 'auditoria', label: 'Auditoría' },
|
||||
] as const;
|
||||
|
||||
const SUBCATALOGOS = [
|
||||
@@ -117,6 +120,7 @@ const Configuracion: FC = () => {
|
||||
const [commissionInputs, setCommissionInputs] = useState<Record<number, string>>({});
|
||||
const [commissionSavingId, setCommissionSavingId] = useState<number | null>(null);
|
||||
const [commissionSavedId, setCommissionSavedId] = useState<number | null>(null);
|
||||
const [impactoOpen, setImpactoOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
odooApi.getCommissionDefault()
|
||||
@@ -212,6 +216,8 @@ const Configuracion: FC = () => {
|
||||
<RecetasPanel />
|
||||
</Card.Body>
|
||||
</Card>
|
||||
) : tab === 'auditoria' ? (
|
||||
<AuditoriaPanel />
|
||||
) : tab === 'catalogos' ? (
|
||||
<Card>
|
||||
<Card.Body>
|
||||
@@ -387,6 +393,18 @@ const Configuracion: FC = () => {
|
||||
<p className="text-sm text-theme-muted mb-4">
|
||||
Porcentaje de comisión sobre las ventas atribuidas a cada médico (visible en su página "Mis ventas").
|
||||
</p>
|
||||
<div className="mb-5 p-4 bg-theme-bg rounded-xl flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
|
||||
<div>
|
||||
<p className="text-sm font-medium text-theme-heading">¿Cuánto costaría esta configuración?</p>
|
||||
<p className="text-xs text-theme-muted">
|
||||
Simula la comisión de cada médico con las ventas atribuidas reales de un mes, sin guardar nada.
|
||||
</p>
|
||||
</div>
|
||||
<Button variant="outline" onClick={() => setImpactoOpen(true)}>
|
||||
<Calculator size={16} className="mr-2" />
|
||||
Ver efecto
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex flex-col sm:flex-row items-start sm:items-end gap-3 max-w-md mb-6">
|
||||
<div className="flex-1 w-full">
|
||||
<Input
|
||||
@@ -467,6 +485,12 @@ const Configuracion: FC = () => {
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ImpactoModal
|
||||
isOpen={impactoOpen}
|
||||
onClose={() => setImpactoOpen(false)}
|
||||
comisionGlobal={parseFloat(commissionDefault) || 0}
|
||||
/>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user