Files
fendi-react-app/src/components/MenuDrawer.jsx
2025-08-12 17:31:48 -06:00

229 lines
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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: 'Logout', icon: <ExitToAppIcon /> },
],
restricted: [],
private: [
{ text: 'Dashboard', icon: <img src="/Dashboard.png" alt="Dashboard" width={24} height={24} /> },
{ text: 'Catalog', icon: <img src="/Catalog.png" alt="Catalog" width={24} height={24} /> },
{ text: 'Define your style', icon: <img src="/DefineYourStyle.png" alt="Define your style" width={24} height={24} /> },
{ text: 'Ambient Design', icon: <img src="/AmbientDesign.png" alt="Ambient Design" width={24} height={24} /> },
{ text: 'Flat Layouts and assets', icon: <img src="/FlatLayouts.png" alt="Flat Layouts and assets" width={24} height={24} /> },
{ text: 'Export and sharing', icon: <img src="/ExportAndSharing.png" alt="Export and sharing" width={24} height={24} /> },
{ text: 'Shopping cart', icon: <img src="/ShoppingCart.png" alt="Shopping cart" width={24} height={24} /> },
{ text: 'Settings', icon: <img src="/Settings.png" alt="Settings" width={24} height={24} /> },
{ text: 'Help', icon: <img src="/Help.png" alt="Help" width={24} height={24} /> },
{ text: 'Logout', icon: <ExitToAppIcon /> },
],
};
// 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"
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',
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)',
},
}}
>
{/* 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"
/>
<InputBase
placeholder="Filter options..."
sx={{
pl: 1.5,
pr: 1.5,
py: 0.75,
borderRadius: 2,
border: '1px solid #40120EFF',
color: '#40120EFF',
width: '100%',
}}
/>
</Box>
)}
</Box>
{/* Collapsed */}
{collapsed && (
<Box textAlign="center" p={3} minHeight={112} justifyContent="center" display="flex"
alignItems="start">
<img
style={{ marginTop: 5 }}
src="MiniLogo.png"
alt="Dream Views"
/>
</Box>
)}
{/* Items */}
<List sx={{
width: '100%',
py: 0,
display: 'flex',
flexDirection: 'column',
alignItems: 'stretch'
}}>
{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 ? 0 : 2,
minHeight: collapsed ? 48 : 44,
cursor: 'pointer',
justifyContent: collapsed ? 'center' : 'flex-start',
width: '100%',
}}
>
<ListItemIcon
sx={{
color: '#40120EFF',
minWidth: collapsed ? 'auto' : 40,
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: 2,
width: 40,
height: 40,
}}>
<img
src={collapsed ? '/Expand.png' : '/Contract.png'}
alt={collapsed ? 'Expand' : 'Contract'}
width={24}
height={24}
/>
</IconButton>
</Tooltip>
</Drawer>
);
}