From 6a5c74fd369a854d0caa04e8efc924eaa32e8ea0 Mon Sep 17 00:00:00 2001 From: Maurovic Cachia Date: Fri, 18 Jul 2025 23:48:43 +0100 Subject: [PATCH 1/5] Sidebar --- src/App.tsx | 2 +- src/navigation/MenuMainContainer.js | 4 +- src/navigation/MenuMainContainer2.tsx | 247 ++++++++++++++++++ src/navigation/MobileNavigationDrawer.js | 4 +- src/navigation/sidebar/Sidebar.tsx | 35 +++ src/navigation/sidebar/SidebarDrawerItems.tsx | 159 +++++++++++ src/navigation/sidebar/SidebarProvider.tsx | 32 +++ src/navigation/sidebar/TopbarButton.tsx | 13 + 8 files changed, 491 insertions(+), 5 deletions(-) create mode 100644 src/navigation/MenuMainContainer2.tsx create mode 100644 src/navigation/sidebar/Sidebar.tsx create mode 100644 src/navigation/sidebar/SidebarDrawerItems.tsx create mode 100644 src/navigation/sidebar/SidebarProvider.tsx create mode 100644 src/navigation/sidebar/TopbarButton.tsx diff --git a/src/App.tsx b/src/App.tsx index d1e4ed967..dc32e538b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,5 @@ import React from "react"; import { APIProvider } from "@vis.gl/react-google-maps"; -import { MenuMainContainer } from "./navigation/MenuMainContainer"; import "./index.css"; import "./App.css"; import CssBaseline from "@mui/material/CssBaseline"; @@ -24,6 +23,7 @@ import SnackNotificationBar from "./components/SnackNotificationBar"; import TenantListProvider from "./scenes/TenantPicker/TenantListProvider"; import { initialiseApp } from "./redux/initialise/initialiseActions"; import * as Sentry from "@sentry/react"; +import MenuMainContainer from "./navigation/MenuMainContainer2"; const GOOGLE_MAPS_API_KEY = process.env.REACT_APP_GOOGLE_MAPS_API_KEY as string; diff --git a/src/navigation/MenuMainContainer.js b/src/navigation/MenuMainContainer.js index 922ba62bb..4df3f84a3 100644 --- a/src/navigation/MenuMainContainer.js +++ b/src/navigation/MenuMainContainer.js @@ -83,7 +83,7 @@ export function MenuMainContainer() { }, [isSm, searchMode]); return ( - + - + ); } diff --git a/src/navigation/MenuMainContainer2.tsx b/src/navigation/MenuMainContainer2.tsx new file mode 100644 index 000000000..e9087df38 --- /dev/null +++ b/src/navigation/MenuMainContainer2.tsx @@ -0,0 +1,247 @@ +import * as React from 'react'; +import { styled, useTheme, Theme, CSSObject } from '@mui/material/styles'; +import Box from '@mui/material/Box'; +import MuiDrawer from '@mui/material/Drawer'; +import MuiAppBar, { AppBarProps as MuiAppBarProps } from '@mui/material/AppBar'; +import CssBaseline from '@mui/material/CssBaseline'; +import IconButton from '@mui/material/IconButton'; +import { Hidden, Stack, useMediaQuery } from '@mui/material'; +import { useSelector, useDispatch } from 'react-redux'; +import { makeStyles } from 'tss-react/mui'; +import { clearDashboardFilter } from '../redux/dashboardFilter/DashboardFilterActions'; +import { menuIndexSelector, dashboardFilterTermSelector } from '../redux/Selectors'; +import { SidebarProvider, useSidebar } from './sidebar/SidebarProvider'; +import MainWindow from './MainWindow'; +import { Sidebar } from './sidebar/Sidebar'; +import TaskFilterTextField from '../components/TaskFilterTextfield'; +import DashboardDetailTabs from '../scenes/Dashboard/components/DashboardDetailTabs'; +import RoleViewSelect from '../scenes/Dashboard/components/RoleViewSelect'; +import LightToggleProfileMenu from './Components/LightToggleProfileMenu'; +import ForwardBackButtons from './ForwardBackButtons'; +import MobileNavigationDrawer from './MobileNavigationDrawer'; +import { + dashboardTabIndexSelector, +} from "../redux/Selectors"; + +import SearchIcon from "@mui/icons-material/Search"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; + +const drawerWidth = 240; + +const openedMixin = (theme: Theme): CSSObject => ({ + width: drawerWidth, + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + overflowX: 'hidden', +}); + +const closedMixin = (theme: Theme): CSSObject => ({ + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + overflowX: 'hidden', + width: `calc(${theme.spacing(7)} + 1px)`, + [theme.breakpoints.up('sm')]: { + width: `calc(${theme.spacing(8)} + 1px)`, + }, +}); + +interface AppBarProps extends MuiAppBarProps { + open?: boolean; +} + +const AppBar = styled(MuiAppBar, { + shouldForwardProp: (prop) => prop !== 'open', +})(({ theme }) => ({ + zIndex: theme.zIndex.drawer + 1, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + variants: [ + { + props: ({ open }: any) => open, + style: { + marginLeft: drawerWidth, + width: `calc(100% - ${drawerWidth}px)`, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + }, + ], +})); + +const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })( + ({ theme }) => ({ + width: drawerWidth, + flexShrink: 0, + whiteSpace: 'nowrap', + boxSizing: 'border-box', + variants: [ + { + props: ({ open }: any) => open, + style: { + ...openedMixin(theme), + '& .MuiDrawer-paper': openedMixin(theme), + }, + }, + { + props: ({ open }: any) => !open, + style: { + ...closedMixin(theme), + '& .MuiDrawer-paper': closedMixin(theme), + }, + }, + ], + }), +); + +const useStyles2 = makeStyles()((theme) => { + return { + appBarComponents: { + margin: "auto", + width: "100%", + padding: 5, + color: theme.palette.text.primary, + }, + appBar: { + [theme.breakpoints.up("sm")]: { + width: "100%", + }, + background: theme.palette.background.paper, + }, + }; +}); + +export default function MenuMainContainer() { + const { classes } = useStyles2(); + const [searchMode, setSearchMode] = React.useState(false); + const dashboardTabIndex = useSelector(dashboardTabIndexSelector); + const menuIndex = useSelector(menuIndexSelector); + const currentFilter = useSelector(dashboardFilterTermSelector); + const toggleIcon = searchMode ? : ; + const dispatch = useDispatch(); + const {sidebarOpen} = useSidebar() + + const toggleSearchMode = () => { + if (searchMode) dispatch(clearDashboardFilter()); + setSearchMode(!searchMode); + }; + + const theme = useTheme(); + const isSm = useMediaQuery(theme.breakpoints.down("md")); + const isXs = useMediaQuery(theme.breakpoints.down("sm")); + + const updateSearchMode = React.useCallback( + (currentFilter, menuIndex, isSm) => { + if (menuIndex !== "dashboard") { + setSearchMode(false); + dispatch(clearDashboardFilter()); + } else if (currentFilter && isSm) { + setSearchMode((prevState) => { + if (!prevState) return true; + else return prevState; + }); + } + }, + [dispatch] + ); + + React.useEffect( + () => updateSearchMode(currentFilter, menuIndex, isSm), + [currentFilter, isSm, menuIndex, updateSearchMode] + ); + + React.useEffect(() => { + if (!isSm && searchMode) setSearchMode(false); + }, [isSm, searchMode]); + + + + return ( + + + + + + + {searchMode ? ( + + + {toggleIcon} + + + + ) : ( + <> + + + + + {menuIndex === "dashboard" && ( + <> + + + + + + + + {toggleIcon} + + + + )} + {isXs && + dashboardTabIndex !== 2 && + menuIndex === "dashboard" && } + + + )} + + + + + + + + + + + ); +} \ No newline at end of file diff --git a/src/navigation/MobileNavigationDrawer.js b/src/navigation/MobileNavigationDrawer.js index 46b426e86..76c49edfe 100644 --- a/src/navigation/MobileNavigationDrawer.js +++ b/src/navigation/MobileNavigationDrawer.js @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import { useState } from "react"; import NavDrawerItems from "./NavDrawerItems"; import IconButton from "@mui/material/IconButton"; import MenuIcon from "@mui/icons-material/Menu"; @@ -14,7 +14,7 @@ const useStyles = makeStyles()({ }); export default function MobileNavigationDrawer() { - const [open, setOpen] = useState(false); + const [open, setOpen] = useState(true); const { classes } = useStyles(); useCordovaBackButton(() => { diff --git a/src/navigation/sidebar/Sidebar.tsx b/src/navigation/sidebar/Sidebar.tsx new file mode 100644 index 000000000..9500b56fa --- /dev/null +++ b/src/navigation/sidebar/Sidebar.tsx @@ -0,0 +1,35 @@ +import { Stack, IconButton, Drawer } from "@mui/material" +import { useSidebar } from "./SidebarProvider" +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import { makeStyles } from 'tss-react/mui'; +import { SidebarDrawerItems } from "./SidebarDrawerItems"; + +const useStyles = makeStyles()({ + list: { + width: 250, + }, +}); + +export const Sidebar = () => { + + const { sidebarOpen, toggleSidebar } = useSidebar() + const { classes } = useStyles(); + + return ( + + + + + + + + + ) +} \ No newline at end of file diff --git a/src/navigation/sidebar/SidebarDrawerItems.tsx b/src/navigation/sidebar/SidebarDrawerItems.tsx new file mode 100644 index 000000000..22d34679d --- /dev/null +++ b/src/navigation/sidebar/SidebarDrawerItems.tsx @@ -0,0 +1,159 @@ +import { FC } from "react"; +import { useSelector } from "react-redux"; +import { getWhoami } from "../../redux/Selectors"; +import { ListItemIcon, ListItemText, Divider, List, ListItemButton } from "@mui/material"; +import { Link } from "react-router-dom"; +import SupervisorAccountIcon from "@mui/icons-material/SupervisorAccount"; +import * as models from "../../models"; +import DashboardIcon from "@mui/icons-material/Dashboard"; +import LocationCityIcon from "@mui/icons-material/LocationCity"; +import BarChartIcon from "@mui/icons-material/BarChart"; +import DescriptionIcon from "@mui/icons-material/Description"; +import HistoryIcon from "@mui/icons-material/History"; +import CalendarMonthIcon from "@mui/icons-material/CalendarMonth"; +import PeopleAltIcon from "@mui/icons-material/PeopleAlt"; +import TwoWheelerIcon from "@mui/icons-material/TwoWheeler"; + +export interface SidebarDrawerItemsProps { + className?: string; + onSelect: () => void; +} + +export const SidebarDrawerItems: FC = (props) => { + const whoami = useSelector(getWhoami); + const menuIndex = useSelector((state) => state.menuIndex); + const onSelect = props.onSelect; + let adminLink = <>; + let historyLink = <>; + let statisticsLink = <>; + let scheduledTasksLink = <>; + + if (whoami.roles) { + if (whoami.roles.includes("ADMIN")) { + adminLink = ( + + + + + + + ); + } + if ( + whoami.roles.includes(models.Role.ADMIN) || + whoami.roles.includes(models.Role.COORDINATOR) + ) { + historyLink = ( + + + + + + + ); + statisticsLink = ( + + + + + + + ); + scheduledTasksLink = ( + + + + + + + ); + } + } + + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {scheduledTasksLink} + {statisticsLink} + {historyLink} + {adminLink} + +
+ ); +} \ No newline at end of file diff --git a/src/navigation/sidebar/SidebarProvider.tsx b/src/navigation/sidebar/SidebarProvider.tsx new file mode 100644 index 000000000..0bc94faa3 --- /dev/null +++ b/src/navigation/sidebar/SidebarProvider.tsx @@ -0,0 +1,32 @@ +import { createContext, FC, ReactNode, useContext, useState } from "react"; + +export interface SidebarProviderProps { + children: ReactNode; +} + +const SidebarContext = createContext<{ + sidebarOpen: boolean; + toggleSidebar: () => void; +} | null>(null); + +export const SidebarProvider: FC = ({ children }) => { + const [sidebarOpen, setSidebarOpen] = useState(true); + + const toggleSidebar = () => { + setSidebarOpen(!sidebarOpen); + }; + + return ( + + {children} + + ); +} + +export const useSidebar = () => { + const context = useContext(SidebarContext); + if (!context) { + throw new Error("useSidebar must be used within a SidebarProvider"); + } + return context; +}; \ No newline at end of file diff --git a/src/navigation/sidebar/TopbarButton.tsx b/src/navigation/sidebar/TopbarButton.tsx new file mode 100644 index 000000000..e9aa7283f --- /dev/null +++ b/src/navigation/sidebar/TopbarButton.tsx @@ -0,0 +1,13 @@ +import { IconButton } from "@mui/material"; +import { useSidebar } from "./SidebarProvider"; +import MenuIcon from "@mui/icons-material/Menu"; + +export const TopbarButton = () => { + const { toggleSidebar } = useSidebar(); + + return ( + + + + ); +} \ No newline at end of file From f84aad823d94f38e24a1490739220c5fac50f641 Mon Sep 17 00:00:00 2001 From: Maurovic Cachia Date: Tue, 29 Jul 2025 14:32:56 +0100 Subject: [PATCH 2/5] Fixes and Changes --- .prettierrc | 2 +- src/App.tsx | 45 ++-- src/navigation/MainWindow.js | 2 +- src/navigation/MenuMainContainer2.tsx | 247 ------------------ src/navigation/MenuMainContainer3.tsx | 171 ++++++++++++ src/navigation/sidebar/Sidebar.tsx | 105 +++++++- src/navigation/sidebar/SidebarDrawerItems.tsx | 10 +- src/navigation/sidebar/SidebarProvider.tsx | 32 --- src/navigation/sidebar/TopbarButton.tsx | 11 +- 9 files changed, 298 insertions(+), 327 deletions(-) delete mode 100644 src/navigation/MenuMainContainer2.tsx create mode 100644 src/navigation/MenuMainContainer3.tsx delete mode 100644 src/navigation/sidebar/SidebarProvider.tsx diff --git a/.prettierrc b/.prettierrc index 39eed9eea..55ea2b2d1 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,4 @@ { "tabWidth": 4, - "useTabs": false, + "useTabs": false } diff --git a/src/App.tsx b/src/App.tsx index dc32e538b..d063c164c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -23,7 +23,9 @@ import SnackNotificationBar from "./components/SnackNotificationBar"; import TenantListProvider from "./scenes/TenantPicker/TenantListProvider"; import { initialiseApp } from "./redux/initialise/initialiseActions"; import * as Sentry from "@sentry/react"; -import MenuMainContainer from "./navigation/MenuMainContainer2"; +// import MenuMainContainer from "./navigation/MenuMainContainer2"; +// import { SidebarProvider } from "./navigation/sidebar/SidebarProvider"; +import MenuMainContainer from "./navigation/MenuMainContainer3"; const GOOGLE_MAPS_API_KEY = process.env.REACT_APP_GOOGLE_MAPS_API_KEY as string; @@ -124,41 +126,32 @@ const App = (props: any) => { }); } - if (process.env.REACT_APP_DEMO_MODE === "true") { - return ( - - - - + return ( + + + + + {/* */} + + {process.env.REACT_APP_DEMO_MODE === "true" ? ( - - - - - - ); - } else { - return ( - - - - + ) : ( - - - - - - ); - } + )} + {/* */} + + + + + ); }; export default App; diff --git a/src/navigation/MainWindow.js b/src/navigation/MainWindow.js index e4275ea82..d25241c2f 100644 --- a/src/navigation/MainWindow.js +++ b/src/navigation/MainWindow.js @@ -33,7 +33,7 @@ const useStyles = makeStyles()((theme, { navIndex, guidedSetupOpen }) => ({ root: { marginRight: guidedSetupOpen && navIndex === "dashboard" ? 0 : "auto", marginLeft: navIndex === "dashboard" ? 0 : 20, - paddingTop: 20, + paddingTop: 58, paddingBottom: 10, [theme.breakpoints.down("md")]: { paddingTop: 5, diff --git a/src/navigation/MenuMainContainer2.tsx b/src/navigation/MenuMainContainer2.tsx deleted file mode 100644 index e9087df38..000000000 --- a/src/navigation/MenuMainContainer2.tsx +++ /dev/null @@ -1,247 +0,0 @@ -import * as React from 'react'; -import { styled, useTheme, Theme, CSSObject } from '@mui/material/styles'; -import Box from '@mui/material/Box'; -import MuiDrawer from '@mui/material/Drawer'; -import MuiAppBar, { AppBarProps as MuiAppBarProps } from '@mui/material/AppBar'; -import CssBaseline from '@mui/material/CssBaseline'; -import IconButton from '@mui/material/IconButton'; -import { Hidden, Stack, useMediaQuery } from '@mui/material'; -import { useSelector, useDispatch } from 'react-redux'; -import { makeStyles } from 'tss-react/mui'; -import { clearDashboardFilter } from '../redux/dashboardFilter/DashboardFilterActions'; -import { menuIndexSelector, dashboardFilterTermSelector } from '../redux/Selectors'; -import { SidebarProvider, useSidebar } from './sidebar/SidebarProvider'; -import MainWindow from './MainWindow'; -import { Sidebar } from './sidebar/Sidebar'; -import TaskFilterTextField from '../components/TaskFilterTextfield'; -import DashboardDetailTabs from '../scenes/Dashboard/components/DashboardDetailTabs'; -import RoleViewSelect from '../scenes/Dashboard/components/RoleViewSelect'; -import LightToggleProfileMenu from './Components/LightToggleProfileMenu'; -import ForwardBackButtons from './ForwardBackButtons'; -import MobileNavigationDrawer from './MobileNavigationDrawer'; -import { - dashboardTabIndexSelector, -} from "../redux/Selectors"; - -import SearchIcon from "@mui/icons-material/Search"; -import ArrowBackIcon from "@mui/icons-material/ArrowBack"; - -const drawerWidth = 240; - -const openedMixin = (theme: Theme): CSSObject => ({ - width: drawerWidth, - transition: theme.transitions.create('width', { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - overflowX: 'hidden', -}); - -const closedMixin = (theme: Theme): CSSObject => ({ - transition: theme.transitions.create('width', { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen, - }), - overflowX: 'hidden', - width: `calc(${theme.spacing(7)} + 1px)`, - [theme.breakpoints.up('sm')]: { - width: `calc(${theme.spacing(8)} + 1px)`, - }, -}); - -interface AppBarProps extends MuiAppBarProps { - open?: boolean; -} - -const AppBar = styled(MuiAppBar, { - shouldForwardProp: (prop) => prop !== 'open', -})(({ theme }) => ({ - zIndex: theme.zIndex.drawer + 1, - transition: theme.transitions.create(['width', 'margin'], { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.leavingScreen, - }), - variants: [ - { - props: ({ open }: any) => open, - style: { - marginLeft: drawerWidth, - width: `calc(100% - ${drawerWidth}px)`, - transition: theme.transitions.create(['width', 'margin'], { - easing: theme.transitions.easing.sharp, - duration: theme.transitions.duration.enteringScreen, - }), - }, - }, - ], -})); - -const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })( - ({ theme }) => ({ - width: drawerWidth, - flexShrink: 0, - whiteSpace: 'nowrap', - boxSizing: 'border-box', - variants: [ - { - props: ({ open }: any) => open, - style: { - ...openedMixin(theme), - '& .MuiDrawer-paper': openedMixin(theme), - }, - }, - { - props: ({ open }: any) => !open, - style: { - ...closedMixin(theme), - '& .MuiDrawer-paper': closedMixin(theme), - }, - }, - ], - }), -); - -const useStyles2 = makeStyles()((theme) => { - return { - appBarComponents: { - margin: "auto", - width: "100%", - padding: 5, - color: theme.palette.text.primary, - }, - appBar: { - [theme.breakpoints.up("sm")]: { - width: "100%", - }, - background: theme.palette.background.paper, - }, - }; -}); - -export default function MenuMainContainer() { - const { classes } = useStyles2(); - const [searchMode, setSearchMode] = React.useState(false); - const dashboardTabIndex = useSelector(dashboardTabIndexSelector); - const menuIndex = useSelector(menuIndexSelector); - const currentFilter = useSelector(dashboardFilterTermSelector); - const toggleIcon = searchMode ? : ; - const dispatch = useDispatch(); - const {sidebarOpen} = useSidebar() - - const toggleSearchMode = () => { - if (searchMode) dispatch(clearDashboardFilter()); - setSearchMode(!searchMode); - }; - - const theme = useTheme(); - const isSm = useMediaQuery(theme.breakpoints.down("md")); - const isXs = useMediaQuery(theme.breakpoints.down("sm")); - - const updateSearchMode = React.useCallback( - (currentFilter, menuIndex, isSm) => { - if (menuIndex !== "dashboard") { - setSearchMode(false); - dispatch(clearDashboardFilter()); - } else if (currentFilter && isSm) { - setSearchMode((prevState) => { - if (!prevState) return true; - else return prevState; - }); - } - }, - [dispatch] - ); - - React.useEffect( - () => updateSearchMode(currentFilter, menuIndex, isSm), - [currentFilter, isSm, menuIndex, updateSearchMode] - ); - - React.useEffect(() => { - if (!isSm && searchMode) setSearchMode(false); - }, [isSm, searchMode]); - - - - return ( - - - - - - - {searchMode ? ( - - - {toggleIcon} - - - - ) : ( - <> - - - - - {menuIndex === "dashboard" && ( - <> - - - - - - - - {toggleIcon} - - - - )} - {isXs && - dashboardTabIndex !== 2 && - menuIndex === "dashboard" && } - - - )} - - - - - - - - - - - ); -} \ No newline at end of file diff --git a/src/navigation/MenuMainContainer3.tsx b/src/navigation/MenuMainContainer3.tsx new file mode 100644 index 000000000..67cf42be2 --- /dev/null +++ b/src/navigation/MenuMainContainer3.tsx @@ -0,0 +1,171 @@ +import * as React from "react"; +import { styled, useTheme } from "@mui/material/styles"; +import Box from "@mui/material/Box"; +import MuiAppBar, { AppBarProps as MuiAppBarProps } from "@mui/material/AppBar"; +import CssBaseline from "@mui/material/CssBaseline"; +import IconButton from "@mui/material/IconButton"; +import { drawerWidth, Sidebar } from "./sidebar/Sidebar"; +import MainWindow from "./MainWindow"; +import { makeStyles } from "tss-react/mui"; +import { Stack, Hidden, useMediaQuery } from "@mui/material"; +import TaskFilterTextField from "../components/TaskFilterTextfield"; +import DashboardDetailTabs from "../scenes/Dashboard/components/DashboardDetailTabs"; +import RoleViewSelect from "../scenes/Dashboard/components/RoleViewSelect"; +import LightToggleProfileMenu from "./Components/LightToggleProfileMenu"; +import ForwardBackButtons from "./ForwardBackButtons"; +import { TopbarButton } from "./sidebar/TopbarButton"; +import { clearDashboardFilter } from "../redux/dashboardFilter/DashboardFilterActions"; +import { useDispatch, useSelector } from "react-redux"; +import SearchIcon from "@mui/icons-material/Search"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import { + dashboardTabIndexSelector, + menuIndexSelector, +} from "../redux/Selectors"; + +const useStyles2 = makeStyles()((theme) => { + return { + appBarComponents: { + margin: "auto", + width: "100%", + padding: 5, + color: theme.palette.text.primary, + }, + appBar: { + [theme.breakpoints.up("sm")]: { + width: "100%", + }, + background: theme.palette.background.paper, + }, + }; +}); + +interface AppBarProps extends MuiAppBarProps { + isXs: boolean; + open: boolean; +} + +const AppBar = styled(MuiAppBar, { + shouldForwardProp: (prop) => prop !== "open", +})(({ theme, open, isXs }) => ({ + zIndex: theme.zIndex.drawer + 1, + transition: theme.transitions.create(["width", "margin"], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + ...(open && + !isXs && { + marginLeft: drawerWidth, + width: `calc(100% - ${drawerWidth}px)`, + transition: theme.transitions.create(["width", "margin"], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }), +})); + +export default function MiniDrawer() { + const menuIndex = useSelector(menuIndexSelector); + const dashboardTabIndex = useSelector(dashboardTabIndexSelector); + const { classes } = useStyles2(); + const theme = useTheme(); + const isXs = useMediaQuery(theme.breakpoints.down("sm")); + const [open, setOpen] = React.useState(false); + const [searchMode, setSearchMode] = React.useState(false); + const dispatch = useDispatch(); + const toggleIcon = searchMode ? : ; + const toggleSearchMode = () => { + if (searchMode) dispatch(clearDashboardFilter()); + setSearchMode(!searchMode); + }; + + const handleDrawerOpen = () => { + setOpen(true); + }; + + const toggleOpen = () => { + if (open) { + handleDrawerClose(); + } else { + handleDrawerOpen(); + } + }; + + const handleDrawerClose = () => { + setOpen(false); + }; + + return ( + + + + + {searchMode ? ( + + + {toggleIcon} + + + + ) : ( + <> + + + + + {menuIndex === "dashboard" && ( + <> + + + + + + + + {toggleIcon} + + + + )} + {isXs && + dashboardTabIndex !== 2 && + menuIndex === "dashboard" && } + + + )} + + + + + + ); +} diff --git a/src/navigation/sidebar/Sidebar.tsx b/src/navigation/sidebar/Sidebar.tsx index 9500b56fa..2996068ca 100644 --- a/src/navigation/sidebar/Sidebar.tsx +++ b/src/navigation/sidebar/Sidebar.tsx @@ -1,35 +1,114 @@ -import { Stack, IconButton, Drawer } from "@mui/material" -import { useSidebar } from "./SidebarProvider" +import { + Stack, + IconButton, + useMediaQuery, + useTheme, + styled, + CSSObject, + Theme, + Box, +} from "@mui/material"; +// import { useSidebar } from "./SidebarProvider"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -import { makeStyles } from 'tss-react/mui'; +import { makeStyles } from "tss-react/mui"; import { SidebarDrawerItems } from "./SidebarDrawerItems"; +import MuiDrawer from "@mui/material/Drawer"; + +export const drawerWidth = 250; const useStyles = makeStyles()({ list: { - width: 250, + width: drawerWidth, + }, + topBox: { + height: 58, + alignContent: "center", }, }); -export const Sidebar = () => { +const openedMixin = (theme: Theme): CSSObject => ({ + width: drawerWidth, + transition: theme.transitions.create("width", { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + overflowX: "hidden", +}); + +const closedMixin = (theme: Theme): CSSObject => ({ + transition: theme.transitions.create("width", { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + overflowX: "hidden", + width: `calc(${theme.spacing(7)} + 1px)`, + [theme.breakpoints.up("sm")]: { + width: `calc(${theme.spacing(8)} + 1px)`, + }, +}); + +const Drawer = styled(MuiDrawer, { + shouldForwardProp: (prop) => prop !== "open" && prop !== "isXs", +})<{ + open: boolean; + isXs: boolean; +}>(({ theme, open, isXs }) => { + if (isXs) { + // Do not override styles for temporary drawer (mobile) + return {}; + } + // Only apply mini-variant styles for permanent drawer + return { + width: drawerWidth, + flexShrink: 0, + whiteSpace: "nowrap", + boxSizing: "border-box", + ...(open + ? { + ...openedMixin(theme), + "& .MuiDrawer-paper": openedMixin(theme), + } + : { + ...closedMixin(theme), + "& .MuiDrawer-paper": closedMixin(theme), + }), + }; +}); + +export interface SidebarProps { + onClose: () => void; + open: boolean; // Optional prop to control the open state +} - const { sidebarOpen, toggleSidebar } = useSidebar() +export const Sidebar: React.FC = ({ onClose, open }) => { + const theme = useTheme(); + const isXs = useMediaQuery(theme.breakpoints.down("sm")); const { classes } = useStyles(); + // For temporary drawer, pass onClose prop so it can close on backdrop click return ( - + - - - + + + + + - ) -} \ No newline at end of file + ); +}; diff --git a/src/navigation/sidebar/SidebarDrawerItems.tsx b/src/navigation/sidebar/SidebarDrawerItems.tsx index 22d34679d..ebe0feeb6 100644 --- a/src/navigation/sidebar/SidebarDrawerItems.tsx +++ b/src/navigation/sidebar/SidebarDrawerItems.tsx @@ -1,7 +1,13 @@ import { FC } from "react"; import { useSelector } from "react-redux"; import { getWhoami } from "../../redux/Selectors"; -import { ListItemIcon, ListItemText, Divider, List, ListItemButton } from "@mui/material"; +import { + ListItemIcon, + ListItemText, + Divider, + List, + ListItemButton, +} from "@mui/material"; import { Link } from "react-router-dom"; import SupervisorAccountIcon from "@mui/icons-material/SupervisorAccount"; import * as models from "../../models"; @@ -156,4 +162,4 @@ export const SidebarDrawerItems: FC = (props) => { ); -} \ No newline at end of file +}; diff --git a/src/navigation/sidebar/SidebarProvider.tsx b/src/navigation/sidebar/SidebarProvider.tsx deleted file mode 100644 index 0bc94faa3..000000000 --- a/src/navigation/sidebar/SidebarProvider.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { createContext, FC, ReactNode, useContext, useState } from "react"; - -export interface SidebarProviderProps { - children: ReactNode; -} - -const SidebarContext = createContext<{ - sidebarOpen: boolean; - toggleSidebar: () => void; -} | null>(null); - -export const SidebarProvider: FC = ({ children }) => { - const [sidebarOpen, setSidebarOpen] = useState(true); - - const toggleSidebar = () => { - setSidebarOpen(!sidebarOpen); - }; - - return ( - - {children} - - ); -} - -export const useSidebar = () => { - const context = useContext(SidebarContext); - if (!context) { - throw new Error("useSidebar must be used within a SidebarProvider"); - } - return context; -}; \ No newline at end of file diff --git a/src/navigation/sidebar/TopbarButton.tsx b/src/navigation/sidebar/TopbarButton.tsx index e9aa7283f..088c7e2cb 100644 --- a/src/navigation/sidebar/TopbarButton.tsx +++ b/src/navigation/sidebar/TopbarButton.tsx @@ -1,13 +1,14 @@ import { IconButton } from "@mui/material"; -import { useSidebar } from "./SidebarProvider"; import MenuIcon from "@mui/icons-material/Menu"; -export const TopbarButton = () => { - const { toggleSidebar } = useSidebar(); +export interface TopbarButtonProps { + onClick: () => void; +} +export const TopbarButton: React.FC = ({ onClick }) => { return ( - + ); -} \ No newline at end of file +}; From 9eb02d4683df01dfe74abbee5bd07735c586afef Mon Sep 17 00:00:00 2001 From: Maurovic Cachia Date: Fri, 22 Aug 2025 17:16:07 +0200 Subject: [PATCH 3/5] Working sidebar collapsable --- src/App.tsx | 6 +- src/navigation/MenuMainContainer.js | 159 ------------------ ...inContainer3.tsx => MenuMainContainer.tsx} | 2 +- src/navigation/sidebar/Sidebar.tsx | 7 +- src/navigation/sidebar/SidebarDrawerItems.tsx | 27 +-- 5 files changed, 21 insertions(+), 180 deletions(-) delete mode 100644 src/navigation/MenuMainContainer.js rename src/navigation/{MenuMainContainer3.tsx => MenuMainContainer.tsx} (99%) diff --git a/src/App.tsx b/src/App.tsx index d063c164c..5bd54bcb3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -23,9 +23,7 @@ import SnackNotificationBar from "./components/SnackNotificationBar"; import TenantListProvider from "./scenes/TenantPicker/TenantListProvider"; import { initialiseApp } from "./redux/initialise/initialiseActions"; import * as Sentry from "@sentry/react"; -// import MenuMainContainer from "./navigation/MenuMainContainer2"; -// import { SidebarProvider } from "./navigation/sidebar/SidebarProvider"; -import MenuMainContainer from "./navigation/MenuMainContainer3"; +import { MenuMainContainer } from "./navigation/MenuMainContainer"; const GOOGLE_MAPS_API_KEY = process.env.REACT_APP_GOOGLE_MAPS_API_KEY as string; @@ -131,7 +129,6 @@ const App = (props: any) => { - {/* */} {process.env.REACT_APP_DEMO_MODE === "true" ? ( @@ -146,7 +143,6 @@ const App = (props: any) => { )} - {/* */} diff --git a/src/navigation/MenuMainContainer.js b/src/navigation/MenuMainContainer.js deleted file mode 100644 index 4df3f84a3..000000000 --- a/src/navigation/MenuMainContainer.js +++ /dev/null @@ -1,159 +0,0 @@ -import React, { useEffect, useState } from "react"; -import "../index.css"; -import { useTheme } from "@mui/material/styles"; -import { makeStyles } from "tss-react/mui"; -import AppBar from "@mui/material/AppBar"; -import IconButton from "@mui/material/IconButton"; -import MainWindow from "./MainWindow"; -import { useDispatch, useSelector } from "react-redux"; -import { Box, Hidden, Stack } from "@mui/material"; -import TaskFilterTextField from "../components/TaskFilterTextfield"; -import LightToggleProfileMenu from "./Components/LightToggleProfileMenu"; -import SearchIcon from "@mui/icons-material/Search"; -import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -import { clearDashboardFilter } from "../redux/dashboardFilter/DashboardFilterActions"; -import useMediaQuery from "@mui/material/useMediaQuery"; -import DashboardDetailTabs from "../scenes/Dashboard/components/DashboardDetailTabs"; -import MobileNavigationDrawer from "./MobileNavigationDrawer"; -import { - dashboardFilterTermSelector, - dashboardTabIndexSelector, - menuIndexSelector, -} from "../redux/Selectors"; -import RoleViewSelect from "../scenes/Dashboard/components/RoleViewSelect"; -import ForwardBackButtons from "./ForwardBackButtons"; - -const useStyles = makeStyles()((theme) => { - return { - appBarComponents: { - margin: "auto", - width: "100%", - padding: 5, - color: theme.palette.text.primary, - }, - appBar: { - [theme.breakpoints.up("sm")]: { - width: "100%", - }, - background: theme.palette.background.paper, - }, - }; -}); - -export function MenuMainContainer() { - const { classes } = useStyles(); - const [searchMode, setSearchMode] = useState(false); - const dashboardTabIndex = useSelector(dashboardTabIndexSelector); - const menuIndex = useSelector(menuIndexSelector); - const currentFilter = useSelector(dashboardFilterTermSelector); - const toggleIcon = searchMode ? : ; - const dispatch = useDispatch(); - - const toggleSearchMode = () => { - if (searchMode) dispatch(clearDashboardFilter()); - setSearchMode(!searchMode); - }; - - const theme = useTheme(); - const isSm = useMediaQuery(theme.breakpoints.down("md")); - const isXs = useMediaQuery(theme.breakpoints.down("sm")); - - const updateSearchMode = React.useCallback( - (currentFilter, menuIndex, isSm) => { - if (menuIndex !== "dashboard") { - setSearchMode(false); - dispatch(clearDashboardFilter()); - } else if (currentFilter && isSm) { - setSearchMode((prevState) => { - if (!prevState) return true; - else return prevState; - }); - } - }, - [dispatch] - ); - - useEffect( - () => updateSearchMode(currentFilter, menuIndex, isSm), - [currentFilter, isSm, menuIndex, updateSearchMode] - ); - - useEffect(() => { - if (!isSm && searchMode) setSearchMode(false); - }, [isSm, searchMode]); - - return ( - - - - {searchMode ? ( - - - {toggleIcon} - - - - ) : ( - <> - - - - - {menuIndex === "dashboard" && ( - <> - - - - - - - - {toggleIcon} - - - - )} - {isXs && - dashboardTabIndex !== 2 && - menuIndex === "dashboard" && } - - - )} - - - - - ); -} diff --git a/src/navigation/MenuMainContainer3.tsx b/src/navigation/MenuMainContainer.tsx similarity index 99% rename from src/navigation/MenuMainContainer3.tsx rename to src/navigation/MenuMainContainer.tsx index 67cf42be2..211847839 100644 --- a/src/navigation/MenuMainContainer3.tsx +++ b/src/navigation/MenuMainContainer.tsx @@ -64,7 +64,7 @@ const AppBar = styled(MuiAppBar, { }), })); -export default function MiniDrawer() { +export function MenuMainContainer() { const menuIndex = useSelector(menuIndexSelector); const dashboardTabIndex = useSelector(dashboardTabIndexSelector); const { classes } = useStyles2(); diff --git a/src/navigation/sidebar/Sidebar.tsx b/src/navigation/sidebar/Sidebar.tsx index 2996068ca..045568233 100644 --- a/src/navigation/sidebar/Sidebar.tsx +++ b/src/navigation/sidebar/Sidebar.tsx @@ -8,7 +8,6 @@ import { Theme, Box, } from "@mui/material"; -// import { useSidebar } from "./SidebarProvider"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { makeStyles } from "tss-react/mui"; import { SidebarDrawerItems } from "./SidebarDrawerItems"; @@ -20,6 +19,9 @@ const useStyles = makeStyles()({ list: { width: drawerWidth, }, + closedList: { + width: "100%", + }, topBox: { height: 58, alignContent: "center", @@ -105,7 +107,8 @@ export const Sidebar: React.FC = ({ onClose, open }) => { diff --git a/src/navigation/sidebar/SidebarDrawerItems.tsx b/src/navigation/sidebar/SidebarDrawerItems.tsx index ebe0feeb6..db6094f80 100644 --- a/src/navigation/sidebar/SidebarDrawerItems.tsx +++ b/src/navigation/sidebar/SidebarDrawerItems.tsx @@ -21,6 +21,7 @@ import PeopleAltIcon from "@mui/icons-material/PeopleAlt"; import TwoWheelerIcon from "@mui/icons-material/TwoWheeler"; export interface SidebarDrawerItemsProps { + open?: boolean; className?: string; onSelect: () => void; } @@ -41,12 +42,12 @@ export const SidebarDrawerItems: FC = (props) => { onClick={onSelect} selected={menuIndex === "admin"} component={Link} - to={"/admin"} + to="/admin" > - + {props.open ? : <>} ); } @@ -59,12 +60,12 @@ export const SidebarDrawerItems: FC = (props) => { onClick={onSelect} selected={menuIndex === "history"} component={Link} - to={"/history"} + to="/history" > - + {props.open ? : <>} ); statisticsLink = ( @@ -72,12 +73,12 @@ export const SidebarDrawerItems: FC = (props) => { onClick={onSelect} selected={menuIndex === "statistics"} component={Link} - to={"/statistics"} + to="/statistics" > - + {props.open ? : <>} ); scheduledTasksLink = ( @@ -85,12 +86,12 @@ export const SidebarDrawerItems: FC = (props) => { onClick={onSelect} selected={menuIndex === "scheduled"} component={Link} - to={"/scheduled"} + to="/scheduled" > - + {props.open ? : <>} ); } @@ -109,7 +110,7 @@ export const SidebarDrawerItems: FC = (props) => { - + {props.open ? : <>} = (props) => { - + {props.open ? : <>} = (props) => { - + {props.open ? : <>} = (props) => { - + {props.open ? : <>} = (props) => { - + {props.open ? : <>} {scheduledTasksLink} {statisticsLink} From 00bb9eb4da885e6857c91533503f6f540b7d2547 Mon Sep 17 00:00:00 2001 From: Maurovic Cachia Date: Fri, 22 Aug 2025 17:51:01 +0200 Subject: [PATCH 4/5] Fixes for Mobile Mode --- src/navigation/MainWindow.js | 4 +- src/navigation/MenuMainContainer.tsx | 7 + src/navigation/MobileNavigationDrawer.js | 62 -------- src/navigation/NavDrawerItems.js | 177 ----------------------- src/navigation/sidebar/Sidebar.tsx | 4 +- 5 files changed, 10 insertions(+), 244 deletions(-) delete mode 100644 src/navigation/MobileNavigationDrawer.js delete mode 100644 src/navigation/NavDrawerItems.js diff --git a/src/navigation/MainWindow.js b/src/navigation/MainWindow.js index d25241c2f..ff8337611 100644 --- a/src/navigation/MainWindow.js +++ b/src/navigation/MainWindow.js @@ -33,10 +33,10 @@ const useStyles = makeStyles()((theme, { navIndex, guidedSetupOpen }) => ({ root: { marginRight: guidedSetupOpen && navIndex === "dashboard" ? 0 : "auto", marginLeft: navIndex === "dashboard" ? 0 : 20, - paddingTop: 58, + paddingTop: 78, paddingBottom: 10, [theme.breakpoints.down("md")]: { - paddingTop: 5, + // paddingTop: 5, marginLeft: 0, marginRight: 0, }, diff --git a/src/navigation/MenuMainContainer.tsx b/src/navigation/MenuMainContainer.tsx index 211847839..e641411ef 100644 --- a/src/navigation/MenuMainContainer.tsx +++ b/src/navigation/MenuMainContainer.tsx @@ -22,6 +22,7 @@ import { dashboardTabIndexSelector, menuIndexSelector, } from "../redux/Selectors"; +import { useCordovaBackButton } from "../hooks/useCordovaBackButton"; const useStyles2 = makeStyles()((theme) => { return { @@ -79,6 +80,12 @@ export function MenuMainContainer() { setSearchMode(!searchMode); }; + useCordovaBackButton(() => { + if (isXs) { + setOpen(false); + } + }, open); + const handleDrawerOpen = () => { setOpen(true); }; diff --git a/src/navigation/MobileNavigationDrawer.js b/src/navigation/MobileNavigationDrawer.js deleted file mode 100644 index 76c49edfe..000000000 --- a/src/navigation/MobileNavigationDrawer.js +++ /dev/null @@ -1,62 +0,0 @@ -import { useState } from "react"; -import NavDrawerItems from "./NavDrawerItems"; -import IconButton from "@mui/material/IconButton"; -import MenuIcon from "@mui/icons-material/Menu"; -import { makeStyles } from 'tss-react/mui'; -import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -import { Stack, SwipeableDrawer } from "@mui/material"; -import { useCordovaBackButton } from "../hooks/useCordovaBackButton"; - -const useStyles = makeStyles()({ - list: { - width: 250, - }, -}); - -export default function MobileNavigationDrawer() { - const [open, setOpen] = useState(true); - const { classes } = useStyles(); - - useCordovaBackButton(() => { - setOpen(false); - }, open); - - const toggleDrawer = (event) => { - if ( - event && - event.type === "keydown" && - (event.key === "Tab" || event.key === "Shift") - ) { - return; - } - setOpen(!open); - }; - - return ( -
- - - - toggleDrawer(false)} - onOpen={() => toggleDrawer(true)} - > - - toggleDrawer(false)}> - - - setOpen(false)} - /> - - -
- ); -} diff --git a/src/navigation/NavDrawerItems.js b/src/navigation/NavDrawerItems.js deleted file mode 100644 index 0af6c0811..000000000 --- a/src/navigation/NavDrawerItems.js +++ /dev/null @@ -1,177 +0,0 @@ -import React from "react"; -import { useSelector } from "react-redux"; -import { ListItem, ListItemIcon, ListItemText } from "@mui/material"; -import TwoWheelerIcon from "@mui/icons-material/TwoWheeler"; -import PeopleAltIcon from "@mui/icons-material/PeopleAlt"; -import SupervisorAccountIcon from "@mui/icons-material/SupervisorAccount"; -import { Link } from "react-router-dom"; -import Divider from "@mui/material/Divider"; -import * as models from "../models"; -import List from "@mui/material/List"; -import PropTypes from "prop-types"; -import DashboardIcon from "@mui/icons-material/Dashboard"; -import LocationCityIcon from "@mui/icons-material/LocationCity"; -import BarChartIcon from "@mui/icons-material/BarChart"; -import DescriptionIcon from "@mui/icons-material/Description"; -import { getWhoami } from "../redux/Selectors"; -import HistoryIcon from "@mui/icons-material/History"; -import CalendarMonthIcon from "@mui/icons-material/CalendarMonth"; - -function NavDrawerItems(props) { - const whoami = useSelector(getWhoami); - const menuIndex = useSelector((state) => state.menuIndex); - const onSelect = props.onSelect; - let adminLink = <>; - let historyLink = <>; - let statisticsLink = <>; - let scheduledTasksLink = <>; - - if (whoami.roles) { - if (whoami.roles.includes("ADMIN")) { - adminLink = ( - - - - - - - ); - } - if ( - whoami.roles.includes(models.Role.ADMIN) || - whoami.roles.includes(models.Role.COORDINATOR) - ) { - historyLink = ( - - - - - - - ); - statisticsLink = ( - - - - - - - ); - scheduledTasksLink = ( - - - - - - - ); - } - } - - return ( -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {scheduledTasksLink} - {statisticsLink} - {historyLink} - {adminLink} - -
- ); -} - -NavDrawerItems.propTypes = { - onSelect: PropTypes.func, - className: PropTypes.string, -}; - -NavDrawerItems.defaultProps = { - onSelect: () => {}, -}; - -export default NavDrawerItems; diff --git a/src/navigation/sidebar/Sidebar.tsx b/src/navigation/sidebar/Sidebar.tsx index 045568233..b2ddab37c 100644 --- a/src/navigation/sidebar/Sidebar.tsx +++ b/src/navigation/sidebar/Sidebar.tsx @@ -49,9 +49,7 @@ const closedMixin = (theme: Theme): CSSObject => ({ }, }); -const Drawer = styled(MuiDrawer, { - shouldForwardProp: (prop) => prop !== "open" && prop !== "isXs", -})<{ +const Drawer = styled(MuiDrawer)<{ open: boolean; isXs: boolean; }>(({ theme, open, isXs }) => { From b588f3d937573ee2e3bf535d835cc3a0371c44bf Mon Sep 17 00:00:00 2001 From: Maurovic Cachia Date: Mon, 1 Sep 2025 15:51:10 +0200 Subject: [PATCH 5/5] Feedback Changes to Sidebar --- src/navigation/MainWindow.js | 8 ++- src/navigation/MenuMainContainer.tsx | 59 ++++++++++++++----- src/navigation/sidebar/Sidebar.tsx | 35 +++++++---- src/navigation/sidebar/SidebarDrawerItems.tsx | 42 ++++++------- 4 files changed, 95 insertions(+), 49 deletions(-) diff --git a/src/navigation/MainWindow.js b/src/navigation/MainWindow.js index ff8337611..ab67cf707 100644 --- a/src/navigation/MainWindow.js +++ b/src/navigation/MainWindow.js @@ -1,4 +1,3 @@ -import React from "react"; import "../index.css"; import { Route, Switch, useLocation } from "react-router-dom"; import Dashboard from "../scenes/Dashboard/Dashboard"; @@ -31,10 +30,15 @@ import ScheduledTaskOverviewRoute from "../scenes/ScheduledTasks/components/Sche const useStyles = makeStyles()((theme, { navIndex, guidedSetupOpen }) => ({ root: { + [theme.breakpoints.up("sm")]: { + display: "flex", + flex: 1, + }, marginRight: guidedSetupOpen && navIndex === "dashboard" ? 0 : "auto", marginLeft: navIndex === "dashboard" ? 0 : 20, paddingTop: 78, paddingBottom: 10, + minWidth: 0, [theme.breakpoints.down("md")]: { // paddingTop: 5, marginLeft: 0, @@ -57,7 +61,7 @@ export default function MainWindow(_props) { // whenever returning an item, set the MenuIndex to update the drawer menu return ( -
+
prop !== "open", + shouldForwardProp: (prop) => prop !== "open" && prop !== "isXs", })(({ theme, open, isXs }) => ({ zIndex: theme.zIndex.drawer + 1, + background: theme.palette.background.paper, transition: theme.transitions.create(["width", "margin"], { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.leavingScreen, }), + boxShadow: + "0px 2px 0px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12)", ...(open && !isXs && { - marginLeft: drawerWidth, - width: `calc(100% - ${drawerWidth}px)`, + // marginLeft: drawerWidth, + // width: `calc(100% - ${drawerWidth}px)`, transition: theme.transitions.create(["width", "margin"], { easing: theme.transitions.easing.sharp, duration: theme.transitions.duration.enteringScreen, @@ -74,7 +83,7 @@ export function MenuMainContainer() { const [open, setOpen] = React.useState(false); const [searchMode, setSearchMode] = React.useState(false); const dispatch = useDispatch(); - const toggleIcon = searchMode ? : ; + const toggleIcon = searchMode ? : ; const toggleSearchMode = () => { if (searchMode) dispatch(clearDashboardFilter()); setSearchMode(!searchMode); @@ -103,7 +112,15 @@ export function MenuMainContainer() { }; return ( - + - - + + + + ); } diff --git a/src/navigation/sidebar/Sidebar.tsx b/src/navigation/sidebar/Sidebar.tsx index b2ddab37c..90148d341 100644 --- a/src/navigation/sidebar/Sidebar.tsx +++ b/src/navigation/sidebar/Sidebar.tsx @@ -1,17 +1,14 @@ import { Stack, - IconButton, useMediaQuery, useTheme, styled, CSSObject, Theme, - Box, + Drawer as MuiDrawer, } from "@mui/material"; -import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { makeStyles } from "tss-react/mui"; import { SidebarDrawerItems } from "./SidebarDrawerItems"; -import MuiDrawer from "@mui/material/Drawer"; export const drawerWidth = 250; @@ -22,9 +19,12 @@ const useStyles = makeStyles()({ closedList: { width: "100%", }, - topBox: { - height: 58, - alignContent: "center", + // topBox: { + // height: 58, + // alignContent: "center", + // }, + stack: { + paddingTop: 58, }, }); @@ -49,7 +49,9 @@ const closedMixin = (theme: Theme): CSSObject => ({ }, }); -const Drawer = styled(MuiDrawer)<{ +const Drawer = styled(MuiDrawer, { + shouldForwardProp: (prop) => prop !== "isXs", +})<{ open: boolean; isXs: boolean; }>(({ theme, open, isXs }) => { @@ -59,10 +61,13 @@ const Drawer = styled(MuiDrawer)<{ } // Only apply mini-variant styles for permanent drawer return { + display: "flex", width: drawerWidth, flexShrink: 0, whiteSpace: "nowrap", boxSizing: "border-box", + background: theme.palette.background.paper, + borderRight: 0, ...(open ? { ...openedMixin(theme), @@ -93,17 +98,27 @@ export const Sidebar: React.FC = ({ onClose, open }) => { onClose={isXs ? onClose : undefined} ModalProps={isXs ? { keepMounted: true } : undefined} // Better mobile performance isXs={isXs} + PaperProps={ + !isXs + ? { + style: { borderRight: "0px", position: "relative" }, + } + : { + style: { background: theme.palette.background.paper }, + } + } > - + {/* - + */} = (props) => { to="/admin" > - + {props.open ? : <>} @@ -63,7 +64,7 @@ export const SidebarDrawerItems: FC = (props) => { to="/history" > - + {props.open ? : <>} @@ -76,7 +77,7 @@ export const SidebarDrawerItems: FC = (props) => { to="/statistics" > - + {props.open ? : <>} @@ -89,7 +90,7 @@ export const SidebarDrawerItems: FC = (props) => { to="/scheduled" > - + {props.open ? : <>} @@ -99,8 +100,7 @@ export const SidebarDrawerItems: FC = (props) => { return (
- - + = (props) => { to="/" > - + {props.open ? : <>} @@ -119,7 +119,7 @@ export const SidebarDrawerItems: FC = (props) => { to="/users" > - + {props.open ? : <>} @@ -130,7 +130,7 @@ export const SidebarDrawerItems: FC = (props) => { to="/vehicles" > - + {props.open ? : <>} @@ -141,7 +141,7 @@ export const SidebarDrawerItems: FC = (props) => { to="/locations" > - + {props.open ? : <>} @@ -152,7 +152,7 @@ export const SidebarDrawerItems: FC = (props) => { to="/reports" > - + {props.open ? : <>}