From 888689383c0028005ec7a31ef3cac5a8904edb79 Mon Sep 17 00:00:00 2001 From: Cedric Mekeirle <143823820+JibrilExe@users.noreply.github.com> Date: Tue, 2 Apr 2024 13:22:55 +0200 Subject: [PATCH] navbar (#80) * navbar * changes * oops * close bar on redirect * linter conflicts for component function * scalability matters * useEffect to check login state and adjust link item list * a little more readable --- frontend/.eslintrc.cjs | 6 +- frontend/index.html | 2 +- frontend/package-lock.json | 3 + frontend/package.json | 3 + frontend/src/App.tsx | 8 +- frontend/src/components/Header/Header.tsx | 110 ++++++++++++++++++---- 6 files changed, 106 insertions(+), 26 deletions(-) diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs index c685b20b..0229c600 100644 --- a/frontend/.eslintrc.cjs +++ b/frontend/.eslintrc.cjs @@ -26,7 +26,7 @@ module.exports = { "jsdoc/check-access": 1, "tsdoc/syntax": "warn", "jsdoc/check-alignment": 1, - "jsdoc/check-param-names": 1, + "jsdoc/check-param-names": 0, "jsdoc/check-property-names": 1, "jsdoc/check-tag-names": 1, "jsdoc/check-types": 1, @@ -37,10 +37,10 @@ module.exports = { "jsdoc/no-multi-asterisks": 1, "jsdoc/no-undefined-types": 1, "jsdoc/require-jsdoc": 1, - "jsdoc/require-param": 1, + "jsdoc/require-param": 0, "jsdoc/require-param-description": 1, "jsdoc/require-param-name": 1, - "jsdoc/require-param-type": 1, + "jsdoc/require-param-type": 0, "jsdoc/require-property": 1, "jsdoc/require-property-description": 1, "jsdoc/require-property-name": 1, diff --git a/frontend/index.html b/frontend/index.html index d42d4487..43fdb5e7 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,5 +1,5 @@ - + diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 8467e285..c9f36c33 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -13,8 +13,11 @@ "@mui/icons-material": "^5.15.10", "@mui/material": "^5.15.10", "@mui/styled-engine-sc": "^6.0.0-alpha.16", + "i18next-browser-languagedetector": "^7.2.0", + "i18next-http-backend": "^2.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-i18next": "^14.1.0", "react-router-dom": "^6.22.1", "styled-components": "^6.1.8" }, diff --git a/frontend/package.json b/frontend/package.json index dfb8c6fa..c53f82b9 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,8 +17,11 @@ "@mui/icons-material": "^5.15.10", "@mui/material": "^5.15.10", "@mui/styled-engine-sc": "^6.0.0-alpha.16", + "i18next-browser-languagedetector": "^7.2.0", + "i18next-http-backend": "^2.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-i18next": "^14.1.0", "react-router-dom": "^6.22.1", "styled-components": "^6.1.8" }, diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 22932a0e..307c2751 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,7 +1,6 @@ -import { BrowserRouter, Route, Routes } from "react-router-dom"; -import Home from "./pages/home/Home"; +import { BrowserRouter,Route,Routes } from "react-router-dom"; import { Header } from "./components/Header/Header"; - +import Home from "./pages/home/Home"; /** * This component is the main application component that will be rendered by the ReactDOM. * @returns - The main application component @@ -16,5 +15,4 @@ function App(): JSX.Element { ); } - -export default App; +export default App; \ No newline at end of file diff --git a/frontend/src/components/Header/Header.tsx b/frontend/src/components/Header/Header.tsx index 8595e6d4..53846db5 100644 --- a/frontend/src/components/Header/Header.tsx +++ b/frontend/src/components/Header/Header.tsx @@ -1,33 +1,109 @@ -import { - AppBar, - Box, - Button, - IconButton, - Toolbar, - Typography, -} from "@mui/material"; -import MenuIcon from "@mui/icons-material/Menu"; -import { useTranslation } from "react-i18next"; +import { AppBar, Box, Button, Drawer, Grid, IconButton, List, ListItemButton, ListItemText, Toolbar, Typography } from "@mui/material"; +import { Menu } from "@mui/icons-material"; +import { useTranslation } from 'react-i18next'; +import { Link, useLocation } from 'react-router-dom'; +import { useEffect, useState } from "react"; /** - * The header component for the application that will be rendered at the top of the page. - * @returns - The header component + * Renders the header component. + * @returns JSX.Element representing the header. */ export function Header(): JSX.Element { const { t } = useTranslation(); + const location = useLocation(); + const [open, setOpen] = useState(false); + const [listItems, setListItems] = useState([ + { link: "/", text: t("homepage") } + ]); + + useEffect(() => { + const baseItems = [{ link: "/", text: t("homepage") }]; + const additionalItems = [ + { link: "/projects", text: t("myProjects") }, + { link: "/courses", text: t("myCourses") } + ]; + if (isLoggedIn()) { + setListItems([...baseItems, ...additionalItems]); + } + else { + setListItems(baseItems); + } + }, [t]); + + const title = getTitle(location.pathname, t); + return ( - - - + + setOpen(!open)} sx={{ color: "white", marginLeft: 0 }}> + - {t('home')} + {title} - + + + setOpen(false)} listItems={listItems}/> ); } +/** + * @returns Whether a user is logged in or not. + */ +function isLoggedIn() { + return true; +} + +/** + * Get the title based on the given pathname. + * @param pathname - The current pathname. + * @param t - The translation function. + * @returns The title. + */ +function getTitle(pathname: string, t: (key: string) => string): string { + switch(pathname) { + case '/': return t('home'); + case '/login': return t('login'); + case '/courses': return t('myCourses'); + case '/projects': return t('myProjects'); + default: return t('home'); + } +} + +/** + * Renders the drawer menu component. + * @param open - Whether the drawer menu is open or not. + * @param onClose - Function to handle the close event of the drawer menu. + * @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 }[] }) { + + return ( + + + + + + + + + {listItems.map((listItem, index) => ( + + + + ))} + + + + ); +}