chore: show icons only when collapsed

This commit is contained in:
Rodolfo Ruiz
2025-08-12 17:13:24 -06:00
parent 7714a6c704
commit 4ac86a9097
5 changed files with 188 additions and 70 deletions

BIN
public/Expand.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

BIN
public/MiniLogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,9 +1,7 @@
import { useState } from 'react';
import fendiLogo from '/favicon.png'
import { AppBar, Toolbar, Typography, IconButton, Box, Avatar } from '@mui/material';
import MenuDrawer from './MenuDrawer';
import MenuIcon from '@mui/icons-material/Menu';
import { useAuth } from '../context/AuthContext';
import { useNavigate } from 'react-router-dom';
@@ -15,7 +13,7 @@ export default function AppHeader({ zone = 'public', onSelectMenuItem }) {
private: '#40120EFF',
};
const [menuOpen, setMenuOpen] = useState(false);
const [drawerExpanded, setDrawerExpanded] = useState(true);
const { user, logout } = useAuth();
const isPrivate = zone === 'private';
@@ -33,11 +31,6 @@ export default function AppHeader({ zone = 'public', onSelectMenuItem }) {
fontSize: { xs: '0.75rem', md: '1rem' },
}} >
<Toolbar sx={{ justifyContent: 'space-between', flexWrap: 'wrap' }}>
<Box display="flex" alignItems="center">
<IconButton edge="start" color="inherit" onClick={() => setMenuOpen(true)}>
<MenuIcon />
</IconButton>
</Box>
{/* Login button only visible for public zone */}
{isPublic && !user && (
@@ -60,8 +53,8 @@ export default function AppHeader({ zone = 'public', onSelectMenuItem }) {
{/* Rendering the Drawer */}
<MenuDrawer
zone="private"
open={menuOpen}
onClose={() => setMenuOpen(false)}
open={drawerExpanded}
onClose={() => setDrawerExpanded(false)}
onSelect={onSelectMenuItem} // pass handler from App
/>

View File

@@ -1,5 +1,5 @@
import { Box, Typography } from '@mui/material';
import fendiLogo from '/logo.png'
import fendiLogo from '/Logo.png'
export default function Footer({ zone = 'public' }) {
const bgColor = {

View File

@@ -1,12 +1,26 @@
import { Drawer, List, ListItem, ListItemText, ListItemIcon, Typography, Box, useMediaQuery, InputBase } from '@mui/material';
import {
Drawer,
List,
ListItem,
ListItemText,
ListItemIcon,
IconButton,
Box,
useMediaQuery,
InputBase,
Tooltip,
Divider
} from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { useEffect, useMemo, useState } from 'react';
import { useAuth } from '../context/AuthContext';
import ExitToAppIcon from '@mui/icons-material/ExitToApp';
// ---- Menu options (unchanged) ----
const menuOptions = {
public: [
{ text: 'Dashboard', icon: <img src="/Dashboard.png" alt="Dashboard" width={24} height={24} />},
{ text: 'Dashboard', icon: <img src="/Dashboard.png" alt="Dashboard" width={24} height={24} /> },
{ text: 'Logout', icon: <ExitToAppIcon /> },
],
restricted: [],
@@ -24,72 +38,183 @@ const menuOptions = {
],
};
export default function MenuDrawer({ zone = 'public', open, onClose, onSelect }) {
const isMobile = useMediaQuery('(max-width:900px)');
const items = menuOptions[zone];
// Minivariant sizes
const OPEN_WIDTH = 300;
const MINI_WIDTH = 72;
export default function MenuDrawer({ zone = 'public', open, onClose, onSelect }) {
const theme = useTheme();
const isMobile = useMediaQuery('(max-width:900px)');
const items = useMemo(() => menuOptions[zone] ?? [], [zone]);
const { logout } = useAuth();
// Collapsed state is only meaningful on desktop (permanent drawer)
const [collapsed, setCollapsed] = useState(false);
// Interpret parent "open" prop:
// - Mobile (temporary): open controls visibility
// - Desktop (permanent): open=true => expanded, open=false => collapsed
useEffect(() => {
if (!isMobile) {
setCollapsed(!open);
}
}, [open, isMobile]);
const paperWidth = isMobile ? OPEN_WIDTH : (collapsed ? MINI_WIDTH : OPEN_WIDTH);
return (
<Drawer anchor="left" open={open} onClose={onClose} slotProps={{
paper: {
sx: {
<Drawer
anchor="left"
variant={isMobile ? 'temporary' : 'permanent'}
open={isMobile ? open : true}
onClose={isMobile ? onClose : undefined}
ModalProps={{ keepMounted: true }}
sx={{
width: paperWidth,
flexShrink: 0,
'& .MuiDrawer-paper': {
width: paperWidth,
boxSizing: 'border-box',
backgroundColor: '#FFFFFFFF',
width: isMobile ? '100vw' : 300,
color: '#40120EFF'
color: '#40120EFF',
transition: theme.transitions.create('width', {
duration: theme.transitions.duration.standard,
easing: theme.transitions.easing.sharp,
}),
borderRight: '1px solid rgba(0,0,0,0.08)',
},
},
}}>
<Box textAlign="center" p={3}>
<img
src="/logo.png"
alt="Dream Views"
style={{ margin: 'auto', marginBottom: 8 }}
/>
}}
>
{/* Header */}
<Box
sx={{
display: 'flex',
alignItems: 'center',
gap: 1,
px: collapsed ? 1 : 2,
py: 1.5,
justifyContent: collapsed ? 'center' : 'space-between',
}}
>
{/* Expanded - default */}
{!collapsed && (
<Box textAlign="center" p={3} alignItems="center" minHeight={72}>
<img
src="Logo.png"
alt="Dream Views"
/>
<Box sx={{ position: 'relative', display: { xs: 'none', md: 'flex' } }}>
<InputBase
placeholder="Filter options..."
sx={{
pl: 4,
pr: 2,
py: 0.5,
borderRadius: 2,
border: '1px solid #40120EFF', // Borde visible
color: '#40120EFF',
width: { md: '300px', lg: '400px' }
}}
/>
</Box>
</Box>
<List sx={{ width: isMobile ? '100vw' : 250, marginTop: 0 }}>
{items.map(({ text, icon }, index) => (
<ListItem key={index} onClick={() => {
onClose(); // Close drawer
onSelect?.(text); // Notify parent of selected item
if (text === 'Logout') {
logout(); // cerrar sesión y redirigir
} else {
onSelect?.(text); // navegar al resto de vistas
}
}}>
<ListItemIcon sx={{ color: '#40120EFF' }}>{icon}</ListItemIcon>
<ListItemText
primary={text}
slotProps={{
primary: {
sx: {
color: '#40120EFF',
fontWeight: 'medium',
},
},
<InputBase
placeholder="Filter options..."
sx={{
pl: 1.5,
pr: 1.5,
py: 0.75,
borderRadius: 2,
border: '1px solid #40120EFF',
color: '#40120EFF',
width: '100%',
}}
/>
</ListItem>
))}
</Box>
)}
</Box>
{/* Collapsed */}
{collapsed && (
<Box textAlign="center" p={3} alignItems="center" minHeight={112}>
<img
src="MiniLogo.png"
alt="Dream Views"
/>
</Box>
)}
{/* Items */}
<List sx={{ width: '100%', py: 0 }}>
{items.map(({ text, icon }, index) => {
// Default items
return (
<Tooltip
key={`${text}-${index}`}
title={collapsed ? (text || ' ') : ''}
placement="right"
disableHoverListener={!collapsed}
>
<ListItem
onClick={() => {
if (isMobile) onClose?.();
if (text === 'Logout') {
logout();
} else {
onSelect?.(text);
}
}}
sx={{
px: collapsed ? 1 : 2,
minHeight: 44,
cursor: 'pointer',
justifyContent: collapsed ? 'center' : 'flex-start',
width: collapsed ? 50 : '100%',
}}
>
<ListItemIcon
sx={{
color: '#40120EFF',
minWidth: 0,
mr: collapsed ? 0 : 1.5,
justifyContent: 'center',
}}
>
{icon}
</ListItemIcon>
{!collapsed && (
<ListItemText
primary={text}
sx={{
opacity: 1,
transition: theme.transitions.create('opacity', {
duration: theme.transitions.duration.shortest,
}),
whiteSpace: 'nowrap',
}}
slotProps={{
primary: {
sx: {
color: '#40120EFF',
fontWeight: 'medium',
},
},
}}
/>
)}
</ListItem>
</Tooltip>
);
})}
</List>
<Tooltip title={collapsed ? 'Expand' : 'Collapse'} placement="right">
<IconButton onClick={() => setCollapsed((c) => !c)} sx={{
backgroundColor: 'transparent',
color: 'transparent',
'&:hover': {
backgroundColor: '#fff4ec',
borderColor: 'transparent'
},
borderRadius: 0,
marginLeft: 1,
width: 40,
height: 40,
}}>
<img
src={collapsed ? '/Expand.png' : '/Contract.png'}
alt={collapsed ? 'Expand' : 'Contract'}
width={24}
height={24}
/>
</IconButton>
</Tooltip>
</Drawer>
);
}