import React, { useEffect, useState } from "react"; import { Box, Collapse, Divider, IconButton, List, ListItemButton, ListItemIcon, ListItemText, ListSubheader, Menu, MenuItem, Stack, Tooltip, Typography, } from "@mui/material"; import { useLocation, useNavigate } from "react-router"; import { useTheme } from "@emotion/react"; import { useDispatch, useSelector } from "react-redux"; import { clearAuthState } from "../../Features/Auth/authSlice"; import { toggleSidebar } from "../../Features/UI/uiSlice"; import { clearUptimeMonitorState } from "../../Features/UptimeMonitors/uptimeMonitorsSlice"; import Avatar from "../Avatar"; import LockSvg from "../../assets/icons/lock.svg?react"; import UserSvg from "../../assets/icons/user.svg?react"; import TeamSvg from "../../assets/icons/user-two.svg?react"; import LogoutSvg from "../../assets/icons/logout.svg?react"; import Support from "../../assets/icons/support.svg?react"; import Dashboard from "../../assets/icons/dashboard.svg?react"; import Account from "../../assets/icons/user-edit.svg?react"; import StatusPages from "../../assets/icons/status-pages.svg?react"; import Maintenance from "../../assets/icons/maintenance.svg?react"; import Monitors from "../../assets/icons/monitors.svg?react"; 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 ArrowDown from "../../assets/icons/down-arrow.svg?react"; import ArrowUp from "../../assets/icons/up-arrow.svg?react"; import ArrowRight from "../../assets/icons/right-arrow.svg?react"; import ArrowLeft from "../../assets/icons/left-arrow.svg?react"; import "./index.css"; const menu = [ { name: "Dashboard", icon: , nested: [ { name: "Monitors", path: "monitors", icon: }, { name: "Pagespeed", path: "pagespeed", icon: }, ], }, { name: "Incidents", path: "incidents", icon: }, { name: "Status pages", path: "status", icon: }, { name: "Maintenance", path: "maintenance", icon: }, { name: "Integrations", path: "integrations", icon: }, { name: "Account", icon: , nested: [ { name: "Profile", path: "account/profile", icon: }, { name: "Password", path: "account/password", icon: }, { name: "Team", path: "account/team", icon: }, ], }, ]; const other = [ { name: "Support", path: "support", icon: }, { name: "Settings", path: "settings", icon: }, ]; /** * @component * Sidebar component serves as a sidebar containing a menu. * * @returns {JSX.Element} The JSX element representing the Sidebar component. */ function Sidebar() { const theme = useTheme(); const navigate = useNavigate(); const location = useLocation(); const dispatch = useDispatch(); const authState = useSelector((state) => state.auth); const { sidebar } = useSelector((state) => state.ui); let collapsed = sidebar.collapsed; const [open, setOpen] = useState({ Dashboard: false, Account: false }); const [anchorEl, setAnchorEl] = useState(null); const [popup, setPopup] = useState(); const openPopup = (event, id) => { setAnchorEl(event.currentTarget); setPopup(id); }; const closePopup = () => { setAnchorEl(null); }; /** * Handles logging out the user * */ const logout = async () => { // Clear auth state dispatch(clearAuthState()); dispatch(clearUptimeMonitorState()); navigate("/login"); }; useEffect(() => { if ( location.pathname.includes("monitors") || location.pathname.includes("pagespeed") ) setOpen((prev) => ({ ...prev, Dashboard: true })); else if (location.pathname.includes("/account")) setOpen((prev) => ({ ...prev, Account: true })); }, []); return ( BU BlueWave Uptime { setOpen({ Dashboard: false, Account: false }); dispatch(toggleSidebar()); }} > {collapsed ? : } {/* menu */} Menu } sx={{ px: theme.gap.medium }} > {menu.map((item) => item.path ? ( navigate(`/${item.path}`)} sx={{ height: "37px", gap: theme.gap.small, borderRadius: `${theme.shape.borderRadius}px`, px: theme.gap.small, }} > {item.icon} {item.name} ) : collapsed ? ( openPopup(event, item.name)} sx={{ position: "relative", gap: theme.gap.small, borderRadius: `${theme.shape.borderRadius}px`, px: theme.gap.small, }} > {item.icon} {item.name} {item.nested.map((child) => { if ( child.name === "Team" && authState.user?.role && !authState.user.role.includes("admin") ) { return null; } return ( { navigate(`/${child.path}`); closePopup(); }} sx={{ gap: theme.gap.small, borderRadius: `${theme.shape.borderRadius}px`, pl: theme.gap.small, mb:"1px" }} > {child.icon} {child.name} ); })} ) : ( setOpen((prev) => ({ ...prev, [`${item.name}`]: !prev[`${item.name}`], })) } sx={{ gap: theme.gap.small, borderRadius: `${theme.shape.borderRadius}px`, px: theme.gap.small, }} > {item.icon} {item.name} {open[`${item.name}`] ? : } {item.nested.map((child) => { if ( child.name === "Team" && authState.user?.role && !authState.user.role.includes("admin") ) { return null; } return ( navigate(`/${child.path}`)} sx={{ gap: theme.gap.small, borderRadius: `${theme.shape.borderRadius}px`, pl: theme.gap.small, }} > {child.icon} {child.name} ); })} ) )} {/* other */} Other } sx={{ px: theme.gap.medium }} > {other.map((item) => ( item.path === "support" ? window.open( "https://github.com/bluewave-labs/bluewave-uptime", "_blank", "noreferrer" ) : navigate(`/${item.path}`) } sx={{ gap: theme.gap.small, borderRadius: `${theme.shape.borderRadius}px`, px: theme.gap.small, }} > {item.icon} {item.name} ))} {collapsed ? ( <> openPopup(event, "logout")} sx={{ p: 0, "&:focus": { outline: "none" } }} > {authState.user?.firstName} {authState.user?.lastName} {authState.user?.role} Log out ) : ( <> {authState.user?.firstName} {authState.user?.lastName} {authState.user?.role} )} ); } export default Sidebar;