diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index accc93b..6deaaa1 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -23,6 +23,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet-async": "^1.3.0",
+ "react-router-dom": "^6.14.2",
"react-scripts": "^5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4",
@@ -3743,6 +3744,14 @@
"url": "https://opencollective.com/popperjs"
}
},
+ "node_modules/@remix-run/router": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.7.2.tgz",
+ "integrity": "sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@rollup/plugin-babel": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@@ -15342,6 +15351,36 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-router": {
+ "version": "6.14.2",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.14.2.tgz",
+ "integrity": "sha512-09Zss2dE2z+T1D03IheqAFtK4UzQyX8nFPWx6jkwdYzGLXd5ie06A6ezS2fO6zJfEb/SpG6UocN2O1hfD+2urQ==",
+ "dependencies": {
+ "@remix-run/router": "1.7.2"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.14.2",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.14.2.tgz",
+ "integrity": "sha512-5pWX0jdKR48XFZBuJqHosX3AAHjRAzygouMTyimnBPOLdY3WjzUSKhus2FVMihUFWzeLebDgr4r8UeQFAct7Bg==",
+ "dependencies": {
+ "@remix-run/router": "1.7.2",
+ "react-router": "6.14.2"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
"node_modules/react-scripts": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 640e87a..ebb2717 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -18,6 +18,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet-async": "^1.3.0",
+ "react-router-dom": "^6.14.2",
"react-scripts": "^5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4",
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index df77705..b4555a2 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -19,6 +19,9 @@ import { Helmet, HelmetProvider } from "react-helmet-async";
// Authentication Context: Check if user is logged in or not
import { AuthContextProvider } from "./AuthContext";
+// React router
+import Router from "./Router";
+
function App() {
return (
@@ -27,7 +30,9 @@ function App() {
Todo
-
+
+
+
diff --git a/frontend/src/Router.tsx b/frontend/src/Router.tsx
new file mode 100644
index 0000000..76746c4
--- /dev/null
+++ b/frontend/src/Router.tsx
@@ -0,0 +1,9 @@
+import { BrowserRouter, Routes } from "react-router-dom";
+
+const Router = () => {
+
+ {}
+ ;
+};
+
+export default Router;
diff --git a/frontend/src/components/RequireAuth.tsx b/frontend/src/components/RequireAuth.tsx
new file mode 100644
index 0000000..3648393
--- /dev/null
+++ b/frontend/src/components/RequireAuth.tsx
@@ -0,0 +1,22 @@
+import { useContext } from "react";
+import { Navigate, useLocation } from "react-router-dom";
+import { AuthContext } from "src/AuthContext";
+
+interface IProps {
+ children: React.ReactNode;
+}
+
+const RequireAuth = ({ children }: IProps) => {
+ const { authenticated } = useContext(AuthContext);
+
+ const location = useLocation();
+
+ if (authenticated) {
+ return <>{children}>;
+ } else {
+ // re-route user back to login page if not logged in
+ return ;
+ }
+};
+
+export default RequireAuth;
diff --git a/frontend/src/components/ScrollToTop.tsx b/frontend/src/components/ScrollToTop.tsx
new file mode 100644
index 0000000..47a604b
--- /dev/null
+++ b/frontend/src/components/ScrollToTop.tsx
@@ -0,0 +1,16 @@
+import { useEffect } from "react";
+import { useLocation } from "react-router";
+
+const ScrollToTop = () => {
+ const { pathname } = useLocation();
+
+ // pathname changes => scroll to top
+ // scrolling only on navigation
+ useEffect(() => {
+ window.scrollTo(0, 0);
+ }, [pathname]);
+
+ return null;
+};
+
+export default ScrollToTop;
diff --git a/frontend/src/setupTests.ts b/frontend/src/setupTests.ts
index 1dd407a..350a8fd 100644
--- a/frontend/src/setupTests.ts
+++ b/frontend/src/setupTests.ts
@@ -3,3 +3,7 @@
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom";
+
+window.scrollTo = (x, y) => {
+ document.documentElement.scrollTop = y;
+};