mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-05-01 14:09:57 -05:00
fix: added nested nav list
This commit is contained in:
@@ -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,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 |
@@ -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 |
Reference in New Issue
Block a user