diff --git a/client/src/Components/Layouts/HomeLayout/index.css b/client/src/Components/Layouts/HomeLayout/index.css
index 2db147f41..56606a935 100644
--- a/client/src/Components/Layouts/HomeLayout/index.css
+++ b/client/src/Components/Layouts/HomeLayout/index.css
@@ -12,13 +12,13 @@
}
} */
-.home-layout aside {
+/* .home-layout aside {
position: sticky;
top: 0;
left: 0;
height: 100vh;
max-width: var(--env-var-side-bar-width);
-}
+} */
.home-layout > div {
min-height: calc(100vh - var(--env-var-spacing-2) * 2);
diff --git a/client/src/Components/Sidebar/index.css b/client/src/Components/Sidebar/index.bak
similarity index 98%
rename from client/src/Components/Sidebar/index.css
rename to client/src/Components/Sidebar/index.bak
index ef921acca..a14a0f3d6 100644
--- a/client/src/Components/Sidebar/index.css
+++ b/client/src/Components/Sidebar/index.bak
@@ -1,5 +1,4 @@
-/* TODO */
-aside .MuiList-root svg {
+TODO aside .MuiList-root svg {
width: 20px;
height: 20px;
opacity: 0.9;
diff --git a/client/src/Components/Sidebar/index.jsx b/client/src/Components/Sidebar/index.jsx
index 219ceff1e..cad7d3b7d 100644
--- a/client/src/Components/Sidebar/index.jsx
+++ b/client/src/Components/Sidebar/index.jsx
@@ -1,19 +1,14 @@
-import React, { useEffect, useState, useRef } from "react";
-import {
- Box,
- Collapse,
- Divider,
- IconButton,
- List,
- ListItemButton,
- ListItemIcon,
- ListItemText,
- Menu,
- MenuItem,
- Stack,
- Tooltip,
- Typography,
-} from "@mui/material";
+import IconButton from "@mui/material/IconButton";
+import Stack from "@mui/material/Stack";
+import ArrowRight from "../../assets/icons/right-arrow.svg?react";
+import ArrowLeft from "../../assets/icons/left-arrow.svg?react";
+import List from "@mui/material/List";
+import ListItemButton from "@mui/material/ListItemButton";
+import ListItemIcon from "@mui/material/ListItemIcon";
+import ListItemText from "@mui/material/ListItemText";
+import Tooltip from "@mui/material/Tooltip";
+import Logo from "./logo";
+
import ThemeSwitch from "../ThemeSwitch";
import Avatar from "../Avatar";
import StarPrompt from "../StarPrompt";
@@ -30,8 +25,6 @@ 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 DotsVertical from "../../assets/icons/dots-vertical.svg?react";
import ChangeLog from "../../assets/icons/changeLog.svg?react";
import Docs from "../../assets/icons/docs.svg?react";
@@ -40,17 +33,13 @@ import Discussions from "../../assets/icons/discussions.svg?react";
import Notifications from "../../assets/icons/notifications.svg?react";
import Logs from "../../assets/icons/logs.svg?react";
-import "./index.css";
-
// Utils
-import { useLocation, useNavigate } from "react-router";
-import { useTheme } from "@emotion/react";
+import { useTheme } from "@mui/material/styles";
import { useDispatch, useSelector } from "react-redux";
-import { useTranslation } from "react-i18next";
-import { clearAuthState } from "../../Features/Auth/authSlice";
import { toggleSidebar } from "../../Features/UI/uiSlice";
-import { TurnedIn } from "@mui/icons-material";
-import { rules } from "eslint-plugin-react-refresh";
+import { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { useNavigate } from "react-router";
const getMenu = (t) => [
{ name: t("menu.uptime"), path: "uptime", icon: },
@@ -75,207 +64,25 @@ const getMenu = (t) => [
},
];
-const getOtherMenuItems = (t) => [
- { name: t("menu.support"), path: "support", icon: },
- {
- name: t("menu.discussions"),
- path: "discussions",
- icon: ,
- },
- { name: t("menu.docs"), path: "docs", icon: },
- { name: t("menu.changelog"), path: "changelog", icon: },
-];
-
-const getAccountMenuItems = (t) => [
- { name: t("menu.profile"), path: "account/profile", icon: },
- { name: t("menu.password"), path: "account/password", icon: },
- { name: t("menu.team"), path: "account/team", icon: },
-];
-
-/* TODO this could be a key in nested Path would be the link */
-const URL_MAP = {
- support: "https://discord.com/invite/NAb6H3UTjK",
- discussions: "https://github.com/bluewave-labs/checkmate/discussions",
- docs: "https://bluewavelabs.gitbook.io/checkmate",
- changelog: "https://github.com/bluewave-labs/checkmate/releases",
-};
-
-const PATH_MAP = {
- monitors: "Dashboard",
- pagespeed: "Dashboard",
- infrastructure: "Dashboard",
- account: "Account",
- settings: "Settings",
-};
-
-/**
- * @component
- * Sidebar component serves as a sidebar containing a menu.
- *
- * @returns {JSX.Element} The JSX element representing the Sidebar component.
- */
-
-function Sidebar() {
+const Sidebar = () => {
const theme = useTheme();
- const navigate = useNavigate();
- const location = useLocation();
const dispatch = useDispatch();
const { t } = useTranslation();
- const authState = useSelector((state) => state.auth);
-
- const otherMenuItems = getOtherMenuItems(t);
- const accountMenuItems = getAccountMenuItems(t);
+ const navigate = useNavigate();
+ // Redux state
const collapsed = useSelector((state) => state.ui.sidebar.collapsed);
+
+ // Local state
const [open, setOpen] = useState({ Dashboard: false, Account: false, Other: false });
- const [anchorEl, setAnchorEl] = useState(null);
- const [popup, setPopup] = useState();
- const { user } = useSelector((state) => state.auth);
- const sidebarRef = useRef(null);
- const [sidebarReady, setSidebarReady] = useState(false);
- const TRANSITION_DURATION = 200;
- let menu = getMenu(t);
- menu = menu.filter((item) => {
- if (item.path === "logs") {
- return user.role?.includes("admin") || user.role?.includes("superadmin");
- }
- return true;
- });
-
- useEffect(() => {
- if (!collapsed) {
- setSidebarReady(false);
- const timeout = setTimeout(() => {
- setSidebarReady(true);
- }, TRANSITION_DURATION);
- return () => clearTimeout(timeout);
- } else {
- setSidebarReady(false);
- }
- }, [collapsed]);
-
- const renderAccountMenuItems = () => {
- let filteredAccountMenuItems = [...accountMenuItems];
-
- // If the user is in demo mode, remove the "Password" option
- if (user.role?.includes("demo")) {
- filteredAccountMenuItems = filteredAccountMenuItems.filter(
- (item) => item.name !== "Password"
- );
- }
-
- // If the user is NOT a superadmin, remove the "Team" option
- if (user.role && !user.role.includes("superadmin")) {
- filteredAccountMenuItems = filteredAccountMenuItems.filter(
- (item) => item.name !== "Team"
- );
- }
-
- return filteredAccountMenuItems.map((item) => (
-
- ));
- };
-
- 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());
- navigate("/login");
- };
-
- useEffect(() => {
- const matchedKey = Object.keys(PATH_MAP).find((key) =>
- location.pathname.includes(key)
- );
-
- if (matchedKey) {
- setOpen((prev) => ({ ...prev, [PATH_MAP[matchedKey]]: true }));
- }
- }, [location]);
-
- const iconColor = theme.palette.primary.contrastTextTertiary;
- const sidebarClassName = `${collapsed ? "collapsed" : "expanded"} ${sidebarReady ? "sidebar-ready" : ""}`;
-
- /* TODO refactor this, there are a some ternaries and comments in the return */
+ const menu = getMenu(t);
+ console.log(collapsed);
return (
{collapsed ? : }
- {/* TODO Alignment done using padding. Use single source of truth to that*/}
-
- {/* TODO Abstract logo into component */}
- {/* TODO Turn logo into a link */}
- navigate("/")}
- sx={{ cursor: "pointer" }}
- >
-
- C
-
-
- {t("common.appName")}
-
-
-
-
-
- {menu.map((item) => {
- return item.path ? (
- /* If item has a path */
-
- navigate(`/${item.path}`)}
- sx={{
- height: "37px",
- gap: theme.spacing(4),
- borderRadius: theme.shape.borderRadius,
- px: theme.spacing(4),
- pl: theme.spacing(5),
- }}
- >
- {item.icon}
- {item.name}
-
-
- ) : collapsed ? (
- /* TODO Do we ever get here? If item does not have a path and collapsed state is true */
-
-
- openPopup(event, item.name)}
- sx={{
- position: "relative",
- gap: theme.spacing(4),
- borderRadius: theme.shape.borderRadius,
- px: theme.spacing(4),
- }}
- >
- {item.icon}
- {item.name}
-
-
-
-
- ) : (
- /* TODO Do we ever get here? If item does not have a path and collapsed state is false */
-
-
- setOpen((prev) => ({
- ...Object.fromEntries(Object.keys(prev).map((key) => [key, false])),
- [item.name]: !prev[item.name],
- }))
- }
- sx={{
- gap: theme.spacing(4),
- borderRadius: theme.shape.borderRadius,
- px: theme.spacing(4),
- }}
- >
- {item.icon}
- {item.name}
- {open[`${item.name}`] ? : }
-
-
-
- {item.nested.map((child) => {
- if (
- child.name === "Team" &&
- authState.user?.role &&
- !authState.user.role.includes("superadmin")
- ) {
- return null;
- }
-
- return (
- {
- const url = URL_MAP[child.path];
- if (url) {
- window.open(url, "_blank", "noreferrer");
- } else {
- navigate(`/${child.path}`);
- }
- }}
- sx={{
- gap: theme.spacing(4),
- borderRadius: theme.shape.borderRadius,
- pl: theme.spacing(4),
- "&::before": {
- content: `""`,
- position: "absolute",
- top: 0,
- left: "-7px",
- height: "100%",
- borderLeft: 1,
- borderLeftColor: theme.palette.primary.lowContrast,
- },
- "&:last-child::before": {
- height: "50%",
- },
- "&::after": {
- content: `""`,
- position: "absolute",
- top: "45%",
- left: "-8px",
- height: "3px",
- width: "3px",
- borderRadius: "50%",
- backgroundColor: theme.palette.primary.lowContrast,
- },
- "&.selected-path::after": {
- /* TODO what is this selector doing? */
- backgroundColor: theme.palette.primary.contrastTextTertiary,
- transform: "scale(1.2)",
- },
- }}
- >
- {child.icon}
- {child.name}
-
- );
- })}
-
-
-
- );
- })}
-
-
-
- {!collapsed && }
-
+
- {otherMenuItems.map((item) => {
+ {menu.map((item) => {
return item.path ? (
+ /* If item has a path */
{
- const url = URL_MAP[item.path];
- if (url) {
- window.open(url, "_blank", "noreferrer");
- } else {
- navigate(`/${item.path}`);
- }
- }}
+ onClick={() => navigate(`/${item.path}`)}
sx={{
height: "37px",
gap: theme.spacing(4),
@@ -666,208 +163,15 @@ function Sidebar() {
pl: theme.spacing(5),
}}
>
- {item.icon}
- {item.name} {" "}
+ {item.icon}
+ {!collapsed && {item.name}}
) : null;
})}
-
-
- {collapsed ? (
- <>
-
- openPopup(event, "logout")}
- sx={{ p: 0, "&:focus": { outline: "none" } }}
- >
-
-
-
- >
- ) : (
- <>
-
-
-
- {authState.user?.firstName} {authState.user?.lastName}
-
-
- {authState.user?.role?.includes("superadmin")
- ? t("roles.superAdmin")
- : authState.user?.role?.includes("admin")
- ? t("roles.admin")
- : authState.user?.role?.includes("user")
- ? t("roles.teamMember")
- : authState.user?.role?.includes("demo")
- ? t("roles.demoUser")
- : authState.user?.role}
-
-
-
-
-
- openPopup(event, "logout")}
- >
-
-
-
-
- >
- )}
-
-
);
-}
+};
export default Sidebar;
diff --git a/client/src/Components/Sidebar/index_old.jsx b/client/src/Components/Sidebar/index_old.jsx
new file mode 100644
index 000000000..219ceff1e
--- /dev/null
+++ b/client/src/Components/Sidebar/index_old.jsx
@@ -0,0 +1,873 @@
+import React, { useEffect, useState, useRef } from "react";
+import {
+ Box,
+ Collapse,
+ Divider,
+ IconButton,
+ List,
+ ListItemButton,
+ ListItemIcon,
+ ListItemText,
+ Menu,
+ MenuItem,
+ Stack,
+ Tooltip,
+ Typography,
+} from "@mui/material";
+import ThemeSwitch from "../ThemeSwitch";
+import Avatar from "../Avatar";
+import StarPrompt from "../StarPrompt";
+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 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 DotsVertical from "../../assets/icons/dots-vertical.svg?react";
+import ChangeLog from "../../assets/icons/changeLog.svg?react";
+import Docs from "../../assets/icons/docs.svg?react";
+import StatusPages from "../../assets/icons/status-pages.svg?react";
+import Discussions from "../../assets/icons/discussions.svg?react";
+import Notifications from "../../assets/icons/notifications.svg?react";
+import Logs from "../../assets/icons/logs.svg?react";
+
+import "./index.css";
+
+// Utils
+import { useLocation, useNavigate } from "react-router";
+import { useTheme } from "@emotion/react";
+import { useDispatch, useSelector } from "react-redux";
+import { useTranslation } from "react-i18next";
+import { clearAuthState } from "../../Features/Auth/authSlice";
+import { toggleSidebar } from "../../Features/UI/uiSlice";
+import { TurnedIn } from "@mui/icons-material";
+import { rules } from "eslint-plugin-react-refresh";
+
+const getMenu = (t) => [
+ { name: t("menu.uptime"), path: "uptime", icon: },
+ { name: t("menu.pagespeed"), path: "pagespeed", icon: },
+
+ { name: t("menu.infrastructure"), path: "infrastructure", icon: },
+ {
+ name: t("menu.notifications"),
+ path: "notifications",
+ icon: ,
+ },
+ { name: t("menu.incidents"), path: "incidents", icon: },
+
+ { name: t("menu.statusPages"), path: "status", icon: },
+ { name: t("menu.maintenance"), path: "maintenance", icon: },
+ { name: t("menu.logs"), path: "logs", icon: },
+
+ {
+ name: t("menu.settings"),
+ icon: ,
+ path: "settings",
+ },
+];
+
+const getOtherMenuItems = (t) => [
+ { name: t("menu.support"), path: "support", icon: },
+ {
+ name: t("menu.discussions"),
+ path: "discussions",
+ icon: ,
+ },
+ { name: t("menu.docs"), path: "docs", icon: },
+ { name: t("menu.changelog"), path: "changelog", icon: },
+];
+
+const getAccountMenuItems = (t) => [
+ { name: t("menu.profile"), path: "account/profile", icon: },
+ { name: t("menu.password"), path: "account/password", icon: },
+ { name: t("menu.team"), path: "account/team", icon: },
+];
+
+/* TODO this could be a key in nested Path would be the link */
+const URL_MAP = {
+ support: "https://discord.com/invite/NAb6H3UTjK",
+ discussions: "https://github.com/bluewave-labs/checkmate/discussions",
+ docs: "https://bluewavelabs.gitbook.io/checkmate",
+ changelog: "https://github.com/bluewave-labs/checkmate/releases",
+};
+
+const PATH_MAP = {
+ monitors: "Dashboard",
+ pagespeed: "Dashboard",
+ infrastructure: "Dashboard",
+ account: "Account",
+ settings: "Settings",
+};
+
+/**
+ * @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 { t } = useTranslation();
+ const authState = useSelector((state) => state.auth);
+
+ const otherMenuItems = getOtherMenuItems(t);
+ const accountMenuItems = getAccountMenuItems(t);
+ const collapsed = useSelector((state) => state.ui.sidebar.collapsed);
+ const [open, setOpen] = useState({ Dashboard: false, Account: false, Other: false });
+ const [anchorEl, setAnchorEl] = useState(null);
+ const [popup, setPopup] = useState();
+ const { user } = useSelector((state) => state.auth);
+
+ const sidebarRef = useRef(null);
+ const [sidebarReady, setSidebarReady] = useState(false);
+ const TRANSITION_DURATION = 200;
+ let menu = getMenu(t);
+ menu = menu.filter((item) => {
+ if (item.path === "logs") {
+ return user.role?.includes("admin") || user.role?.includes("superadmin");
+ }
+ return true;
+ });
+
+ useEffect(() => {
+ if (!collapsed) {
+ setSidebarReady(false);
+ const timeout = setTimeout(() => {
+ setSidebarReady(true);
+ }, TRANSITION_DURATION);
+ return () => clearTimeout(timeout);
+ } else {
+ setSidebarReady(false);
+ }
+ }, [collapsed]);
+
+ const renderAccountMenuItems = () => {
+ let filteredAccountMenuItems = [...accountMenuItems];
+
+ // If the user is in demo mode, remove the "Password" option
+ if (user.role?.includes("demo")) {
+ filteredAccountMenuItems = filteredAccountMenuItems.filter(
+ (item) => item.name !== "Password"
+ );
+ }
+
+ // If the user is NOT a superadmin, remove the "Team" option
+ if (user.role && !user.role.includes("superadmin")) {
+ filteredAccountMenuItems = filteredAccountMenuItems.filter(
+ (item) => item.name !== "Team"
+ );
+ }
+
+ return filteredAccountMenuItems.map((item) => (
+
+ ));
+ };
+
+ 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());
+ navigate("/login");
+ };
+
+ useEffect(() => {
+ const matchedKey = Object.keys(PATH_MAP).find((key) =>
+ location.pathname.includes(key)
+ );
+
+ if (matchedKey) {
+ setOpen((prev) => ({ ...prev, [PATH_MAP[matchedKey]]: true }));
+ }
+ }, [location]);
+
+ const iconColor = theme.palette.primary.contrastTextTertiary;
+ const sidebarClassName = `${collapsed ? "collapsed" : "expanded"} ${sidebarReady ? "sidebar-ready" : ""}`;
+
+ /* TODO refactor this, there are a some ternaries and comments in the return */
+ return (
+
+ {
+ setOpen((prev) =>
+ Object.fromEntries(Object.keys(prev).map((key) => [key, false]))
+ );
+ dispatch(toggleSidebar());
+ }}
+ >
+ {collapsed ? : }
+
+ {/* TODO Alignment done using padding. Use single source of truth to that*/}
+
+ {/* TODO Abstract logo into component */}
+ {/* TODO Turn logo into a link */}
+ navigate("/")}
+ sx={{ cursor: "pointer" }}
+ >
+
+ C
+
+
+ {t("common.appName")}
+
+
+
+
+
+ {menu.map((item) => {
+ return item.path ? (
+ /* If item has a path */
+
+ navigate(`/${item.path}`)}
+ sx={{
+ height: "37px",
+ gap: theme.spacing(4),
+ borderRadius: theme.shape.borderRadius,
+ px: theme.spacing(4),
+ pl: theme.spacing(5),
+ }}
+ >
+ {item.icon}
+ {item.name}
+
+
+ ) : collapsed ? (
+ /* TODO Do we ever get here? If item does not have a path and collapsed state is true */
+
+
+ openPopup(event, item.name)}
+ sx={{
+ position: "relative",
+ gap: theme.spacing(4),
+ borderRadius: theme.shape.borderRadius,
+ px: theme.spacing(4),
+ }}
+ >
+ {item.icon}
+ {item.name}
+
+
+
+
+ ) : (
+ /* TODO Do we ever get here? If item does not have a path and collapsed state is false */
+
+
+ setOpen((prev) => ({
+ ...Object.fromEntries(Object.keys(prev).map((key) => [key, false])),
+ [item.name]: !prev[item.name],
+ }))
+ }
+ sx={{
+ gap: theme.spacing(4),
+ borderRadius: theme.shape.borderRadius,
+ px: theme.spacing(4),
+ }}
+ >
+ {item.icon}
+ {item.name}
+ {open[`${item.name}`] ? : }
+
+
+
+ {item.nested.map((child) => {
+ if (
+ child.name === "Team" &&
+ authState.user?.role &&
+ !authState.user.role.includes("superadmin")
+ ) {
+ return null;
+ }
+
+ return (
+ {
+ const url = URL_MAP[child.path];
+ if (url) {
+ window.open(url, "_blank", "noreferrer");
+ } else {
+ navigate(`/${child.path}`);
+ }
+ }}
+ sx={{
+ gap: theme.spacing(4),
+ borderRadius: theme.shape.borderRadius,
+ pl: theme.spacing(4),
+ "&::before": {
+ content: `""`,
+ position: "absolute",
+ top: 0,
+ left: "-7px",
+ height: "100%",
+ borderLeft: 1,
+ borderLeftColor: theme.palette.primary.lowContrast,
+ },
+ "&:last-child::before": {
+ height: "50%",
+ },
+ "&::after": {
+ content: `""`,
+ position: "absolute",
+ top: "45%",
+ left: "-8px",
+ height: "3px",
+ width: "3px",
+ borderRadius: "50%",
+ backgroundColor: theme.palette.primary.lowContrast,
+ },
+ "&.selected-path::after": {
+ /* TODO what is this selector doing? */
+ backgroundColor: theme.palette.primary.contrastTextTertiary,
+ transform: "scale(1.2)",
+ },
+ }}
+ >
+ {child.icon}
+ {child.name}
+
+ );
+ })}
+
+
+
+ );
+ })}
+
+
+
+ {!collapsed && }
+
+
+ {otherMenuItems.map((item) => {
+ return item.path ? (
+
+ {
+ const url = URL_MAP[item.path];
+ if (url) {
+ window.open(url, "_blank", "noreferrer");
+ } else {
+ navigate(`/${item.path}`);
+ }
+ }}
+ sx={{
+ height: "37px",
+ gap: theme.spacing(4),
+ borderRadius: theme.shape.borderRadius,
+ px: theme.spacing(4),
+ pl: theme.spacing(5),
+ }}
+ >
+ {item.icon}
+ {item.name} {" "}
+
+
+ ) : null;
+ })}
+
+
+
+ {collapsed ? (
+ <>
+
+ openPopup(event, "logout")}
+ sx={{ p: 0, "&:focus": { outline: "none" } }}
+ >
+
+
+
+ >
+ ) : (
+ <>
+
+
+
+ {authState.user?.firstName} {authState.user?.lastName}
+
+
+ {authState.user?.role?.includes("superadmin")
+ ? t("roles.superAdmin")
+ : authState.user?.role?.includes("admin")
+ ? t("roles.admin")
+ : authState.user?.role?.includes("user")
+ ? t("roles.teamMember")
+ : authState.user?.role?.includes("demo")
+ ? t("roles.demoUser")
+ : authState.user?.role}
+
+
+
+
+
+ openPopup(event, "logout")}
+ >
+
+
+
+
+ >
+ )}
+
+
+
+ );
+}
+
+export default Sidebar;
diff --git a/client/src/Components/Sidebar/logo.jsx b/client/src/Components/Sidebar/logo.jsx
new file mode 100644
index 000000000..0a8a76f0c
--- /dev/null
+++ b/client/src/Components/Sidebar/logo.jsx
@@ -0,0 +1,57 @@
+import Stack from "@mui/material/Stack";
+import Typography from "@mui/material/Typography";
+import { useTheme } from "@mui/material/styles";
+import { useNavigate } from "react-router";
+import { useTranslation } from "react-i18next";
+
+const Logo = () => {
+ const { t } = useTranslation();
+ const theme = useTheme();
+ const navigate = useNavigate();
+
+ return (
+
+ {/* TODO Abstract logo into component */}
+ {/* TODO Turn logo into a link */}
+ navigate("/")}
+ sx={{ cursor: "pointer" }}
+ >
+
+ C
+
+
+ {t("common.appName")}
+
+
+
+ );
+};
+
+export default Logo;