Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up breadcrumb nav #27

Merged
merged 11 commits into from
Aug 13, 2024
113 changes: 0 additions & 113 deletions submit-web/src/components/Shared/SideNavBar.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from "react";
import { Box, Breadcrumbs, Typography } from "@mui/material";
import { Link, useRouterState } from "@tanstack/react-router";
import { theme } from "@/styles/theme";

interface RouteSegment {
title: string;
path: string;
}

const filterUniqueRoutes = (breadcrumbs: RouteSegment[]) => {
const seenPaths = new Set();
return breadcrumbs.filter((segment) => {
const isUnique = !seenPaths.has(segment.path);

Check warning on line 14 in submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx#L12-L14

Added lines #L12 - L14 were not covered by tests
if (isUnique) {
seenPaths.add(segment.path);

Check warning on line 16 in submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx#L16

Added line #L16 was not covered by tests
}
return isUnique;

Check warning on line 18 in submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx#L18

Added line #L18 was not covered by tests
});
};

const BreadcrumbNav: React.FC = () => {
const router = useRouterState();
const breadcrumbs = router.matches.map((match) => {
const { meta, pathname } = match;

Check warning on line 25 in submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx#L23-L25

Added lines #L23 - L25 were not covered by tests
if (meta)
return {

Check warning on line 27 in submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx#L27

Added line #L27 was not covered by tests
title: meta[0].title,
path: pathname,
};
});

const uniqueBreadcrumbs = filterUniqueRoutes(breadcrumbs as RouteSegment[]);
const isRoot = uniqueBreadcrumbs.length === 1;

Check warning on line 34 in submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx#L33-L34

Added lines #L33 - L34 were not covered by tests

return (
<>
{!isRoot && (
<Box
sx={{
p: 1,
paddingLeft: 5,
borderBottom: "1px solid #0000001A",
}}
>
<Breadcrumbs aria-label="breadcrumb">
{uniqueBreadcrumbs.map(
(segment: { title: string; path: string }, index: number) => {
const { title, path } = segment;
const isLast = index === uniqueBreadcrumbs.length - 1;

Check warning on line 50 in submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/BreadcrumbNav.tsx#L48-L50

Added lines #L48 - L50 were not covered by tests
return isLast ? (
<Typography key={path} color="text.primary">
{title}
</Typography>
) : (
<Link
key={path}
style={{ color: theme.palette.primary.dark }}
to={path}
>
{title}
</Link>
);
}
)}
</Breadcrumbs>
</Box>
)}
</>
);
};

export default BreadcrumbNav;
131 changes: 131 additions & 0 deletions submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { useState } from "react";
import {
Box,
List,
ListItem,
ListItemButton,
ListItemText,
} from "@mui/material";
import { Link } from "@tanstack/react-router";
import { theme } from "@/styles/theme";
import { useAuth } from "react-oidc-context";
import { AuthenticatedRoutes, Routes } from "./SideNavElements";
import { alpha } from "@mui/system";
import { useIsMobile } from "@/hooks/common";

