network-resurrector/frontend/src/components/layout/SideBar.tsx

113 lines
3.4 KiB
TypeScript

import * as React from "react";
import { styled, Theme, CSSObject } from "@mui/material/styles";
import MuiDrawer from "@mui/material/Drawer";
import List from "@mui/material/List";
import Divider from "@mui/material/Divider";
import IconButton from "@mui/material/IconButton";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import { useNavigate } from "react-router-dom";
import { drawerWidth } from "./constants";
import MenuItem from "./MenuItem";
import { useTranslation } from "react-i18next";
import { menu } from "./constants";
const openedMixin = (theme: Theme): CSSObject => ({
width: drawerWidth,
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
}),
overflowX: "hidden"
});
const closedMixin = (theme: Theme): CSSObject => ({
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
}),
overflowX: "hidden",
width: `calc(${theme.spacing(7)} + 1px)`,
[theme.breakpoints.up("sm")]: {
width: `calc(${theme.spacing(8)} + 1px)`
}
});
const DrawerHeader = styled("div")(({ theme }) => ({
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar
}));
const Drawer = styled(MuiDrawer, { shouldForwardProp: prop => prop !== "open" })(({ theme, open }) => ({
width: drawerWidth,
flexShrink: 0,
whiteSpace: "nowrap",
boxSizing: "border-box",
...(open && {
...openedMixin(theme),
"& .MuiDrawer-paper": openedMixin(theme)
}),
...(!open && {
...closedMixin(theme),
"& .MuiDrawer-paper": closedMixin(theme)
})
}));
type SideBarProps = {
open: boolean;
onDrawerOpen: () => void;
onDrawerClose: () => void;
};
const SideBar: React.FC<SideBarProps> = ({ open, onDrawerOpen, onDrawerClose }) => {
const navigate = useNavigate();
const { t } = useTranslation();
menu.sort((a, b) => (a.order || 0) - (b.order || 0));
return (
<Drawer variant="permanent" open={open}>
<DrawerHeader>
<IconButton onClick={open ? onDrawerClose : onDrawerOpen}>
{open ? <ChevronLeftIcon /> : <ChevronRightIcon />}
</IconButton>
</DrawerHeader>
<Divider />
{menu.map((section, index) => {
const isLast = index === menu.length - 1;
return (
<React.Fragment key={`section-${section.order}`}>
<List>
{section.items
.sort((i1, i2) => i1.order - i2.order)
.map(item => (
<MenuItem
key={`${item.code}-${index}`}
open={open}
icon={item.icon}
label={t(item.name)}
onClick={item.subMenus ? undefined : () => navigate(item.route)}
subMenus={item.subMenus?.map(si => ({
open,
icon: si.icon,
label: t(si.name),
onClick: () => navigate(si.route)
}))}
/>
))}
</List>
{!isLast && <Divider />}
</React.Fragment>
);
})}
</Drawer>
);
};
export default SideBar;