Files
Checkmate/Client/src/Components/NavBar/index.jsx
T

186 lines
5.0 KiB
React
Raw Normal View History

2024-06-06 12:27:36 +03:30
import "./index.css";
2024-07-26 12:39:18 -04:00
import { cloneElement, useState } from "react";
2024-06-06 12:27:36 +03:30
import AppBar from "@mui/material/AppBar";
import Box from "@mui/material/Box";
import Toolbar from "@mui/material/Toolbar";
import IconButton from "@mui/material/IconButton";
import Typography from "@mui/material/Typography";
import Menu from "@mui/material/Menu";
2024-07-26 12:39:18 -04:00
import Avatar from "../Avatar";
2024-06-06 12:27:36 +03:30
import Tooltip from "@mui/material/Tooltip";
import MenuItem from "@mui/material/MenuItem";
import { useTheme } from "@mui/material/styles";
2024-07-26 12:39:18 -04:00
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
2024-06-24 11:21:30 -07:00
import { clearAuthState } from "../../Features/Auth/authSlice";
2024-07-30 11:25:14 -07:00
import { clearUptimeMonitorState } from "../../Features/UptimeMonitors/uptimeMonitorsSlice";
2024-06-24 12:00:49 -07:00
import { useDispatch, useSelector } from "react-redux";
2024-06-24 11:21:30 -07:00
import { useNavigate } from "react-router-dom";
2024-07-07 19:15:44 -04:00
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";
2024-07-26 12:39:18 -04:00
import { Stack, useScrollTrigger } from "@mui/material";
2024-07-12 17:34:42 +03:30
2024-07-07 19:15:44 -04:00
const icons = {
Profile: <UserSvg />,
Team: <TeamSvg />,
Password: <LockSvg />,
Logout: <LogoutSvg />,
};
2024-07-26 12:39:18 -04:00
function AddBorderOnScroll(props) {
const { children, window } = props;
const trigger = useScrollTrigger({
target: window ? window() : undefined,
disableHysteresis: true,
threshold: 0,
});
2024-07-30 11:25:14 -07:00
2024-07-26 12:39:18 -04:00
return (
<AppBar
className={trigger ? "scrolled" : ""}
position="sticky"
sx={{
boxShadow: "none",
transition: "all 0.3s ease",
borderBottom: "1px solid transparent",
"&.scrolled": {
borderBottom: "1px solid #eaecf0",
2024-07-30 11:25:14 -07:00
backgroundColor: "white",
2024-07-26 12:39:18 -04:00
},
}}
>
{children}
</AppBar>
);
}
/**
* NavBar component
*
* A responsive navigation bar component with a user menu.
*
* @component
* @example
* return (
* <NavBar />
* )
*/
function NavBar() {
const theme = useTheme();
const [anchorElUser, setAnchorElUser] = useState(null);
2024-06-24 11:21:30 -07:00
const dispatch = useDispatch();
const navigate = useNavigate();
const authState = useSelector((state) => state.auth);
2024-07-26 07:21:18 -07:00
// Initialize settings and update based on user role
2024-07-24 14:46:49 -04:00
let settings = ["Profile", "Password", "Team", "Logout"];
2024-07-26 07:21:18 -07:00
if (authState.user?.role && !authState.user.role.includes("admin")) {
2024-07-24 14:46:49 -04:00
settings = ["Profile", "Password", "Logout"];
2024-07-26 07:21:18 -07:00
}
2024-07-24 15:07:00 -04:00
/**
* 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);
};
2024-06-24 11:21:30 -07:00
/**
* Handles logging out the user
*
*/
const logout = () => {
// Clear auth state
dispatch(clearAuthState());
2024-07-30 11:25:14 -07:00
dispatch(clearUptimeMonitorState());
navigate("/login");
2024-06-24 11:21:30 -07:00
};
/**
* Handles closing the user menu.
*/
2024-06-24 11:21:30 -07:00
const handleCloseUserMenu = (setting) => {
setAnchorElUser(null);
2024-06-24 11:21:30 -07:00
switch (setting) {
case "Profile":
2024-06-27 19:19:36 -04:00
navigate("/account/profile");
2024-06-24 11:21:30 -07:00
break;
case "Team":
2024-06-27 19:19:36 -04:00
navigate("/account/team");
2024-06-24 11:21:30 -07:00
break;
2024-07-07 19:15:44 -04:00
case "Password":
navigate("/account/password");
2024-06-24 11:21:30 -07:00
break;
case "Logout":
logout();
break;
default:
break;
}
};
return (
2024-07-26 12:39:18 -04:00
<AddBorderOnScroll>
<Toolbar disableGutters sx={{ alignSelf: "flex-end", paddingX: "25px" }}>
<Tooltip title="Open settings">
<IconButton
id="icon-button"
onClick={handleOpenUserMenu}
sx={{ p: 0 }}
>
2024-07-26 12:39:18 -04:00
<Stack direction="row" alignItems="center" gap="8px">
<Avatar small={true} />
<Box
className="icon-button-toggle-title"
sx={{ mr: "3px", lineHeight: 2 }}
2024-06-06 22:04:30 +03:30
>
2024-07-26 12:39:18 -04:00
{authState.user?.firstName} {authState.user?.lastName}
</Box>
<KeyboardArrowDownIcon sx={{ mt: "2px" }} />
</Stack>
</IconButton>
</Tooltip>
<Menu
sx={{ mt: theme.spacing(5.5) }}
id="menu-appbar"
anchorEl={anchorElUser}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
keepMounted
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}
>
{settings.map((setting) => (
<MenuItem
id="menu-item"
key={setting}
onClick={() => handleCloseUserMenu(setting)}
sx={{ width: "150px" }}
>
2024-07-26 12:39:18 -04:00
{icons[setting]}
<Typography
fontSize="var(--env-var-font-size-medium)"
textAlign="center"
marginLeft="8px"
>
{setting}
</Typography>
</MenuItem>
))}
</Menu>
</Toolbar>
</AddBorderOnScroll>
);
}
2024-05-06 12:29:36 -04:00
export default NavBar;