Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
fix home/header login button (#228)
Browse files Browse the repository at this point in the history
fix home/header login button #227 #241
  • Loading branch information
warreprovoost authored Apr 26, 2024
1 parent afe3893 commit 40db0ad
Show file tree
Hide file tree
Showing 15 changed files with 309 additions and 186 deletions.
15 changes: 15 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5.15.15",
"@mui/material": "^5.15.15",
"@mui/lab": "^5.0.0-alpha.170",
"@mui/material": "^5.15.15",
"@mui/styled-engine-sc": "^6.0.0-alpha.16",
"@mui/x-data-grid": "^7.1.1",
"@mui/x-date-pickers": "^7.1.1",
Expand All @@ -27,6 +27,7 @@
"i18next-browser-languagedetector": "^7.2.0",
"i18next-http-backend": "^2.5.0",
"jszip": "^3.10.1",
"prettier": "^3.2.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^14.1.0",
Expand All @@ -37,10 +38,10 @@
},
"devDependencies": {
"@types/downloadjs": "^1.4.6",
"@types/history": "^4.7.11",
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19",
"@types/react-router-dom": "^5.3.3",
"@types/history": "^4.7.11",
"@types/scheduler": "^0.23.0",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
Expand Down
3 changes: 2 additions & 1 deletion frontend/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"home": "Home",
"tag": "en",
"homepage": "Homepage",
"projectUploadForm": "Project upload form"
"projectUploadForm": "Project upload form",
"logout": "Logout"
},
"home": {
"home": "Home",
Expand Down
3 changes: 2 additions & 1 deletion frontend/public/locales/nl/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"home": "Home",
"tag": "nl",
"homepage": "Homepage",
"projectUploadForm": "Project uploaden"
"projectUploadForm": "Project uploaden",
"logout": "Afmelden"
},
"home": {
"home": "Home",
Expand Down
44 changes: 32 additions & 12 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,61 @@
import { Route, RouterProvider, createBrowserRouter, createRoutesFromElements } from "react-router-dom";
import {
Route,
RouterProvider,
createBrowserRouter,
createRoutesFromElements,
} from "react-router-dom";
import Layout from "./components/Header/Layout";
import { AllCoursesTeacher } from "./components/Courses/AllCoursesTeacher";
import { CourseDetailTeacher } from "./components/Courses/CourseDetailTeacher";
import { dataLoaderCourseDetail, dataLoaderCourses } from "./components/Courses/CourseUtils";
import {
dataLoaderCourseDetail,
dataLoaderCourses,
} from "./components/Courses/CourseUtils";
import LanguagePath from "./components/LanguagePath";
import ProjectView from "./pages/project/projectView/ProjectView";
import { ErrorBoundary } from "./pages/error/ErrorBoundary.tsx";
import ProjectCreateHome from "./pages/create_project/ProjectCreateHome.tsx";
import SubmissionsOverview from "./pages/submission_overview/SubmissionsOverview.tsx";
import {fetchProjectPage} from "./pages/project/FetchProjects.tsx";
import { fetchProjectPage } from "./utils/fetches/FetchProjects.tsx";
import HomePages from "./pages/home/HomePages.tsx";
import ProjectOverView from "./pages/project/projectOverview.tsx";
import { synchronizeJoinCode } from "./loaders/join-code.ts";
import { fetchMe } from "./utils/fetches/FetchMe.ts";

const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<Layout />} errorElement={<ErrorBoundary />}>
<Route index element={<HomePages />} loader={fetchProjectPage}/>
<Route path=":lang" element={<LanguagePath/>}>
<Route
path="/"
element={<Layout />}
errorElement={<ErrorBoundary />}
loader={fetchMe}
>
<Route index element={<HomePages />} loader={fetchProjectPage} />
<Route path=":lang" element={<LanguagePath />}>
<Route path="home" element={<HomePages />} loader={fetchProjectPage} />
<Route path="project/:projectId/overview" element={<SubmissionsOverview/>}/>
<Route
path="project/:projectId/overview"
element={<SubmissionsOverview />}
/>
<Route path="project">
<Route path=":projectId" element={<ProjectView />}>
</Route>
<Route path=":projectId" element={<ProjectView />}></Route>
</Route>
<Route path="courses">
<Route index element={<AllCoursesTeacher />} loader={dataLoaderCourses}/>
<Route path="join" loader={synchronizeJoinCode} />
<Route path=":courseId" element={<CourseDetailTeacher />} loader={dataLoaderCourseDetail} />
</Route>
<Route path="projects">
<Route index element={<ProjectOverView/>} loader={fetchProjectPage}/>
<Route
index
element={<ProjectOverView />}
loader={fetchProjectPage}
/>
<Route path="create" element={<ProjectCreateHome />} />
</Route>
</Route>
</Route>
)
</Route>,
),
);

