Skip to content

Commit

Permalink
Nav bar redesign for mobile users (#54)
Browse files Browse the repository at this point in the history
* Initial implementation of a side drawer for mobile view

* optimizations for top menu bar and side drawer

* Minor refactor to fix coding style

* Simplified code to use mui components

* refactored with prettier

* updated name of drawer hook

* renamed route key

* Implementing better navbar mapping system, added text highlighting for sidebar

* Use mui theme rather than hard coding color

* Remove debugging stuff

* Simplify duplicate code
  • Loading branch information
mckeenicholas authored Oct 29, 2023
1 parent dea9964 commit 32de521
Showing 1 changed file with 102 additions and 18 deletions.
120 changes: 102 additions & 18 deletions app/src/components/Base.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
import { useEffect } from "react";
import { useEffect, useState } from "react";
import i18n from "i18next";
import { useTranslation } from "react-i18next";
import {
Box,
Paper,
BottomNavigation,
BottomNavigationAction,
List,
ListItemIcon,
ListItemButton,
ListItemText,
IconButton,
Drawer,
useMediaQuery,
Theme,
useTheme,
} from "@mui/material";
import { Home, Info, CorporateFare, QuestionAnswer } 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";

const ROUTES = ["home", "about", "organization", "faq"] as const;
const ROUTE_NAMES = ["home", "about", "organization", "faq"] as const;

const ICONS = {
home: Home,
Expand All @@ -20,19 +35,35 @@ 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<typeof getLocaleOrFallback>}/${Path}`;

type NavigationBarItem = {
routeName: RouteName;
Icon: NavigationIcon;
path: Path;
pathWithLocale: PathWithLocale;
};

export const Base = () => {
const { t } = useTranslation();
const { pathname } = useLocation();
const pathWithoutLocale = pathname.split("/").at(-1);
const params = useParams();
const locale = getLocaleOrFallback(params.locale as string);
const theme = useTheme();
const isSmall = useMediaQuery<Theme>((theme) => theme.breakpoints.down("sm"));

const [isDrawerOpen, setIsDrawerOpen] = useState(false);

useEffect(() => {
localStorage.setItem(SAVED_LOCALE, locale);
Expand All @@ -43,7 +74,64 @@ export const Base = () => {
window.scrollTo(0, 0);
}, [pathWithoutLocale]);

return (
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 ? (
<Box minHeight="90vh" flex={1} display="flex" flexDirection="column">
<Paper sx={{ position: "sticky", top: 0, zIndex: 1100 }} elevation={2}>
<IconButton onClick={() => setIsDrawerOpen(true)}>
<Menu sx={{ fontSize: 40, color: "black" }} />
</IconButton>
</Paper>
<Drawer
open={isDrawerOpen}
anchor="left"
onClose={() => setIsDrawerOpen(false)}
>
<List>
{navigationBarItems.map(
({ routeName, Icon, path, pathWithLocale }) => {
const color =
pathWithoutLocale === path
? theme.palette.primary.main
: undefined;

return (
<ListItemButton
key={routeName}
component={Link}
to={pathWithLocale}
onClick={() => setIsDrawerOpen(false)}
>
<ListItemIcon sx={{ color }}>
<Icon />
</ListItemIcon>
<ListItemText
primary={t(`routes.${routeName}`)}
sx={{ color }}
/>
</ListItemButton>
);
},
)}
</List>
</Drawer>
<Box display="flex" flex={1}>
<Outlet />
</Box>
</Box>
) : (
<Box minHeight="100vh" flex={1} display="flex" flexDirection="column">
<Box display="flex" flex={1}>
<Outlet />
Expand All @@ -53,22 +141,18 @@ export const Base = () => {
elevation={2}
>
<BottomNavigation showLabels value={pathWithoutLocale}>
{ROUTES.map((r) => {
const Icon = ICONS[r];
const route = ROUTE_NAME_TO_ROUTE[r];
const routeWithLocale = `${locale}/${route}`;

return (
{navigationBarItems.map(
({ routeName, Icon, path, pathWithLocale }) => (
<BottomNavigationAction
key={r}
label={t(`routes.${r}`)}
icon={<Icon />}
to={routeWithLocale}
value={route}
key={routeName}
label={t(`routes.${routeName}`)}
component={Link}
to={pathWithLocale}
icon={<Icon />}
value={path}
/>
);
})}
),
)}
</BottomNavigation>
</Paper>
</Box>
Expand Down

0 comments on commit 32de521

Please sign in to comment.