fix: added nested nav list

This commit is contained in:
Daniel Cojocea
2024-08-16 12:13:05 -04:00
parent 4b4af5aa24
commit d9360ee8eb
3 changed files with 87 additions and 88 deletions
+83 -87
View File
@@ -1,13 +1,12 @@
import { useState } from "react";
import {
Box,
Collapse,
List,
ListItemButton,
ListItemIcon,
ListItemText,
ListSubheader,
Menu,
MenuItem,
Stack,
Tooltip,
Typography,
@@ -31,17 +30,33 @@ import Incidents from "../../assets/icons/incidents.svg?react";
import Integrations from "../../assets/icons/integrations.svg?react";
import PageSpeed from "../../assets/icons/page-speed.svg?react";
import Settings from "../../assets/icons/settings.svg?react";
import Arrow from "../../assets/icons/down-arrow.svg?react";
import ArrowDown from "../../assets/icons/down-arrow.svg?react";
import ArrowUp from "../../assets/icons/up-arrow.svg?react";
import "./index.css";
const menu = [
{ name: "Monitors", path: "monitors", icon: <Monitors /> },
{
name: "Dashboard",
icon: <Monitors />,
nested: [
{ name: "Monitors", path: "monitors", icon: <Monitors /> },
{ name: "Pagespeed", path: "pagespeed", icon: <PageSpeed /> },
],
},
{ name: "Incidents", path: "incidents", icon: <Incidents /> },
{ name: "Status pages", path: "status", icon: <StatusPages /> },
{ name: "Maintenance", path: "maintenance", icon: <Maintenance /> },
{ name: "Page speed", path: "pagespeed", icon: <PageSpeed /> },
{ name: "Integrations", path: "integrations", icon: <Integrations /> },
{
name: "Account",
icon: <UserSvg />,
nested: [
{ name: "Profile", path: "account/profile", icon: <UserSvg /> },
{ name: "Password", path: "account/password", icon: <TeamSvg /> },
{ name: "Team", path: "account/team", icon: <LockSvg /> },
],
},
];
const other = [
@@ -49,13 +64,6 @@ const other = [
{ name: "Settings", path: "settings", icon: <Settings /> },
];
const icons = {
Profile: <UserSvg />,
Team: <TeamSvg />,
Password: <LockSvg />,
Logout: <LogoutSvg />,
};
/**
* @component
* Sidebar component serves as a sidebar containing a menu.
@@ -68,8 +76,8 @@ function Sidebar() {
const navigate = useNavigate();
const location = useLocation();
const dispatch = useDispatch();
const [anchorElUser, setAnchorElUser] = useState(null);
const authState = useSelector((state) => state.auth);
const [open, setOpen] = useState({ Dashboard: false, Account: false });
// Initialize settings and update based on user role
let settings = ["Profile", "Password", "Team", "Logout"];
@@ -77,15 +85,6 @@ function Sidebar() {
settings = ["Profile", "Password", "Logout"];
}
/**
* Handles opening the user menu.
*
* @param {React.MouseEvent<HTMLElement>} event - The event triggered by clicking the user menu button.
*/
const handleOpenUserMenu = (event) => {
setAnchorElUser(event.currentTarget);
};
/**
* Handles logging out the user
*
@@ -97,29 +96,6 @@ function Sidebar() {
navigate("/login");
};
/**
* Handles closing the user menu.
*/
const handleCloseUserMenu = (setting) => {
setAnchorElUser(null);
switch (setting) {
case "Profile":
navigate("/account/profile");
break;
case "Team":
navigate("/account/team");
break;
case "Password":
navigate("/account/password");
break;
case "Logout":
logout();
break;
default:
break;
}
};
return (
<Stack component="aside" gap={theme.gap.large}>
<Box pt={theme.gap.large} pl={theme.gap.ml} pb={theme.gap.xs}>
@@ -136,22 +112,68 @@ function Sidebar() {
}
sx={{ width: "100%" }}
>
{menu.map((item) => (
<ListItemButton
className={
location.pathname.includes(item.path) ? "selected-path" : ""
}
key={item.path}
onClick={() => navigate(`/${item.path}`)}
sx={{
gap: theme.gap.medium,
borderRadius: `${theme.shape.borderRadius}px`,
}}
>
<ListItemIcon sx={{ minWidth: 0 }}>{item.icon}</ListItemIcon>
<ListItemText>{item.name}</ListItemText>
</ListItemButton>
))}
{menu.map((item) =>
item.path ? (
<ListItemButton
className={
location.pathname.includes(item.path) ? "selected-path" : ""
}
key={item.path}
onClick={() => navigate(`/${item.path}`)}
sx={{
gap: theme.gap.medium,
borderRadius: `${theme.shape.borderRadius}px`,
}}
>
<ListItemIcon sx={{ minWidth: 0 }}>{item.icon}</ListItemIcon>
<ListItemText>{item.name}</ListItemText>
</ListItemButton>
) : (
<>
<ListItemButton
key={item.name}
onClick={() =>
setOpen((prev) => ({
...prev,
[`${item.name}`]: !prev[`${item.name}`],
}))
}
sx={{
gap: theme.gap.medium,
borderRadius: `${theme.shape.borderRadius}px`,
}}
>
<ListItemIcon sx={{ minWidth: 0 }}>{item.icon}</ListItemIcon>
<ListItemText>{item.name}</ListItemText>
{open[`${item.name}`] ? <ArrowUp /> : <ArrowDown />}
</ListItemButton>
<Collapse in={open[`${item.name}`]} timeout="auto" unmountOnExit>
<List component="div" disablePadding sx={{ pl: theme.gap.large }}>
{item.nested.map((child) => (
<ListItemButton
className={
location.pathname.includes(child.path)
? "selected-path"
: ""
}
key={child.path}
onClick={() => navigate(`/${child.path}`)}
sx={{
gap: theme.gap.medium,
borderRadius: `${theme.shape.borderRadius}px`,
}}
>
<ListItemIcon sx={{ minWidth: 0 }}>
{child.icon}
</ListItemIcon>
<ListItemText>{child.name}</ListItemText>
</ListItemButton>
))}
</List>
</Collapse>
</>
)
)}
</List>
{/* other */}
<List
@@ -211,39 +233,13 @@ function Sidebar() {
px={theme.gap.medium}
gap={theme.gap.xs}
borderRadius={`${theme.shape.borderRadius}px`}
onClick={handleOpenUserMenu}
>
<Avatar small={true} />
<Typography component="span" ml={theme.gap.xs}>
{authState.user?.firstName} {authState.user?.lastName}
</Typography>
<Arrow style={{ marginTop: "2px", marginLeft: "auto" }} />
</Stack>
</Tooltip>
<Menu
className="sidebar-menu"
anchorEl={anchorElUser}
anchorOrigin={{
vertical: "top",
horizontal: "center",
}}
keepMounted
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}
autoFocus={false}
sx={{
ml: theme.gap.xxl,
}}
>
{settings.map((setting) => (
<MenuItem key={setting} onClick={() => handleCloseUserMenu(setting)}>
{icons[setting]}
<Typography component="span" ml={theme.gap.small}>
{setting}
</Typography>
</MenuItem>
))}
</Menu>
</Stack>
);
}
+1 -1
View File
@@ -1,3 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 9L12 15L18 9" stroke="#667085" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6 9L12 15L18 9" stroke="#667085" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 214 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18 15L12 9L6 15" stroke="#667085" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 215 B