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;