fix: version 2.4.0 -- menu lateral como drawer en celular

En pantallas angostas (<=768px) el sidebar arranca oculto y se abre
como panel superpuesto desde el boton de hamburguesa, con fondo
oscuro detras y cierre automatico al navegar o tocar afuera. El
escritorio no se toca: sigue igual que siempre.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-09-22 13:20:30 -05:00
parent ea0feb7e3a
commit 9b20f85ae0
7 changed files with 61 additions and 10 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "project-linkedcorp-frontend",
"private": true,
"version": "2.3.0",
"version": "2.4.0",
"type": "module",
"scripts": {
"dev": "vite",
+17 -2
View File
@@ -16,8 +16,11 @@ import { getUpdateStatus } from '../services/updater.js';
const EMPTY_PASSWORD_FORM = { currentPassword: '', newPassword: '', confirmPassword: '' };
const MOBILE_BREAKPOINT = 768;
export default function AppShell() {
const [navMode, setNavMode] = useState('expanded');
const [mobileNavOpen, setMobileNavOpen] = useState(false);
const { user, logout } = useAuth();
const { t, theme, setTheme, lang, setLang, pushToast, openDialog } = useUi();
const navigate = useNavigate();
@@ -54,8 +57,19 @@ export default function AppShell() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// En celular el boton de hamburguesa abre/cierra el drawer superpuesto (mobileNavOpen); en
// escritorio, sigue alternando el riel expandido/compacto de siempre -- son dos estados
// independientes para no tocar el comportamiento de escritorio ya existente.
function toggleNav() {
setNavMode((m) => (m === 'expanded' ? 'compact' : 'expanded'));
if (window.innerWidth <= MOBILE_BREAKPOINT) {
setMobileNavOpen((v) => !v);
} else {
setNavMode((m) => (m === 'expanded' ? 'compact' : 'expanded'));
}
}
function closeMobileNav() {
setMobileNavOpen(false);
}
async function handleNotificationClick(notification) {
@@ -92,7 +106,8 @@ export default function AppShell() {
return (
<div className="app-shell">
<NavigationView mode={navMode} />
<NavigationView mode={navMode} mobileOpen={mobileNavOpen} onNavigate={closeMobileNav} />
<div className={`nav-backdrop ${mobileNavOpen ? 'visible' : ''}`} onClick={closeMobileNav} />
<div className="content-column">
<div className="topbar">
<div className="topbar-left">
+7 -5
View File
@@ -17,15 +17,17 @@ const ITEMS = [
{ to: '/configuracion', icon: Settings, labelKey: 'nav_config', superadminOnly: true },
];
export function NavigationView({ mode }) {
export function NavigationView({ mode, mobileOpen, onNavigate }) {
const { t, theme } = useUi();
const { user } = useAuth();
const branding = useBranding();
const compact = mode === 'compact';
// En celular el drawer siempre se ve completo (con etiquetas), sin importar el modo
// compacto/expandido del riel de escritorio -- son dos cosas independientes.
const compact = mode === 'compact' && !mobileOpen;
const items = ITEMS.filter((item) => !item.superadminOnly || user?.roleCode === 'superadmin');
const brandName = branding.name || t('appName');
return (
<nav className={`nav-view ${mode}`}>
<nav className={`nav-view ${mode} ${mobileOpen ? 'mobile-open' : ''}`}>
{branding.logoUrl && (
<div className="nav-header">
<img
@@ -37,9 +39,9 @@ export function NavigationView({ mode }) {
)}
<div className="nav-items">
{items.map((item) => (
<NavLink key={item.to} to={item.to} end={item.end} className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`}>
<NavLink key={item.to} to={item.to} end={item.end} onClick={onNavigate} className={({ isActive }) => `nav-item ${isActive ? 'active' : ''}`}>
<item.icon />
{mode !== 'compact' && <span>{t(item.labelKey)}</span>}
{!compact && <span>{t(item.labelKey)}</span>}
</NavLink>
))}
</div>
+27
View File
@@ -73,6 +73,33 @@ button { font-family: inherit; }
.nav-logo-icon-header { width: 72px; height: 72px; flex: none; object-fit: contain; }
.nav-logo-full-header { height: 64px; width: auto; max-width: 100%; object-fit: contain; }
/* --- Menu lateral en celular: todo lo de acá abajo es exclusivo de pantallas angostas, no
toca nada del layout de escritorio (que sigue con el sidebar fijo de siempre). --- */
.nav-backdrop { display: none; }
@media (max-width: 768px) {
.nav-view, .nav-view.compact, .nav-view.expanded {
position: fixed;
top: 0; left: 0; bottom: 0;
width: 260px;
z-index: 60;
transform: translateX(-100%);
transition: transform .2s ease;
box-shadow: 4px 0 20px rgb(0 0 0 / .4);
}
.nav-view.mobile-open { transform: translateX(0); }
.nav-backdrop {
display: block;
position: fixed; inset: 0;
background: rgb(0 0 0 / .5);
z-index: 55;
opacity: 0; pointer-events: none;
transition: opacity .2s ease;
}
.nav-backdrop.visible { opacity: 1; pointer-events: auto; }
}
.content-column { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.topbar {
height: 84px; flex: none; display: flex; align-items: center; justify-content: space-between;