|
- import { ExpandLess, ExpandMore } from "@mui/icons-material";
- import HomeIcon from "@mui/icons-material/Home";
- import PeopleIcon from "@mui/icons-material/People";
- import SettingsIcon from "@mui/icons-material/Settings";
- import { Collapse } from "@mui/material";
- import Box from "@mui/material/Box";
- import Divider from "@mui/material/Divider";
- import Drawer, { DrawerProps } from "@mui/material/Drawer";
- import List from "@mui/material/List";
- import ListItem from "@mui/material/ListItem";
- import ListItemButton from "@mui/material/ListItemButton";
- import ListItemIcon from "@mui/material/ListItemIcon";
- import ListItemText from "@mui/material/ListItemText";
- import { PageID } from "codes/page";
- import useAuth from "hooks/useAuth";
- import useNavigateCustom from "hooks/useNavigateCustom";
- import usePage from "hooks/usePage";
- import * as React from "react";
- import { getPath } from "routes/path";
-
- type Group = {
- label: string;
- children: SubGroup[];
- };
-
- type SubGroup = {
- label: string;
- icon: React.ReactNode;
- children?: Child[];
-
- // 子要素を持たない場合は設定
- id?: PageID;
- };
-
- type Child = {
- label: string;
- id: PageID;
- };
-
- const categories: Group[] = [
- {
- label: "管理",
- children: [
- {
- label: "契約",
- icon: <PeopleIcon />,
- children: [
- {
- id: PageID.DASHBOARD_CONTRACT_LIST,
- label: "一覧",
- },
- {
- id: PageID.DASHBOARD_CONTRACT_DETAIL,
- label: "詳細",
- },
- ],
- },
- {
- label: "領収証発行依頼",
- icon: <PeopleIcon />,
- children: [
- {
- id: PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_LIST,
- label: "一覧",
- },
- {
- id: PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_CREATE,
- label: "新規",
- },
- ],
- },
- ],
- },
- {
- label: "アカウント",
- children: [
- { label: "ログアウト", icon: <SettingsIcon />, id: PageID.LOGOUT },
- ],
- },
- ];
-
- const item = {
- py: "2px",
- px: 3,
- color: "rgba(255, 255, 255, 0.7)",
- "&:hover, &:focus": {
- bgcolor: "rgba(255, 255, 255, 0.08)",
- },
- };
-
- const itemCategory = {
- boxShadow: "0 -1px 0 rgb(255,255,255,0.1) inset",
- py: 1.5,
- px: 3,
- };
-
- export default function Navigator(props: DrawerProps) {
- const { ...other } = props;
-
- return (
- <Drawer variant="permanent" {...other}>
- <List disablePadding>
- <ListItem
- sx={{ ...item, ...itemCategory, fontSize: 22, color: "#fff" }}
- >
- SateReceipt
- </ListItem>
- <ListItem sx={{ ...item, ...itemCategory }}>
- <ListItemIcon>
- <HomeIcon />
- </ListItemIcon>
- <ListItemText>Project Overview</ListItemText>
- </ListItem>
-
- {categories.map((group, index) => {
- return <Group {...group} key={index} />;
- })}
- </List>
- </Drawer>
- );
- }
-
- function Group(group: Group) {
- const { label, children } = group;
-
- const elements = children.map((ele, index) => (
- <SubGroup {...ele} key={index} />
- ));
-
- if (elements.length === 0) return null;
-
- return (
- <Box sx={{ bgcolor: "#101F33" }}>
- <ListItem sx={{ py: 2, px: 3 }}>
- <ListItemText sx={{ color: "#fff" }}>{label}</ListItemText>
- </ListItem>
- {elements}
- <Divider sx={{ mt: 2 }} />
- </Box>
- );
- }
-
- function SubGroup({ icon, label, id, children }: SubGroup) {
- const { pageId } = usePage();
- const { navigateWhenChanged } = useNavigateCustom();
-
- const { elements, shouldOpen } = useContents(children ?? []);
-
- const [open, setOpen] = React.useState(false);
-
- React.useEffect(() => {
- setOpen(shouldOpen);
- }, [shouldOpen]);
-
- // 子要素ありの場合
- if (elements && elements.length !== 0) {
- const handleClick = () => {
- setOpen(!open);
- };
- return (
- <>
- <ListItemButton onClick={handleClick} sx={item} selected={false}>
- <ListItemIcon>{icon}</ListItemIcon>
- <ListItemText>{label}</ListItemText>
- {open ? <ExpandLess /> : <ExpandMore />}
- </ListItemButton>
- <Collapse in={open} timeout="auto" unmountOnExit>
- <List component="div" disablePadding>
- {elements}
- </List>
- </Collapse>
- </>
- );
- }
- // 子要素なしの場合
- if (id !== undefined) {
- const handleClick = () => {
- if (id) {
- const path = getPath(id);
- navigateWhenChanged(path);
- }
- };
- const selected = id === pageId;
- return (
- <ListItemButton onClick={handleClick} selected={selected} sx={item}>
- <ListItemIcon>{icon}</ListItemIcon>
- <ListItemText>{label}</ListItemText>
- </ListItemButton>
- );
- }
- return null;
- }
-
- function useContents(children: Child[]) {
- const { pageId } = usePage();
- const { navigateWhenChanged } = useNavigateCustom();
- const { canAccess, initialized } = useAuth();
-
- const [shouldOpen, setShouldOpen] = React.useState(false);
-
- const elements = React.useMemo(() => {
- setShouldOpen(false);
- return children
- .filter(({ id }) => canAccess(id))
- .map(({ label, id }, index) => {
- const selected = id === pageId;
- if (selected) {
- setShouldOpen(true);
- }
-
- const handleClick = () => {
- const path = getPath(id);
- navigateWhenChanged(path);
- };
-
- return (
- <ListItemButton
- selected={selected}
- sx={{ ...item, pl: 4 }}
- key={index}
- onClick={handleClick}
- >
- <ListItemText primary={label} />
- </ListItemButton>
- );
- });
- }, [pageId, initialized]);
-
- return {
- elements,
- shouldOpen,
- };
- }
|