Skip to content

Commit

Permalink
Merge pull request #16 from MuNuChapterHKN/feature/frontend-structure…
Browse files Browse the repository at this point in the history
…-and-login

Refactored frontend following best practices:
- code cleanup and typos fixed
- url-based rendering instead of logic-based
- Auth0 now tries to automatically login when viewing "protected" pages, and redirects accordingly
- added basic navigation between pages (doesn't break authentication session)
- added temporary debug page to be used to debug APIs
- added basic responsive layout
  • Loading branch information
AlbertoBaroso committed Apr 15, 2024
2 parents 9d4119a + e9a781c commit 8cdd032
Show file tree
Hide file tree
Showing 31 changed files with 585 additions and 574 deletions.
104 changes: 36 additions & 68 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -1,71 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png" />
<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png" />
<link
rel="apple-touch-icon"
sizes="114x114"
href="/apple-icon-114x114.png"
/>
<link
rel="apple-touch-icon"
sizes="120x120"
href="/apple-icon-120x120.png"
/>
<link
rel="apple-touch-icon"
sizes="144x144"
href="/apple-icon-144x144.png"
/>
<link
rel="apple-touch-icon"
sizes="152x152"
href="/apple-icon-152x152.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-icon-180x180.png"
/>
<link
rel="icon"
type="image/png"
sizes="192x192"
href="/android-icon-192x192.png"
/>
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/manifest.json" />
<meta name="msapplication-TileColor" content="#ffffff" />
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png" />
<meta name="theme-color" content="#ffffff" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="HKRecruitment" content="HKN polito recruitment platform" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>HKRecruitment</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
<head>
<meta charset="utf-8" />
<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png" />
<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png" />
<link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png" />
<link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png" />
<link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png" />
<link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png" />
<link rel="icon" type="image/png" sizes="192x192" href="/android-icon-192x192.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />

<meta name="msapplication-TileColor" content="#ffffff" />
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png" />

<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="HKN Polito Recruitment Platform" />
<meta name="author" content="IT Area @ HKN Polito" />

<link rel="manifest" href="/manifest.json" />

<title>HKRecruitment</title>
</head>

<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.jsx"></script>
</body>

</html>
2 changes: 2 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"@auth0/auth0-react": "^1.12.0",
"@hkrecruitment/shared": "workspace:*",
"@popperjs/core": "^2.11.6",
"@types/react": "^18.2.75",
"bootstrap": "^5.2.3",
"bootstrap-icons": "^1.11.3",
"moment": "^2.29.3",
"moment-timezone": "^0.5.34",
"prop-types": "^15.7.0",
Expand Down
74 changes: 74 additions & 0 deletions frontend/public/hkn_logo_white_vector.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/notfound404.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 23 additions & 71 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
@@ -1,82 +1,34 @@
.App {
text-align: center;
/* Generic styling */
:root {
--hkblue: #061e33;
--hkwhite: #ffffff;
}

.App-logo {
height: 40vmin;
pointer-events: none;
body {
background-color: var(--hkblue);
color: var(--hkwhite);
}

@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
a {
color: var(--hkwhite);
}

.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: black;
}
.active {
background: green !important;
color: white !important;
}

.App-link {
color: #61dafb;
}

.black {
color: white;
background-color: #282c34;
background: #282c34;
}

.pink {
color: black;
background-color: pink;
background: pink;
}

.submitButton {
background-color: #00629b !important;
background: #00629b !important;
}
.myNavbar {
background-color: #f9f9f9;
}
.table {
--bs-table-bg: rgba(55, 81, 113, 0.8) !important ;
--bs-table-accent-bg: transparent;
--bs-table-striped-color: white !important;
--bs-table-striped-bg: rgba(55, 81, 113, 0.8) !important ;
--bs-table-active-color: white !important;
--bs-table-active-bg: rgba(0, 0, 0, 0.1);
--bs-table-hover-color: white !important ;
--bs-table-hover-bg: rgba(0, 0, 0, 0.075);
width: 100%;
margin-bottom: 1rem;
color: white important!;
vertical-align: top;
border-color: #dee2e6;
/* Profile dropdown on HKNavbar */
#profile-nav-dropdown .dropdown-menu {
position: absolute;
right: 0;
left: auto;
padding: 0.5rem 1rem;
margin-top: 0.5rem;
background-color: rgba(6, 30, 51, 0.7);
backdrop-filter: blur(4px);
border: 1px solid white;
}

.table > thead {
vertical-align: bottom;
background-color: rgba(55, 81, 113, 1);
#profile-nav-dropdown .dropdown-menu .dropdown-item-text {
color: var(--hkwhite);
}

@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
#profile-nav-dropdown .dropdown-menu .dropdown-divider {
border-top: 1px solid white;
}
106 changes: 46 additions & 60 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,56 @@
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css";
import React, { useEffect, useState } from "react";
import MyNavbar from "./MyNavbar";
import SignupForm from "./SignupForm";
import { Route } from "react-router-dom";
import { Navigate } from "react-router-dom";
import { Routes } from "react-router-dom";
import React from "react";
import { Route, Routes } from "react-router-dom";
import { useAuth0 } from "@auth0/auth0-react";
import AvaiabilitiesTable from "./AvaiabilitiesTable";

function App() {
function parseJwt(token) {
return JSON.parse(Buffer.from(token.split(".")[1], "base64").toString());
}
import Alert from "react-bootstrap/Alert";

const {
isLoading,
isAuthenticated,
error,
user,
loginWithRedirect,
logout,
getAccessTokenSilently,
} = useAuth0();
import HKNavbar from "./components/HKNavbar";
import PageLayout from "./components/PageLayout";
import LoadingSpinner from "./components/LoadingSpinner";
import AuthGuard from "./components/AuthGuard";

const [accessToken, setAccessToken] = useState("");
import HomePage from "./pages/HomePage";
import ApplyPage from "./pages/ApplyPage";
import AvailabilitiesPage from "./pages/AvailabilitiesPage";
import DebugPage from "./pages/DebugPage";
import NotFoundPage from "./pages/NotFoundPage";

useEffect(() => {
if (isAuthenticated) {
getAccessTokenSilently({
audience: import.meta.env.VITE_AUTH0_AUDIENCE,
grant_type: "client_credentials",
}).then((token) => {
setAccessToken(parseJwt(token));
});
}
}, [isAuthenticated]);
import "./App.css";

return (
<Routes>
<Route
path="/"
element={
<AfterLogin
isAuthenticated={isAuthenticated}
user={user}
token={accessToken}
/>
}
/>
<Route path="/*" element={<Navigate to="/" />} />
</Routes>
);
}
export default App;
function App() {
const { isLoading } = useAuth0();

function AfterLogin(props) {
return (
<div>
{" "}
<MyNavbar />
{props.isAuthenticated &&
!props.user.email.endsWith("@hknpolito.org") && <SignupForm />}
{props.isAuthenticated && props.user.email.endsWith("@hknpolito.org") && (
<AvaiabilitiesTable token={props.accessToken} />
)}
</div>
<>
<HKNavbar />
<PageLayout>
<Alert variant="warning">
<strong>Note:</strong> all of this is work-in-progress, stuff{" "}
<u>will</u> change!
</Alert>
{isLoading ? (
<LoadingSpinner />
) : (
<Routes>
<Route path="/" element={<HomePage />} />
<Route
path="/apply"
element={<AuthGuard component={ApplyPage} />}
/>
<Route
path="/availabilities"
element={<AuthGuard component={AvailabilitiesPage} />}
/>
<Route
path="/debug"
element={<AuthGuard component={DebugPage} />}
/>
<Route path="*" element={<NotFoundPage />} />
</Routes>
)}
</PageLayout>
</>
);
}

export default App;
32 changes: 32 additions & 0 deletions frontend/src/Auth0ProviderWithNavigate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Auth0Provider } from "@auth0/auth0-react";
import React from "react";
import { useNavigate } from "react-router-dom";

export const Auth0ProviderWithNavigate = ({ children }): JSX.Element | null => {
const navigate = useNavigate();

const domain = import.meta.env.VITE_AUTH0_DOMAIN;
const clientId = import.meta.env.VITE_AUTH0_CLIENTID;
const audience = import.meta.env.VITE_AUTH0_AUDIENCE;
const redirectUri = window.location.origin;

const onRedirectCallback = (appState) => {
navigate(appState?.returnTo || window.location.pathname);
};

if (!(domain && clientId && redirectUri)) {
return null;
}

return (
<Auth0Provider
domain={domain}
clientId={clientId}
audience={audience}
redirectUri={redirectUri}
onRedirectCallback={onRedirectCallback}
>
{children}
</Auth0Provider>
);
};
22 changes: 0 additions & 22 deletions frontend/src/LoginButton.tsx

This file was deleted.

Loading

0 comments on commit 8cdd032

Please sign in to comment.