From afbf588b5e2c84bf0f5fc4da6bb409c5e56ffcfd Mon Sep 17 00:00:00 2001
From: "Embruch, Gerd" <gerd.embruch@uni-hamburg.de>
Date: Tue, 2 Jul 2024 10:42:33 +0200
Subject: [PATCH] added private routes

---
 README.md                       |  5 ++---
 README_tmp.html                 |  3 +--
 src/contexts/Auth/AuthState.jsx |  1 +
 src/routes/PrivateRoute.jsx     | 26 ++++++++++++++++++++++++++
 src/routes/WrapRoutes.jsx       |  6 ++++--
 5 files changed, 34 insertions(+), 7 deletions(-)
 create mode 100755 src/routes/PrivateRoute.jsx

diff --git a/README.md b/README.md
index d310fc7..33d5cc0 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,5 @@ cp ./.env.template.local ./.env.production.local
 - [PM2](https://pm2.keymetrics.io/)
 
 # Roadmap
-- [ ] create private routes
-- [ ] fix errors
-- [ ] complete pages incl. password request and RAGChat
\ No newline at end of file
+- [ ] complete pages incl. password request and RAGChat
+- [ ] fix errors
\ No newline at end of file
diff --git a/README_tmp.html b/README_tmp.html
index 203124e..b3a3df1 100644
--- a/README_tmp.html
+++ b/README_tmp.html
@@ -389,9 +389,8 @@ cp ./.env.template.local ./.env.production.local
 </ul>
 <h1 id="roadmap">Roadmap</h1>
 <ul>
-<li><input type="checkbox" id="checkbox0"><label for="checkbox0">create private routes</label></li>
+<li><input type="checkbox" id="checkbox0"><label for="checkbox0">complete pages incl. password request and RAGChat</label></li>
 <li><input type="checkbox" id="checkbox1"><label for="checkbox1">fix errors</label></li>
-<li><input type="checkbox" id="checkbox2"><label for="checkbox2">complete pages incl. password request and RAGChat</label></li>
 </ul>
 
 </body>
diff --git a/src/contexts/Auth/AuthState.jsx b/src/contexts/Auth/AuthState.jsx
index 05d213c..c4bd1d7 100755
--- a/src/contexts/Auth/AuthState.jsx
+++ b/src/contexts/Auth/AuthState.jsx
@@ -55,6 +55,7 @@ function AuthState({ children }) {
       value={{
         login,
         logout,
+        currentUser,
         USER_ACTIONS,
         dispatchCurrentUser
       }}>
diff --git a/src/routes/PrivateRoute.jsx b/src/routes/PrivateRoute.jsx
new file mode 100755
index 0000000..863247d
--- /dev/null
+++ b/src/routes/PrivateRoute.jsx
@@ -0,0 +1,26 @@
+import React from 'react';
+import { Navigate, useLocation } from 'react-router-dom';
+import { useAuth } from '../contexts/Auth/AuthState';
+
+function PrivateRoute({ children }) {
+  // #################################
+  // HOOKS
+  // #################################
+  // ### MAKE USE OF location
+  const location = useLocation();
+
+  // #################################
+  // FUNCTIONS
+  // #################################
+  // ### IMPORT CurrentUser FUNCTION FROM AuthContext
+  const { currentUser } = useAuth();
+
+  // #################################
+  // OUTPUT
+  // #################################
+  // if user is logged in, load children
+  // otherwise load login page, but remember originally requested page in location state.redirectTo
+  return currentUser ? children : <Navigate to='/login' replace state={{ redirectTo: location }} />;
+}
+
+export default PrivateRoute;
\ No newline at end of file
diff --git a/src/routes/WrapRoutes.jsx b/src/routes/WrapRoutes.jsx
index 5c9c8fc..562bd6b 100644
--- a/src/routes/WrapRoutes.jsx
+++ b/src/routes/WrapRoutes.jsx
@@ -1,4 +1,5 @@
 import { lazy, Suspense } from 'react';
+import PrivateRoute from './PrivateRoute';
 
 /**
  * Lazily load the mentioned component which resides in the page directory
@@ -8,15 +9,16 @@ import { lazy, Suspense } from 'react';
 export function loadComponent(componentPath, lazyLoad, privateRoute) {
 
   lazyLoad = typeof lazyLoad !== "undefined" ? lazyLoad : true;
+  privateRoute = typeof privateRoute !== "undefined" ? privateRoute : false;
 
   // It is not possible to use a fully dynamic import statement, such as import(foo). Because foo could potentially be any path to any file in your system or project.
   // The import() must contain at least some information about where the module is located.
 
   const Component = lazyLoad ? lazy(() => import(/* @vite-ignore */`../pages/${componentPath}`)) : import(/* @vite-ignore */`../pages/${componentPath}`);
 
+  let element = privateRoute ? <PrivateRoute><Component /></PrivateRoute> : <Component />;
 
-
-  let element = lazyLoad ? <Suspense fallback={<span>Loading...</span>}><Component /></Suspense> : <Component />;
+  element = lazyLoad ? <Suspense fallback={<span>Loading...</span>}>{element}</Suspense> : element;
 
   // Wrapping around the suspense component is mandatory
   return element;
-- 
GitLab