160 lines
4.6 KiB
TypeScript
160 lines
4.6 KiB
TypeScript
/**
|
|
* @ai-summary Hamburger menu drawer for mobile navigation
|
|
* @ai-context Bottom slide-up drawer with all navigation options
|
|
*/
|
|
|
|
import React from 'react';
|
|
import {
|
|
Box,
|
|
SwipeableDrawer,
|
|
List,
|
|
ListItemButton,
|
|
ListItemIcon,
|
|
ListItemText,
|
|
Typography,
|
|
useTheme
|
|
} from '@mui/material';
|
|
import HomeRoundedIcon from '@mui/icons-material/HomeRounded';
|
|
import DirectionsCarRoundedIcon from '@mui/icons-material/DirectionsCarRounded';
|
|
import LocalGasStationRoundedIcon from '@mui/icons-material/LocalGasStationRounded';
|
|
import DescriptionRoundedIcon from '@mui/icons-material/DescriptionRounded';
|
|
import BuildRoundedIcon from '@mui/icons-material/BuildRounded';
|
|
import SettingsRoundedIcon from '@mui/icons-material/SettingsRounded';
|
|
import { MobileScreen } from '../../../core/store/navigation';
|
|
|
|
// iOS swipeable drawer configuration
|
|
const iOS = typeof navigator !== 'undefined' && /iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
|
|
interface HamburgerDrawerProps {
|
|
open: boolean;
|
|
onClose: () => void;
|
|
onNavigate: (screen: MobileScreen) => void;
|
|
activeScreen: MobileScreen;
|
|
}
|
|
|
|
interface MenuItem {
|
|
screen: MobileScreen;
|
|
label: string;
|
|
icon: React.ReactNode;
|
|
}
|
|
|
|
// Menu items from bottom to top (reversed order in array for rendering)
|
|
const menuItems: MenuItem[] = [
|
|
{ screen: 'Settings', label: 'Settings', icon: <SettingsRoundedIcon /> },
|
|
{ screen: 'Documents', label: 'Documents', icon: <DescriptionRoundedIcon /> },
|
|
{ screen: 'Maintenance', label: 'Maintenance', icon: <BuildRoundedIcon /> },
|
|
{ screen: 'Log Fuel', label: 'Log Fuel', icon: <LocalGasStationRoundedIcon /> },
|
|
{ screen: 'Vehicles', label: 'Vehicles', icon: <DirectionsCarRoundedIcon /> },
|
|
{ screen: 'Dashboard', label: 'Dashboard', icon: <HomeRoundedIcon /> },
|
|
];
|
|
|
|
export const HamburgerDrawer: React.FC<HamburgerDrawerProps> = ({
|
|
open,
|
|
onClose,
|
|
onNavigate,
|
|
activeScreen
|
|
}) => {
|
|
const theme = useTheme();
|
|
|
|
const handleNavigate = (screen: MobileScreen) => {
|
|
onNavigate(screen);
|
|
onClose();
|
|
};
|
|
|
|
return (
|
|
<SwipeableDrawer
|
|
anchor="bottom"
|
|
open={open}
|
|
onClose={onClose}
|
|
onOpen={() => {}}
|
|
disableSwipeToOpen
|
|
disableBackdropTransition={!iOS}
|
|
disableDiscovery={iOS}
|
|
sx={{
|
|
'& .MuiDrawer-paper': {
|
|
borderTopLeftRadius: 16,
|
|
borderTopRightRadius: 16,
|
|
maxHeight: '60vh',
|
|
overflow: 'visible'
|
|
}
|
|
}}
|
|
>
|
|
<Box sx={{ pb: 4 }}>
|
|
{/* Drawer handle */}
|
|
<Box
|
|
sx={{
|
|
width: 40,
|
|
height: 4,
|
|
backgroundColor: theme.palette.divider,
|
|
borderRadius: 2,
|
|
margin: '12px auto 8px'
|
|
}}
|
|
/>
|
|
|
|
{/* Header */}
|
|
<Typography
|
|
variant="subtitle1"
|
|
sx={{
|
|
fontWeight: 600,
|
|
px: 2,
|
|
py: 1.5,
|
|
color: theme.palette.text.secondary
|
|
}}
|
|
>
|
|
Menu
|
|
</Typography>
|
|
|
|
{/* Menu Items */}
|
|
<List disablePadding>
|
|
{menuItems.map(({ screen, label, icon }) => {
|
|
const isActive = activeScreen === screen;
|
|
return (
|
|
<ListItemButton
|
|
key={screen}
|
|
onClick={() => handleNavigate(screen)}
|
|
sx={{
|
|
py: 1.5,
|
|
px: 2,
|
|
minHeight: 56,
|
|
backgroundColor: isActive
|
|
? theme.palette.primary.main + '14'
|
|
: 'transparent',
|
|
borderLeft: isActive
|
|
? `3px solid ${theme.palette.primary.main}`
|
|
: '3px solid transparent',
|
|
'&:hover': {
|
|
backgroundColor: isActive
|
|
? theme.palette.primary.main + '20'
|
|
: theme.palette.action.hover
|
|
}
|
|
}}
|
|
>
|
|
<ListItemIcon
|
|
sx={{
|
|
minWidth: 40,
|
|
color: isActive
|
|
? theme.palette.primary.main
|
|
: theme.palette.text.secondary
|
|
}}
|
|
>
|
|
{icon}
|
|
</ListItemIcon>
|
|
<ListItemText
|
|
primary={label}
|
|
primaryTypographyProps={{
|
|
fontWeight: isActive ? 600 : 500,
|
|
fontSize: '0.95rem',
|
|
color: isActive
|
|
? theme.palette.primary.main
|
|
: theme.palette.text.primary
|
|
}}
|
|
/>
|
|
</ListItemButton>
|
|
);
|
|
})}
|
|
</List>
|
|
</Box>
|
|
</SwipeableDrawer>
|
|
);
|
|
};
|