export default function SideNavBar() {
const { isAuthenticated } = useAuth();
const [currentPath, setCurrentPath] = useState(window.location.pathname);
const isMobile = useIsMobile();

Check warning on line 19 in submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx#L16-L19

Added lines #L16 - L19 were not covered by tests

let routeMenuItems = Routes;

Check warning on line 21 in submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx#L21

Added line #L21 was not covered by tests

if (isAuthenticated) {
routeMenuItems = routeMenuItems.concat(AuthenticatedRoutes);

Check warning on line 24 in submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx#L24

Added line #L24 was not covered by tests
}

return (
<div>
{!isMobile && (
<Box
sx={{
overflow: "auto",
borderRight: "1px solid #0000001A",
width: 240,
height: "calc(100vh - 88px)",
zIndex: 0,
position: "static",
}}
>
<List>
{routeMenuItems.map((route) => (
<>
<ListItem key={route.name}>
<Link
to={route.path}
onClick={() => setCurrentPath(route.path)}

Check warning on line 46 in submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx#L46

Added line #L46 was not covered by tests
style={{
color: theme.palette.primary.light,
fontWeight: "bold",
textDecoration: "none",
width: "100%",
}}
>
<ListItemButton
sx={{
pl: "2rem",
backgroundColor:
currentPath === route.path
? alpha(theme.palette.secondary.main, 0.1)
: theme.palette.primary.light,

Check warning on line 60 in submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx#L59-L60

Added lines #L59 - L60 were not covered by tests
borderLeft: `4px solid ${theme.palette.primary.main}`,
}}
>
<span
style={{
color: alpha(theme.palette.primary.main, 0.8),
}}
>
{route.name}
</span>
</ListItemButton>
</Link>
</ListItem>
{route.routes && route.routes?.length > 0 && (
<List disablePadding key={`list-${route.name}`}>
{route.routes?.map((subRoute) => (
<ListItem
key={`sub-list-${subRoute?.name}`}
sx={{ margin: 0, padding: 0 }}
>
<Link
to={subRoute.path}
onClick={() => setCurrentPath(subRoute.path)}

Check warning on line 83 in submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx#L83

Added line #L83 was not covered by tests
style={{
textDecoration: "none",
margin: 0,
padding: 0,
color: "inherit",
}}
activeProps={{
style: {
color: theme.palette.primary.main,
fontWeight:
currentPath === subRoute.path
? "bold"
: "normal",

Check warning on line 96 in submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx#L95-L96

Added lines #L95 - L96 were not covered by tests
width: "100%",
},
}}
>
<ListItemButton
key={`sub-list-button-${subRoute?.name}`}
sx={{
marginLeft: "40px",
borderLeft:
currentPath === subRoute.path
? `4px solid ${theme.palette.primary.main}`
: `1px solid ${theme.palette.divider}`,

Check warning on line 108 in submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/components/Shared/layout/SideNav/SideNavBar.tsx#L107-L108

Added lines #L107 - L108 were not covered by tests
}}
>
<ListItemText
key={`sub-list-text-${subRoute?.name}`}
>
<span style={{ color: "inherit" }}>
{subRoute.name}
</span>
</ListItemText>
</ListItemButton>
</Link>
</ListItem>
))}
</List>
)}
</>
))}
</List>
</Box>
)}
</div>
);
}
8 changes: 8 additions & 0 deletions submit-web/src/hooks/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useMediaQuery, useTheme } from "@mui/material";

export const useIsMobile = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));

return isMobile;
};
16 changes: 14 additions & 2 deletions submit-web/src/routes/__root.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import EAOAppBar from "@/components/Shared/EAOAppBar";
import Footer from "@/components/Shared/layout/Footer";
import PageNotFound from "@/components/Shared/PageNotFound";
import SideNavBar from "@/components/Shared/layout/SideNav/SideNavBar";
import { Box } from "@mui/system";
import { createRootRouteWithContext, Outlet } from "@tanstack/react-router";
import { TanStackRouterDevtools } from "@tanstack/router-devtools";
import { AuthContextProps } from "react-oidc-context";
import { AuthContextProps, useAuth } from "react-oidc-context";
import { useIsMobile } from "@/hooks/common";
import BreadcrumbNav from "@/components/Shared/layout/SideNav/BreadcrumbNav";

type RouterContext = {
authentication: AuthContextProps;
Expand All @@ -13,15 +16,24 @@ type RouterContext = {
export const Route = createRootRouteWithContext<RouterContext>()({
component: Layout,
notFoundComponent: PageNotFound,
meta: () => [{ title: "Home" }],
});

function Layout() {
const { isAuthenticated } = useAuth();
const isMobile = useIsMobile();
return (
<>
<EAOAppBar />
{isAuthenticated && <BreadcrumbNav />}
<Box
height={"calc(100vh - 88px)"}
width={
isMobile ? "100%" : `calc(100vw - ${isAuthenticated ? 240 : 0}px)`
}
flexDirection={isAuthenticated ? "column" : "row"}
display={"flex"}
>
{isAuthenticated && <SideNavBar />}
<Outlet />
</Box>
<Footer />
Expand Down
1 change: 1 addition & 0 deletions submit-web/src/routes/_authenticated/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

export const Route = createFileRoute("/_authenticated/profile")({
component: Profile,
meta: () => [{ title: "Profile" }],

Check warning on line 14 in submit-web/src/routes/_authenticated/profile.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/routes/_authenticated/profile.tsx#L14

Added line #L14 was not covered by tests
});

function Profile() {
Expand Down
1 change: 1 addition & 0 deletions submit-web/src/routes/_authenticated/projects/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

export const Route = createFileRoute("/_authenticated/projects/")({
component: ProjectsPage,
meta: () => [{ title: "Projects" }],

Check warning on line 5 in submit-web/src/routes/_authenticated/projects/index.tsx

View check run for this annotation

Codecov / codecov/patch

submit-web/src/routes/_authenticated/projects/index.tsx#L5

Added line #L5 was not covered by tests
});

function ProjectsPage() {
Expand Down
Loading
Loading