import { useEffect, useState } from 'react' import { MODULOS, esModuloVisible } from './data/modulos' import { Navbar } from './components/Navbar' import { TarjetaModulo } from './components/TarjetaModulo' import { ConfiguracionCuenta } from './components/ConfiguracionCuenta' import BannerModoLocal from './components/BannerModoLocal' import { VistaContactos } from './components/VistaContactos' import { ConfigPage } from './components/config/ConfigPage' import { CapturaPage } from './pages/CapturaPage' import { getToken, type UsuarioSesion } from './services/auth' import { getMe } from './services/api' type Vista = 'home' | 'contactos' | 'captura' | 'configuraciones' export default function App() { const [vista, setVista] = useState('home') // Módulos permitidos por el rol (GET /auth/me); null = sin sesión → se muestran todos const [permitidos, setPermitidos] = useState(null) const [usuario, setUsuario] = useState(null) useEffect(() => { let cancelado = false const cargar = () => { if (!getToken()) { setPermitidos(null) setUsuario(null) return } // Si /me falla se conserva lo anterior (o todos): el login wall de cada app sigue getMe() .then((u) => { if (!cancelado) { setPermitidos(u.modulos ?? []) setUsuario(u) } }) .catch(() => {}) } cargar() window.addEventListener('frasa:sesion', cargar) return () => { cancelado = true window.removeEventListener('frasa:sesion', cargar) } }, []) if (vista === 'contactos') { return (
setVista('configuraciones')} /> setVista('home')} />
) } if (vista === 'captura') { return (
setVista('configuraciones')} /> setVista('home')} />
) } if (vista === 'configuraciones' && usuario?.rol === 'admin') { return (
setVista('configuraciones')} /> setVista('home')} />
) } return (
setVista('configuraciones')} />

Ecosistema comercial

Las herramientas del equipo comercial de Frasa Desarrollos en un solo lugar: cotizaciones, alta de clientes, cobranza, tableros y asistente IA.

) }