LFFE-6 sidebar improvement

This commit is contained in:
Yasiu1376
2023-11-05 14:53:25 +03:30
parent c900226823
commit c745791c59
4 changed files with 111 additions and 60 deletions

View File

@@ -1,5 +1,5 @@
import {Divider, List} from "@mui/material";
import {useEffect, useReducer} from "react";
import {Fragment, useEffect, useReducer, useRef, useState} from "react";
import SidebarListItem from "./SidebarListItem";
import sidebarMenu from "@/core/data/sidebarMenu";
import {useRouter} from "next/router";
@@ -10,18 +10,27 @@ function reducer(state, action) {
case "COLLAPSE_MENU":
return state.map((itemsArr) =>
itemsArr.map((item) =>
action.key == item.key
? {...item, showSubItem: !item.showSubItem}
: item
action.key === item.key ? { ...item, showSubItem: !item.showSubItem } : item
)
);
case "SELECTED":
return state.map((itemsArr) =>
itemsArr.map((item) =>
action.route == item.route
? {...item, selected: true}
: {...item, selected: false}
)
itemsArr.map((item) => {
return item.type === "page"
? { ...item, selected: action.route === item.route }
: item.subItem && Array.isArray(item.subItem)
? {
...item,
subItem: item.subItem.map((subitem) => ({
...subitem,
selected: subitem.route === action.route,
})),
showSubItem: item.subItem.some(
(subitem) => subitem.selected
),
}
: item;
})
);
default:
throw new Error();
@@ -32,26 +41,39 @@ export default function SidebarList({handleDrawerToggle}) {
const [itemMenu, dispatch] = useReducer(reducer, sidebarMenu);
const {user} = useUser();
const router = useRouter();
const [selectedKey, setSelectedKey] = useState(null);
useEffect(() => {
dispatch({type: "SELECTED", route: router.pathname});
setSelectedKey(router.pathname);
}, [router.pathname]);
const filteredItemMenu = itemMenu[0].filter(
(item) => user.permissions.includes(item.permission) || item.permission === "all"
);
useEffect(() => {
selectedKey && document.querySelector(`[data-route="${selectedKey}"]`)?.scrollIntoView({
behavior: "smooth",
block: "center"
});
}, [selectedKey]);
return (
<List>
{filteredItemMenu.map((item, index) => (
<SidebarListItem
item={item}
dispatch={dispatch}
key={item.key}
handleDrawerToggle={handleDrawerToggle}
/>
<List sx={{ overflow: "scroll"}}>
{itemMenu.map((itemArr, index) => (
<Fragment key={index}>
{itemArr.map((item) =>
<Fragment key={item.key}>
{(user?.permissions?.includes(item.permission) || item.permission === "all") &&
<SidebarListItem
item={item}
dispatch={dispatch}
handleDrawerToggle={handleDrawerToggle}
/>}
</Fragment>
)}
<Divider/>
</Fragment>
))}
{filteredItemMenu.length > 0 && <Divider/>}
</List>
);
}

View File

@@ -9,23 +9,27 @@ import useNotification from "@/lib/app/hooks/useNotification";
const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => {
const t = useTranslations();
const {notification_count} = useNotification()
const { notification_count } = useNotification();
const hasSubItems = item.type === "menu" && item.subItem && item.subItem.length > 0;
const renderBadge = () => {
return !hasSubItems ? (
<IconButton>
<Badge
badgeContent={notification_count && notification_count.length>0 ? notification_count[item.name] : 0}
color="error"
variant="standard"
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
/>
</IconButton>
) : null;
};
return (
<Fragment key={item.key}>
<ListItem disablePadding secondaryAction={
<IconButton>
<Badge
badgeContent={notification_count ? notification_count[item.name] : 0}
color="error"
variant="standard"
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
/>
</IconButton>
}>
<>
<ListItem data-route={item.route} disablePadding secondaryAction={renderBadge()}>
<ListItemButton
selected={item.selected}
{...(item.type == "page" && {
@@ -35,10 +39,9 @@ const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => {
},
})}
onClick={() => {
if (item.type == "menu") {
dispatch({type: "COLLAPSE_MENU", key: item.key});
if (hasSubItems) {
dispatch({ type: "COLLAPSE_MENU", key: item.key });
}
handleDrawerToggle();
}}
sx={{
minHeight: 48,
@@ -66,9 +69,7 @@ const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => {
}
/>
{item.type == "menu" &&
(item.showSubItem ? <ExpandLess/> : <ExpandMore/>)}
{hasSubItems && (item.showSubItem ? <ExpandLess /> : <ExpandMore />)}
</ListItemButton>
</ListItem>
{item.subItem && (
@@ -77,7 +78,7 @@ const SidebarListItem = ({item, dispatch, handleDrawerToggle}) => {
handleDrawerToggle={handleDrawerToggle}
/>
)}
</Fragment>
</>
);
};

View File

@@ -1,18 +1,43 @@
import {NextLinkComposed} from "@/core/components/LinkRouting";
import InboxIcon from "@mui/icons-material/MoveToInbox";
import {Collapse, List, ListItemButton, ListItemIcon, ListItemText,} from "@mui/material";
import {
Badge,
Collapse,
IconButton,
List,
ListItem,
ListItemButton,
ListItemIcon,
ListItemText,
Typography,
} from "@mui/material";
import {useTranslations} from "next-intl";
import {Fragment} from "react";
import useNotification from "@/lib/app/hooks/useNotification";
const SidebarListSubItem = ({item, handleDrawerToggle}) => {
const SidebarListSubItem = ({item, handleDrawerToggle }) => {
const t = useTranslations();
const {notification_count} = useNotification();
const renderBadge = (subitem) => (
<IconButton>
<Badge
badgeContent={notification_count && notification_count.length>0 ? notification_count[subitem.name] : 0}
color="error"
variant="standard"
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
/>
</IconButton>
);
return (
<Collapse in={item.showSubItem} timeout="auto" unmountOnExit>
<List component="div" disablePadding sx={{bgcolor: "#f6f6f6"}}>
{item.subItem.map((subitem, index) => (
<Fragment key={subitem.key}>
<Collapse in={item.showSubItem} timeout="auto" mountOnEnter={true} unmountOnExit={true}>
<List component="div" disablePadding sx={{bgcolor: "#f6f6f6", pr: 0}}>
{item.subItem.map((subitem) => (
<ListItem key={subitem.key} disablePadding secondaryAction={renderBadge(subitem)}>
<ListItemButton
selected={subitem.selected}
component={NextLinkComposed}
to={{
pathname: subitem.route,
@@ -20,12 +45,6 @@ const SidebarListSubItem = ({item, handleDrawerToggle}) => {
sx={{
minHeight: 48,
}}
onClick={(event) => {
if (item.type == "menu") {
dispatch({type: "COLLAPSE_MENU", key: item.key});
}
handleDrawerToggle();
}}
>
<ListItemIcon
sx={{
@@ -34,14 +53,21 @@ const SidebarListSubItem = ({item, handleDrawerToggle}) => {
pr: 2,
}}
>
<InboxIcon/>
{subitem.icon}
</ListItemIcon>
<ListItemText primary={t(subitem.key)}/>
<ListItemText primary={t(subitem.key)} secondary={
subitem.secondary !== undefined ? (
<Typography variant="caption" color="textSecondary">
{t(subitem.secondary)}
</Typography>
) : null
}/>
</ListItemButton>
</Fragment>
</ListItem>
))}
</List>
</Collapse>
);
};

View File

@@ -21,6 +21,7 @@ const Sidebar = (props) => {
"& .MuiDrawer-paper": {
boxSizing: "border-box",
width: props.drawerWidth,
overflow: "hidden",
},
}}
>
@@ -33,6 +34,7 @@ const Sidebar = (props) => {
"& .MuiDrawer-paper": {
boxSizing: "border-box",
width: props.drawerWidth,
overflow: "hidden",
},
}}
open