From 37c186b5f34d804c29a02a3014c1b2a0124563f9 Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Thu, 24 Aug 2023 12:20:41 -0400 Subject: [PATCH 01/11] Initial implementation of a side drawer for mobile view --- app/src/components/Base.tsx | 111 +++++++++++++++++++++++++++--------- 1 file changed, 83 insertions(+), 28 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index cbce34e..59d5ff0 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import i18n from "i18next"; import { useTranslation } from "react-i18next"; import { @@ -6,8 +6,16 @@ import { Paper, BottomNavigation, BottomNavigationAction, + SwipeableDrawer, + List, + ListItemIcon, + ListItemButton, + ListItemText, + ListItem, + IconButton, } from "@mui/material"; import { Home, Info, CorporateFare, QuestionAnswer } from "@mui/icons-material"; +import MenuIcon from '@mui/icons-material/Menu'; import { Link, Outlet, useLocation, useParams } from "react-router-dom"; import { getLocaleOrFallback, SAVED_LOCALE } from "../locale"; @@ -43,34 +51,81 @@ export const Base = () => { window.scrollTo(0, 0); }, [pathWithoutLocale]); + const [width, setWidth] = React.useState(window.innerWidth); + const breakpoint = 700; + + const [drawerState, setState] = useState(false); + + useEffect(() => { + window.addEventListener("resize", () => setWidth(window.innerWidth)); + } , []); + return ( - - - - - - - {ROUTES.map((r) => { - const Icon = ICONS[r]; - const route = ROUTE_NAME_TO_ROUTE[r]; - const routeWithLocale = `${locale}/${route}`; + ( width > breakpoint + ? + + + + + + {ROUTES.map((r) => { + const Icon = ICONS[r]; + const route = ROUTE_NAME_TO_ROUTE[r]; + const routeWithLocale = `${locale}/${route}`; + + return ( + } + to={routeWithLocale} + value={route} + component={Link} + /> + ); + })} + + + + : + + + setState(true)}> + + + + setState(true)} + onClose={() => setState(false)} + > + + {ROUTES.map((r) => { + const Icon = ICONS[r]; + const route = ROUTE_NAME_TO_ROUTE[r]; + const routeWithLocale = `${locale}/${route}`; - return ( - } - to={routeWithLocale} - value={route} - component={Link} - /> - ); - })} - - - + return ( + + setState(false)}> + + {} + + + + + ); + })} + + + + + + + ) ); }; From 23faf9e3b46718242c4fe573f0d6f43cc46f62da Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Fri, 25 Aug 2023 10:52:29 -0400 Subject: [PATCH 02/11] optimizations for top menu bar and side drawer --- app/src/components/Base.tsx | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index 59d5ff0..041c8d3 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -6,13 +6,13 @@ import { Paper, BottomNavigation, BottomNavigationAction, - SwipeableDrawer, List, ListItemIcon, ListItemButton, ListItemText, ListItem, IconButton, + Drawer, } from "@mui/material"; import { Home, Info, CorporateFare, QuestionAnswer } from "@mui/icons-material"; import MenuIcon from '@mui/icons-material/Menu'; @@ -54,7 +54,7 @@ export const Base = () => { const [width, setWidth] = React.useState(window.innerWidth); const breakpoint = 700; - const [drawerState, setState] = useState(false); + const [drawerState, setDrawerState] = useState(false); useEffect(() => { window.addEventListener("resize", () => setWidth(window.innerWidth)); @@ -91,17 +91,19 @@ export const Base = () => { : - - - setState(true)}> - + + + setDrawerState(true)}> + - - + setState(true)} - onClose={() => setState(false)} + onClose={() => setDrawerState(false)} > {ROUTES.map((r) => { @@ -111,7 +113,7 @@ export const Base = () => { return ( - setState(false)}> + setDrawerState(false)}> {} @@ -121,7 +123,7 @@ export const Base = () => { ); })} - + From a5d40e8e9cfa34f25e70800fdb09b075518e72b2 Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Sat, 9 Sep 2023 19:48:25 -0400 Subject: [PATCH 03/11] Minor refactor to fix coding style --- app/src/components/Base.tsx | 76 ++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index 041c8d3..45ebe23 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -14,8 +14,7 @@ import { IconButton, Drawer, } from "@mui/material"; -import { Home, Info, CorporateFare, QuestionAnswer } from "@mui/icons-material"; -import MenuIcon from '@mui/icons-material/Menu'; +import { Home, Info, CorporateFare, QuestionAnswer, Menu } from "@mui/icons-material"; import { Link, Outlet, useLocation, useParams } from "react-router-dom"; import { getLocaleOrFallback, SAVED_LOCALE } from "../locale"; @@ -35,6 +34,8 @@ const ROUTE_NAME_TO_ROUTE = { faq: "faq", } as const; +const BREAKPOINT = 700; + export const Base = () => { const { t } = useTranslation(); const { pathname } = useLocation(); @@ -42,6 +43,9 @@ export const Base = () => { const params = useParams(); const locale = getLocaleOrFallback(params.locale as string); + const [width, setWidth] = React.useState(window.innerWidth); + const [drawerState, setDrawerState] = useState(false); + useEffect(() => { localStorage.setItem(SAVED_LOCALE, locale); i18n.changeLanguage(locale); @@ -51,53 +55,49 @@ export const Base = () => { window.scrollTo(0, 0); }, [pathWithoutLocale]); - const [width, setWidth] = React.useState(window.innerWidth); - const breakpoint = 700; - - const [drawerState, setDrawerState] = useState(false); - useEffect(() => { window.addEventListener("resize", () => setWidth(window.innerWidth)); } , []); return ( - ( width > breakpoint - ? - - - - - - {ROUTES.map((r) => { - const Icon = ICONS[r]; - const route = ROUTE_NAME_TO_ROUTE[r]; - const routeWithLocale = `${locale}/${route}`; - - return ( - } - to={routeWithLocale} - value={route} - component={Link} - /> - ); - })} - - + ( width > BREAKPOINT + ? + + + + + + {ROUTES.map((r) => { + const Icon = ICONS[r]; + const route = ROUTE_NAME_TO_ROUTE[r]; + const routeWithLocale = `${locale}/${route}`; + + return ( + } + to={routeWithLocale} + value={route} + component={Link} + /> + ); + })} + + + : setDrawerState(true)}> - + { setDrawerState(false)}> - {} + From 386a19eed4de15592776fa40794dc26157fadaad Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Mon, 2 Oct 2023 22:30:04 -0400 Subject: [PATCH 04/11] Simplified code to use mui components --- app/src/components/Base.tsx | 70 +++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index 45ebe23..cfc64d3 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -13,6 +13,8 @@ import { ListItem, IconButton, Drawer, + useMediaQuery, + Theme, } from "@mui/material"; import { Home, Info, CorporateFare, QuestionAnswer, Menu } from "@mui/icons-material"; import { Link, Outlet, useLocation, useParams } from "react-router-dom"; @@ -34,8 +36,6 @@ const ROUTE_NAME_TO_ROUTE = { faq: "faq", } as const; -const BREAKPOINT = 700; - export const Base = () => { const { t } = useTranslation(); const { pathname } = useLocation(); @@ -43,8 +43,8 @@ export const Base = () => { const params = useParams(); const locale = getLocaleOrFallback(params.locale as string); - const [width, setWidth] = React.useState(window.innerWidth); const [drawerState, setDrawerState] = useState(false); + const isSmall = useMediaQuery((theme) => theme.breakpoints.down("sm")); useEffect(() => { localStorage.setItem(SAVED_LOCALE, locale); @@ -55,42 +55,9 @@ export const Base = () => { window.scrollTo(0, 0); }, [pathWithoutLocale]); - useEffect(() => { - window.addEventListener("resize", () => setWidth(window.innerWidth)); - } , []); - return ( - ( width > BREAKPOINT + ( isSmall ? - - - - - - - {ROUTES.map((r) => { - const Icon = ICONS[r]; - const route = ROUTE_NAME_TO_ROUTE[r]; - const routeWithLocale = `${locale}/${route}`; - - return ( - } - to={routeWithLocale} - value={route} - component={Link} - /> - ); - })} - - - - : { + : + + + + + + + {ROUTES.map((r) => { + const Icon = ICONS[r]; + const route = ROUTE_NAME_TO_ROUTE[r]; + const routeWithLocale = `${locale}/${route}`; + + return ( + } + to={routeWithLocale} + value={route} + component={Link} + /> + ); + })} + + + ) ); }; From 2ca82747eff68f36a508c279b011fddd4bc2a8ad Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Fri, 6 Oct 2023 23:03:38 -0400 Subject: [PATCH 05/11] refactored with prettier --- app/src/components/Base.tsx | 140 ++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 68 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index cfc64d3..f11bc73 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -16,7 +16,13 @@ import { useMediaQuery, Theme, } from "@mui/material"; -import { Home, Info, CorporateFare, QuestionAnswer, Menu } from "@mui/icons-material"; +import { + Home, + Info, + CorporateFare, + QuestionAnswer, + Menu, +} from "@mui/icons-material"; import { Link, Outlet, useLocation, useParams } from "react-router-dom"; import { getLocaleOrFallback, SAVED_LOCALE } from "../locale"; @@ -55,75 +61,73 @@ export const Base = () => { window.scrollTo(0, 0); }, [pathWithoutLocale]); - return ( - ( isSmall - ? - - - setDrawerState(true)}> - - - - setDrawerState(false)} - > - - {ROUTES.map((r) => { - const Icon = ICONS[r]; - const route = ROUTE_NAME_TO_ROUTE[r]; - const routeWithLocale = `${locale}/${route}`; + return isSmall ? ( + + + setDrawerState(true)}> + + + + setDrawerState(false)} + > + + {ROUTES.map((r) => { + const Icon = ICONS[r]; + const route = ROUTE_NAME_TO_ROUTE[r]; + const routeWithLocale = `${locale}/${route}`; - return ( - - setDrawerState(false)}> - - - - - - - ); - })} - - - - - + return ( + + setDrawerState(false)} + > + + + + + + + ); + })} + + + + - : - - - - - - - {ROUTES.map((r) => { - const Icon = ICONS[r]; - const route = ROUTE_NAME_TO_ROUTE[r]; - const routeWithLocale = `${locale}/${route}`; + + ) : ( + + + + + + + {ROUTES.map((r) => { + const Icon = ICONS[r]; + const route = ROUTE_NAME_TO_ROUTE[r]; + const routeWithLocale = `${locale}/${route}`; - return ( - } - to={routeWithLocale} - value={route} - component={Link} - /> - ); - })} - - - - ) + return ( + } + to={routeWithLocale} + value={route} + component={Link} + /> + ); + })} + + + ); }; From 3f20b2680b2a49a389c6e83dcd321f2be760baaa Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Fri, 6 Oct 2023 23:24:18 -0400 Subject: [PATCH 06/11] updated name of drawer hook --- app/src/components/Base.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index f11bc73..228b7e0 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -49,7 +49,7 @@ export const Base = () => { const params = useParams(); const locale = getLocaleOrFallback(params.locale as string); - const [drawerState, setDrawerState] = useState(false); + const [isDrawerOpen, setIsDrawerOpen] = useState(false); const isSmall = useMediaQuery((theme) => theme.breakpoints.down("sm")); useEffect(() => { @@ -64,14 +64,14 @@ export const Base = () => { return isSmall ? ( - setDrawerState(true)}> + setIsDrawerOpen(true)}> setDrawerState(false)} + onClose={() => setIsDrawerOpen(false)} > {ROUTES.map((r) => { @@ -84,7 +84,7 @@ export const Base = () => { setDrawerState(false)} + onClick={() => setIsDrawerOpen(false)} > From b06e85329b56cc4d786370af33a2f48e61226b63 Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Sat, 7 Oct 2023 00:09:02 -0400 Subject: [PATCH 07/11] renamed route key --- app/src/components/Base.tsx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index 228b7e0..c148034 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -74,13 +74,13 @@ export const Base = () => { onClose={() => setIsDrawerOpen(false)} > - {ROUTES.map((r) => { - const Icon = ICONS[r]; - const route = ROUTE_NAME_TO_ROUTE[r]; + {ROUTES.map((routeName) => { + const Icon = ICONS[routeName]; + const route = ROUTE_NAME_TO_ROUTE[routeName]; const routeWithLocale = `${locale}/${route}`; return ( - + { - + ); @@ -110,15 +110,15 @@ export const Base = () => { elevation={2} > - {ROUTES.map((r) => { - const Icon = ICONS[r]; - const route = ROUTE_NAME_TO_ROUTE[r]; + {ROUTES.map((routeName) => { + const Icon = ICONS[routeName]; + const route = ROUTE_NAME_TO_ROUTE[routeName]; const routeWithLocale = `${locale}/${route}`; return ( } to={routeWithLocale} value={route} From 1c9a91efee61a2a0e566a5cc36da7446df0d7ae0 Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Mon, 9 Oct 2023 20:17:33 -0400 Subject: [PATCH 08/11] Implementing better navbar mapping system, added text highlighting for sidebar --- app/src/components/Base.tsx | 88 +++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index c148034..334841a 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import i18n from "i18next"; import { useTranslation } from "react-i18next"; import { @@ -10,7 +10,6 @@ import { ListItemIcon, ListItemButton, ListItemText, - ListItem, IconButton, Drawer, useMediaQuery, @@ -26,7 +25,7 @@ import { import { Link, Outlet, useLocation, useParams } from "react-router-dom"; import { getLocaleOrFallback, SAVED_LOCALE } from "../locale"; -const ROUTES = ["home", "about", "organization", "faq"] as const; +const ROUTE_NAMES = ["home", "about", "organization", "faq"] as const; const ICONS = { home: Home, @@ -35,13 +34,25 @@ const ICONS = { faq: QuestionAnswer, } as const; -const ROUTE_NAME_TO_ROUTE = { +const ROUTE_NAME_TO_PATH = { home: "", about: "about", organization: "organization", faq: "faq", } as const; +type RouteName = (typeof ROUTE_NAMES)[number]; +type NavigationIcon = (typeof ICONS)[keyof typeof ICONS]; +type Path = (typeof ROUTE_NAME_TO_PATH)[keyof typeof ROUTE_NAME_TO_PATH]; +type PathWithLocale = `${ReturnType}/${Path}`; + +type NavigationBarItem = { + routeName: RouteName; + Icon: NavigationIcon; + path: Path; + pathWithLocale: PathWithLocale; +}; + export const Base = () => { const { t } = useTranslation(); const { pathname } = useLocation(); @@ -61,6 +72,19 @@ export const Base = () => { window.scrollTo(0, 0); }, [pathWithoutLocale]); + const navigationBarItems: NavigationBarItem[] = ROUTE_NAMES.map( + (routeName) => { + const path = ROUTE_NAME_TO_PATH[routeName]; + + return { + routeName, + Icon: ICONS[routeName], + path, + pathWithLocale: `${locale}/${path}`, + }; + }, + ); + return isSmall ? ( @@ -74,26 +98,26 @@ export const Base = () => { onClose={() => setIsDrawerOpen(false)} > - {ROUTES.map((routeName) => { - const Icon = ICONS[routeName]; - const route = ROUTE_NAME_TO_ROUTE[routeName]; - const routeWithLocale = `${locale}/${route}`; - - return ( - - setIsDrawerOpen(false)} + {navigationBarItems.map( + ({ routeName, Icon, path, pathWithLocale }) => ( + setIsDrawerOpen(false)} + > + - - - - - - - ); - })} + + + + + ), + )} @@ -110,22 +134,18 @@ export const Base = () => { elevation={2} > - {ROUTES.map((routeName) => { - const Icon = ICONS[routeName]; - const route = ROUTE_NAME_TO_ROUTE[routeName]; - const routeWithLocale = `${locale}/${route}`; - - return ( + {navigationBarItems.map( + ({ routeName, Icon, path, pathWithLocale }) => ( } - to={routeWithLocale} - value={route} component={Link} + to={pathWithLocale} + icon={} + value={path} /> - ); - })} + ), + )} From 44074cde14101142f18392a3608ce1f4259e9e51 Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Mon, 9 Oct 2023 20:54:07 -0400 Subject: [PATCH 09/11] Use mui theme rather than hard coding color --- app/src/components/Base.tsx | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index 334841a..0bf6570 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -14,6 +14,7 @@ import { Drawer, useMediaQuery, Theme, + useTheme, } from "@mui/material"; import { Home, @@ -59,9 +60,10 @@ export const Base = () => { const pathWithoutLocale = pathname.split("/").at(-1); const params = useParams(); const locale = getLocaleOrFallback(params.locale as string); + const theme = useTheme(); + const isSmall = useMediaQuery((theme) => theme.breakpoints.down("sm")); const [isDrawerOpen, setIsDrawerOpen] = useState(false); - const isSmall = useMediaQuery((theme) => theme.breakpoints.down("sm")); useEffect(() => { localStorage.setItem(SAVED_LOCALE, locale); @@ -85,6 +87,8 @@ export const Base = () => { }, ); + console.log(theme); + return isSmall ? ( @@ -107,13 +111,23 @@ export const Base = () => { onClick={() => setIsDrawerOpen(false)} > ), From 678cb60a35c9bafcc692d0ae9f759065bc688302 Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Mon, 9 Oct 2023 20:55:43 -0400 Subject: [PATCH 10/11] Remove debugging stuff --- app/src/components/Base.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index 0bf6570..fbc20ea 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -87,8 +87,6 @@ export const Base = () => { }, ); - console.log(theme); - return isSmall ? ( From cc141f9fb49fe70084a42d95e7e25d16f1067430 Mon Sep 17 00:00:00 2001 From: Nicholas McKee Date: Sat, 28 Oct 2023 17:58:05 -0400 Subject: [PATCH 11/11] Simplify duplicate code --- app/src/components/Base.tsx | 49 +++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/app/src/components/Base.tsx b/app/src/components/Base.tsx index fbc20ea..19641a7 100644 --- a/app/src/components/Base.tsx +++ b/app/src/components/Base.tsx @@ -101,34 +101,29 @@ export const Base = () => { > {navigationBarItems.map( - ({ routeName, Icon, path, pathWithLocale }) => ( - setIsDrawerOpen(false)} - > - { + const color = + pathWithoutLocale === path + ? theme.palette.primary.main + : undefined; + + return ( + setIsDrawerOpen(false)} > - - - - - ), + + + + + + ); + }, )}