import * as React from 'react';
import PropTypes from 'prop-types';
import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
import Box from '@mui/material/Box';
import Drawer from '@mui/material/Drawer';
import List from '@mui/material/List';
import Toolbar from '@mui/material/Toolbar';
import PersonIcon from '@mui/icons-material/Person';
import BarChartIcon from '@mui/icons-material/BarChart';
import DescriptionIcon from '@mui/icons-material/Description';
import LayersIcon from '@mui/icons-material/Layers';
import { matchPath, useLocation } from 'react-router';
import DashboardSidebarContext from '../context/DashboardSidebarContext';
import { DRAWER_WIDTH, MINI_DRAWER_WIDTH } from '../constants';
import DashboardSidebarPageItem from './DashboardSidebarPageItem';
import DashboardSidebarHeaderItem from './DashboardSidebarHeaderItem';
import DashboardSidebarDividerItem from './DashboardSidebarDividerItem';
import {
getDrawerSxTransitionMixin,
getDrawerWidthTransitionMixin,
} from '../mixins';
function DashboardSidebar({
expanded = true,
setExpanded,
disableCollapsibleSidebar = false,
container,
}) {
const theme = useTheme();
const { pathname } = useLocation();
const [expandedItemIds, setExpandedItemIds] = React.useState([]);
const isOverSmViewport = useMediaQuery(theme.breakpoints.up('sm'));
const isOverMdViewport = useMediaQuery(theme.breakpoints.up('md'));
const [isFullyExpanded, setIsFullyExpanded] = React.useState(expanded);
const [isFullyCollapsed, setIsFullyCollapsed] = React.useState(!expanded);
React.useEffect(() => {
if (expanded) {
const drawerWidthTransitionTimeout = setTimeout(() => {
setIsFullyExpanded(true);
}, theme.transitions.duration.enteringScreen);
return () => clearTimeout(drawerWidthTransitionTimeout);
}
setIsFullyExpanded(false);
return () => {};
}, [expanded, theme.transitions.duration.enteringScreen]);
React.useEffect(() => {
if (!expanded) {
const drawerWidthTransitionTimeout = setTimeout(() => {
setIsFullyCollapsed(true);
}, theme.transitions.duration.leavingScreen);
return () => clearTimeout(drawerWidthTransitionTimeout);
}
setIsFullyCollapsed(false);
return () => {};
}, [expanded, theme.transitions.duration.leavingScreen]);
const mini = !disableCollapsibleSidebar && !expanded;
const handleSetSidebarExpanded = React.useCallback(
(newExpanded) => () => {
setExpanded(newExpanded);
},
[setExpanded],
);
const handlePageItemClick = React.useCallback(
(itemId, hasNestedNavigation) => {
if (hasNestedNavigation && !mini) {
setExpandedItemIds((previousValue) =>
previousValue.includes(itemId)
? previousValue.filter(
(previousValueItemId) => previousValueItemId !== itemId,
)
: [...previousValue, itemId],
);
} else if (!isOverSmViewport && !hasNestedNavigation) {
setExpanded(false);
}
},
[mini, setExpanded, isOverSmViewport],
);
const hasDrawerTransitions =
isOverSmViewport && (!disableCollapsibleSidebar || isOverMdViewport);
const getDrawerContent = React.useCallback(
(viewport) => (
Main items
}
href="/employees"
selected={!!matchPath('/employees/*', pathname) || pathname === '/'}
/>
Example items
}
href="/reports"
selected={!!matchPath('/reports', pathname)}
defaultExpanded={!!matchPath('/reports', pathname)}
expanded={expandedItemIds.includes('reports')}
nestedNavigation={
}
href="/reports/sales"
selected={!!matchPath('/reports/sales', pathname)}
/>
}
href="/reports/traffic"
selected={!!matchPath('/reports/traffic', pathname)}
/>
}
/>
}
href="/integrations"
selected={!!matchPath('/integrations', pathname)}
/>
),
[mini, hasDrawerTransitions, isFullyExpanded, expandedItemIds, pathname],
);
const getDrawerSharedSx = React.useCallback(
(isTemporary) => {
const drawerWidth = mini ? MINI_DRAWER_WIDTH : DRAWER_WIDTH;
return {
displayPrint: 'none',
width: drawerWidth,
flexShrink: 0,
...getDrawerWidthTransitionMixin(expanded),
...(isTemporary ? { position: 'absolute' } : {}),
[`& .MuiDrawer-paper`]: {
position: 'absolute',
width: drawerWidth,
boxSizing: 'border-box',
backgroundImage: 'none',
...getDrawerWidthTransitionMixin(expanded),
},
};
},
[expanded, mini],
);
const sidebarContextValue = React.useMemo(() => {
return {
onPageItemClick: handlePageItemClick,
mini,
fullyExpanded: isFullyExpanded,
fullyCollapsed: isFullyCollapsed,
hasDrawerTransitions,
};
}, [
handlePageItemClick,
mini,
isFullyExpanded,
isFullyCollapsed,
hasDrawerTransitions,
]);
return (
{getDrawerContent('phone')}
{getDrawerContent('tablet')}
{getDrawerContent('desktop')}
);
}
DashboardSidebar.propTypes = {
container: (props, propName) => {
if (props[propName] == null) {
return null;
}
if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) {
return new Error(`Expected prop '${propName}' to be of type Element`);
}
return null;
},
disableCollapsibleSidebar: PropTypes.bool,
expanded: PropTypes.bool,
setExpanded: PropTypes.func.isRequired,
};
export default DashboardSidebar;