feat(config): modulo Configuraciones admin + permisos por rol
- Tablas ConfiguracionSistema (7 configs) + RolConfiguracion (6 roles) - Endpoints: config/sistema GET/PATCH, config/roles GET/PATCH, config/usuarios GET/PATCH, config/reset-roles POST, config/acciones GET - modulosDeRol() async con fallback a MATRIZ estatica - auth/me devuelve acciones[] segun rol del usuario - saludMonday.estaDisponible() lee modo_local_forzado de DB (cache 30s) - Landing: vista Configuraciones con 4 tabs (Modo, Roles, Usuarios, Sistema) - Mi-dia: boton Descartar se deshabilita si !descartar_lead - 630 API tests + 24 landing tests + 20 mi-dia tests verdes Seed: npm run seed:config
This commit is contained in:
@@ -5,27 +5,33 @@ import { TarjetaModulo } from './components/TarjetaModulo'
|
||||
import { ConfiguracionCuenta } from './components/ConfiguracionCuenta'
|
||||
import BannerModoLocal from './components/BannerModoLocal'
|
||||
import { VistaContactos } from './components/VistaContactos'
|
||||
import { getToken } from './services/auth'
|
||||
import { ConfigPage } from './components/config/ConfigPage'
|
||||
import { getToken, type UsuarioSesion } from './services/auth'
|
||||
import { getMe } from './services/api'
|
||||
|
||||
type Vista = 'home' | 'contactos'
|
||||
type Vista = 'home' | 'contactos' | 'configuraciones'
|
||||
|
||||
export default function App() {
|
||||
const [vista, setVista] = useState<Vista>('home')
|
||||
// Módulos permitidos por el rol (GET /auth/me); null = sin sesión → se muestran todos
|
||||
const [permitidos, setPermitidos] = useState<string[] | null>(null)
|
||||
const [usuario, setUsuario] = useState<UsuarioSesion | null>(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((usuario) => {
|
||||
if (!cancelado) setPermitidos(usuario.modulos ?? [])
|
||||
.then((u) => {
|
||||
if (!cancelado) {
|
||||
setPermitidos(u.modulos ?? [])
|
||||
setUsuario(u)
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
@@ -40,16 +46,26 @@ export default function App() {
|
||||
if (vista === 'contactos') {
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col">
|
||||
<Navbar />
|
||||
<Navbar usuario={usuario} onConfiguraciones={() => setVista('configuraciones')} />
|
||||
<BannerModoLocal />
|
||||
<VistaContactos onVolver={() => setVista('home')} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (vista === 'configuraciones' && usuario?.rol === 'admin') {
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col">
|
||||
<Navbar usuario={usuario} onConfiguraciones={() => setVista('configuraciones')} />
|
||||
<BannerModoLocal />
|
||||
<ConfigPage onVolver={() => setVista('home')} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col">
|
||||
<Navbar />
|
||||
<Navbar usuario={usuario} onConfiguraciones={() => setVista('configuraciones')} />
|
||||
<BannerModoLocal />
|
||||
|
||||
<main className="mx-auto w-full max-w-[1280px] flex-1 px-6">
|
||||
|
||||
Reference in New Issue
Block a user