feat: administradores por proyecto y Configuracion solo para superadmin
- Un proyecto puede tener uno o mas administradores (role_in_project= 'admin' en project_members), independiente del rol global del usuario. Nuevo PUT /api/projects/:id/members/:userId/role; canWriteProject lo reconoce ademas del comportamiento previo (admin/superadmin/it_manager global, o project_lead miembro). UI: casilla al agregar miembro + boton de escudo para promover/degradar (nunca toca al Dueño). - Menu "Configuracion" (apariencia, catalogos, SMTP) visible y accesible solo para el superadmin: oculto en el nav y con guarda en la ruta /configuracion para quien la teclee directo. Escritura de catalogos restringida de [superadmin, admin] a solo superadmin para que el backend sea consistente con la UI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { LayoutDashboard, FolderKanban, Building2, Settings } from 'lucide-react';
|
||||
import { useUi } from '../context/ui-context.jsx';
|
||||
import { useAuth } from '../context/auth-context.jsx';
|
||||
import logoDark from '../assets/logoLinkedCorpTxt.png';
|
||||
import logoLight from '../assets/logoLinkedCorpTxtBlack.png';
|
||||
import logoIcon from '../assets/logoLinked1.png';
|
||||
@@ -9,12 +10,14 @@ const ITEMS = [
|
||||
{ to: '/', icon: LayoutDashboard, labelKey: 'nav_dashboard', end: true },
|
||||
{ to: '/proyectos', icon: FolderKanban, labelKey: 'nav_projects' },
|
||||
{ to: '/organizacion', icon: Building2, labelKey: 'nav_organization' },
|
||||
{ to: '/configuracion', icon: Settings, labelKey: 'nav_config' },
|
||||
{ to: '/configuracion', icon: Settings, labelKey: 'nav_config', superadminOnly: true },
|
||||
];
|
||||
|
||||
export function NavigationView({ mode }) {
|
||||
const { t, theme } = useUi();
|
||||
const { user } = useAuth();
|
||||
const compact = mode === 'compact';
|
||||
const items = ITEMS.filter((item) => !item.superadminOnly || user?.roleCode === 'superadmin');
|
||||
return (
|
||||
<nav className={`nav-view ${mode}`}>
|
||||
<div className="nav-header">
|
||||
@@ -25,7 +28,7 @@ export function NavigationView({ mode }) {
|
||||
)}
|
||||
</div>
|
||||
<div className="nav-items">
|
||||
{ITEMS.map((item) => (
|
||||
{items.map((item) => (
|
||||
<NavLink key={item.to} to={item.to} end={item.end} className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`}>
|
||||
<item.icon />
|
||||
{mode !== 'compact' && <span>{t(item.labelKey)}</span>}
|
||||
|
||||
Reference in New Issue
Block a user