/**
Expand Down
15 changes: 0 additions & 15 deletions frontend/src/Layout.tsx

This file was deleted.

138 changes: 101 additions & 37 deletions frontend/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,28 @@ import {
Drawer,
Grid,
ListItemButton,
ListItemText
ListItemText,
} from "@mui/material";
import { useTranslation } from "react-i18next";
import MenuIcon from "@mui/icons-material/Menu";
import { useTranslation } from 'react-i18next';
import { useEffect, useState } from "react";
import React, { useState } from "react";
import LanguageIcon from "@mui/icons-material/Language";
import AccountCircleIcon from "@mui/icons-material/AccountCircle";
import { Link } from "react-router-dom";
import { TitlePortal } from "./TitlePortal";
import {LoginButton} from "./Login";
import { Me } from "../../types/me.ts";
import {LoginButton} from "./Login.tsx";

interface HeaderProps {
me: Me;
}
/**
* The header component for the application that will be rendered at the top of the page.
* @returns - The header component
*/
export function Header(): JSX.Element {
const { t, i18n } = useTranslation('translation', { keyPrefix: 'header' });
export function Header({ me }: HeaderProps): JSX.Element {
const API_URL = import.meta.env.VITE_APP_API_HOST;
const { t, i18n } = useTranslation("translation", { keyPrefix: "header" });
const [languageMenuAnchor, setLanguageMenuAnchor] =
useState<null | HTMLElement>(null);

Expand All @@ -44,32 +50,72 @@ export function Header(): JSX.Element {

const [open, setOpen] = useState(false);
const [listItems, setListItems] = useState([
{ link: "/", text: t("homepage") }
{ link: "/", text: t("homepage") },
]);

useEffect(() => {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLButtonElement>(
null,
);

const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};

React.useEffect(() => {
const baseItems = [{ link: "/", text: t("homepage") }];
const additionalItems = [
{ link: "/projects", text: t("myProjects") },
{ link: "/courses", text: t("myCourses") }
{ link: "/courses", text: t("myCourses") },
];
if (isLoggedIn()) {
if (me.loggedIn) {
setListItems([...baseItems, ...additionalItems]);
}
else {
} else {
setListItems(baseItems);
}
}, [t]);
}, [me, t]);

return (
<Box sx={{ flexGrow: 1 }}>
<AppBar position="sticky">
<Toolbar disableGutters>
<IconButton edge="start" onClick={() => setOpen(!open)} sx={{ color: "white", marginLeft: 0 }}>
<MenuIcon style={{fontSize:"2rem"}} />
<IconButton
edge="start"
onClick={() => setOpen(!open)}
sx={{ color: "white", marginLeft: 0 }}
>
<MenuIcon style={{ fontSize: "2rem" }} />
</IconButton>
<TitlePortal/>
<LoginButton></LoginButton>
<TitlePortal />
{!me.loggedIn && (
<LoginButton/>
)}
{me.loggedIn && (
<>
<IconButton
edge="end"
onClick={handleClick}
sx={{ color: "inherit", marginRight: "0.3rem" }}
>
<AccountCircleIcon />
<Typography variant="body1" sx={{ paddingLeft: "0.3rem" }}>
{me.display_name}
</Typography>
</IconButton>
<Menu
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={() => setAnchorEl(null)}
>
<Typography sx={{ padding: "6px 16px", color: "black" }}>
{me.display_name}
</Typography>
<MenuItem>
<Link to={`${API_URL}/logout`} style={{ color: 'inherit', textDecoration: 'none' }}>
{t("logout")}</Link>
</MenuItem>
</Menu>
</>
)}
<div>
<IconButton onClick={handleLanguageMenu} color="inherit">
<LanguageIcon />
Expand All @@ -92,16 +138,14 @@ export function Header(): JSX.Element {
</div>
</Toolbar>
</AppBar>
<DrawerMenu open={open} onClose={() => setOpen(false)} listItems={listItems}/>
<DrawerMenu
open={open}
onClose={() => setOpen(false)}
listItems={listItems}
/>
</Box>
);
}
/**
* @returns Whether a user is logged in or not.
*/
function isLoggedIn() {
return true;
}

/**
* Renders the drawer menu component.
Expand All @@ -110,26 +154,46 @@ function isLoggedIn() {
* @param listItems - Array of objects representing the list items in the drawer menu.
* @returns The Side Bar
*/
function DrawerMenu({ open, onClose, listItems }: { open: boolean, onClose: () => void, listItems: { link: string, text: string }[] }) {

function DrawerMenu({
open,
onClose,
listItems,
}: {
open: boolean;
onClose: () => void;
listItems: { link: string; text: string }[];
}) {
return (
<Drawer open={open} anchor="left" onClose={onClose}>
<Grid container direction="column" sx={{
width: 250,
height: "100%",
backgroundColor: "primary.main"
}}>
<Grid
container
direction="column"
sx={{
width: 250,
height: "100%",
backgroundColor: "primary.main",
}}
>
<Grid item container direction="row" alignItems="flex-start">
<IconButton onClick={onClose} sx={{
color: "white"
}}>
<MenuIcon style={{fontSize:"2rem"}} />
<IconButton
onClick={onClose}
sx={{
color: "white",
}}
>
<MenuIcon style={{ fontSize: "2rem" }} />
</IconButton>
</Grid>
<List>
{listItems.map((listItem, index) => (
<ListItemButton key={index} component={Link} to={listItem.link} role="listitem" onClick={onClose}>
<ListItemText primary={listItem.text} sx={{color:"white"}} />
<ListItemButton
key={index}
component={Link}
to={listItem.link}
role="listitem"
onClick={onClose}
>
<ListItemText primary={listItem.text} sx={{ color: "white" }} />
</ListItemButton>
))}
</List>
Expand Down
9 changes: 6 additions & 3 deletions frontend/src/components/Header/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { Outlet } from "react-router-dom";
import { Outlet, useLoaderData } from "react-router-dom";
import { Header } from "./Header.tsx";
import { Me } from "../../types/me.ts";

/**
* Basic layout component that will be used on all routes.
* @returns The Layout component
*/
export default function Layout(): JSX.Element {
const meData: Me = useLoaderData() as Me;

return (
<>
<Header />
<Header me={meData} />
<Outlet />
</>
);
}
}
Loading

0 comments on commit 40db0ad

Please sign in to comment.