From 7478daa3376fd1ed611703db590c3938ed2bfe54 Mon Sep 17 00:00:00 2001
From: "Embruch, Gerd" <gerd.embruch@uni-hamburg.de>
Date: Mon, 1 Jul 2024 12:55:21 +0200
Subject: [PATCH] created a flexible router, enabled breadcrumbs

---
 src/assets/css/tailwind.presets.min.css       |  2 +-
 src/assets/css/tailwind.presets.min.css.map   |  2 +-
 src/assets/sass/tailwind.presets.scss         | 14 +++++++
 src/layouts/MainLayout.jsx                    |  8 +++-
 .../partials/subheader/Breadcrumbs.jsx        | 41 +++++++++++++++++++
 src/layouts/partials/subheader/Subheader.jsx  | 27 ++++++++++++
 src/pages/Onboarding/Onboarding.jsx           | 20 +++++++++
 src/routes/Sitemap.jsx                        | 36 +++++++++++-----
 src/routes/WrapRoutes.jsx                     | 23 +++++++++++
 9 files changed, 159 insertions(+), 14 deletions(-)
 create mode 100644 src/layouts/partials/subheader/Breadcrumbs.jsx
 create mode 100644 src/layouts/partials/subheader/Subheader.jsx
 create mode 100644 src/pages/Onboarding/Onboarding.jsx
 create mode 100644 src/routes/WrapRoutes.jsx

diff --git a/src/assets/css/tailwind.presets.min.css b/src/assets/css/tailwind.presets.min.css
index fce319f..130dc89 100644
--- a/src/assets/css/tailwind.presets.min.css
+++ b/src/assets/css/tailwind.presets.min.css
@@ -1 +1 @@
-@tailwind base;@tailwind components;@tailwind utilities/*# sourceMappingURL=tailwind.presets.min.css.map */
\ No newline at end of file
+@tailwind base;@tailwind components;@tailwind utilities;@layer base{img,svg,video,canvas,audio,iframe,embed,object{display:inline;vertical-align:middle}}/*# sourceMappingURL=tailwind.presets.min.css.map */
\ No newline at end of file
diff --git a/src/assets/css/tailwind.presets.min.css.map b/src/assets/css/tailwind.presets.min.css.map
index 8c4ad4f..21d66c4 100644
--- a/src/assets/css/tailwind.presets.min.css.map
+++ b/src/assets/css/tailwind.presets.min.css.map
@@ -1 +1 @@
-{"version":3,"sources":["../sass/tailwind.presets.scss"],"names":[],"mappings":"AAAA,cAAA,CACA,oBAAA,CACA","file":"tailwind.presets.min.css"}
\ No newline at end of file
+{"version":3,"sources":["../sass/tailwind.presets.scss"],"names":[],"mappings":"AAAA,cAAA,CACA,oBAAA,CACA,mBAAA,CAEA,YACE,+CAQE,cAAA,CACA,qBAAA,CAAA","file":"tailwind.presets.min.css"}
\ No newline at end of file
diff --git a/src/assets/sass/tailwind.presets.scss b/src/assets/sass/tailwind.presets.scss
index b5c61c9..d184c0b 100644
--- a/src/assets/sass/tailwind.presets.scss
+++ b/src/assets/sass/tailwind.presets.scss
@@ -1,3 +1,17 @@
 @tailwind base;
 @tailwind components;
 @tailwind utilities;
+
+@layer base {
+  img,
+  svg,
+  video,
+  canvas,
+  audio,
+  iframe,
+  embed,
+  object {
+    display: inline;
+    vertical-align: middle;
+  }
+}
diff --git a/src/layouts/MainLayout.jsx b/src/layouts/MainLayout.jsx
index b8f161e..7a3abba 100644
--- a/src/layouts/MainLayout.jsx
+++ b/src/layouts/MainLayout.jsx
@@ -1,6 +1,8 @@
 import React from 'react';
 import { Outlet } from 'react-router-dom';
 import Header from './partials/Header';
+import Subheader from './partials/subheader/Subheader';
+
 
 function MainLayout() {
   // #################################
@@ -17,7 +19,11 @@ function MainLayout() {
   return (
     <>
       <Header />
-      <Outlet />
+      <Subheader />
+      <main role="main" className="relative row-start-2 col-span-full flex sm:justify-center overflow-y-auto sm:row-start-4">
+        <Outlet />
+      </main>
+      <div>Navbar</div>
     </>
   );
 }
diff --git a/src/layouts/partials/subheader/Breadcrumbs.jsx b/src/layouts/partials/subheader/Breadcrumbs.jsx
new file mode 100644
index 0000000..48a0dad
--- /dev/null
+++ b/src/layouts/partials/subheader/Breadcrumbs.jsx
@@ -0,0 +1,41 @@
+import React from 'react';
+import { RiArrowDropRightLine, RiHome2Line } from 'react-icons/ri';
+import { useMatches } from 'react-router-dom';
+
+function Breadcrumbs() {
+  // #################################
+  // HOOKS
+  // #################################
+  let matches = useMatches();
+
+  // #################################
+  // FUNCTIONS
+  // #################################
+  let crumbs = matches
+    // get rid of any matches that don't have handle and crumb
+    .filter((match) => Boolean(match.handle?.crumb));
+
+  // #################################
+  // OUTPUT
+  // #################################
+  return (
+
+    <div className="h-0 overflow-hidden sm:h-6 px-4 my-2 container sm:flex justify-between">
+      <ul className="flex">
+        {
+          // map crumbs into an array of elements, passing the loader data to each one
+          // TODO: find out how to render result of .map, then move into functions-section and render ${crumbs} in here
+          crumbs.map((match, idx) =>
+            <li key={`bc-${idx}`}>
+              {/* show home icon on first item, others will display split img */}
+              {idx === 0 ? <RiHome2Line className='text-xl mr-1' /> : <RiArrowDropRightLine className='text-2xl mx-4' />}
+              {/* render handle.crumb callback */}
+              {match.handle.crumb(match.data)}
+            </li>)
+        }
+      </ul>
+    </div>
+  );
+}
+
+export default React.memo(Breadcrumbs);;
\ No newline at end of file
diff --git a/src/layouts/partials/subheader/Subheader.jsx b/src/layouts/partials/subheader/Subheader.jsx
new file mode 100644
index 0000000..2c4f020
--- /dev/null
+++ b/src/layouts/partials/subheader/Subheader.jsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import Breadcrumbs from './Breadcrumbs';
+
+function Subheader() {
+  // #################################
+  // HOOKS
+  // #################################
+
+
+  // #################################
+  // FUNCTIONS
+  // #################################
+
+
+  // #################################
+  // OUTPUT
+  // #################################
+  return (
+    <div className='group flex justify-center  box-border shadow-md z-20  h-0 open:h-10 sm:h-10 transform transition-all overflow-hidden row-start-2 sm:row-start-3 col-span-full text-sm bg-UhhWhite'>
+      <div className="container flex justify-center flex-wrap">
+        <Breadcrumbs />
+      </div>
+    </div>
+  );
+}
+
+export default React.memo(Subheader);
\ No newline at end of file
diff --git a/src/pages/Onboarding/Onboarding.jsx b/src/pages/Onboarding/Onboarding.jsx
new file mode 100644
index 0000000..d9dd414
--- /dev/null
+++ b/src/pages/Onboarding/Onboarding.jsx
@@ -0,0 +1,20 @@
+import React from 'react';
+
+function Onboarding() {
+  // #################################
+  // HOOKS
+  // #################################
+
+  // #################################
+  // FUNCTIONS
+  // #################################
+
+  // #################################
+  // OUTPUT
+  // #################################
+  return (
+    <div>TEST Onboarding</div>
+  );
+}
+
+export default React.memo(Onboarding);
\ No newline at end of file
diff --git a/src/routes/Sitemap.jsx b/src/routes/Sitemap.jsx
index 205ac30..3d0fe9a 100644
--- a/src/routes/Sitemap.jsx
+++ b/src/routes/Sitemap.jsx
@@ -1,13 +1,27 @@
 import MainLayout from "../layouts/MainLayout";
-import Home from "../pages/Home";
+import { loadComponent } from "./WrapRoutes";
+import { Link } from 'react-router-dom';
 
-export const sitemap = [
-  {
-    title: 'MenuBar', element: <MainLayout />,
-    children: [
-      {
-        title: 'Home', path: '/', element: <Home />
-      }
-    ]
-  }
-];
\ No newline at end of file
+export const sitemap = [{
+  title: 'MenuBar', element: <MainLayout />,
+  children: [
+    {
+      title: 'Home',
+      path: '/',
+      handle: { crumb: () => <Link to="/">ZBH Portal</Link> },
+      children: [
+        {
+          index: true,
+          element: loadComponent('Home', true, true)
+        },
+        // ONBOARDING
+        {
+          title: 'Onboarding',
+          path: '/onboarding',
+          element: loadComponent('Onboarding/Onboarding', true, true),
+          handle: { crumb: () => <Link to="/onboarding">Onboarding</Link> }
+        }
+      ]
+    }
+  ]
+}];
\ No newline at end of file
diff --git a/src/routes/WrapRoutes.jsx b/src/routes/WrapRoutes.jsx
new file mode 100644
index 0000000..5c9c8fc
--- /dev/null
+++ b/src/routes/WrapRoutes.jsx
@@ -0,0 +1,23 @@
+import { lazy, Suspense } from 'react';
+
+/**
+ * Lazily load the mentioned component which resides in the page directory
+ * This method will be used in routes so that the files are loaded only
+ * When users are on that route
+ */
+export function loadComponent(componentPath, lazyLoad, privateRoute) {
+
+  lazyLoad = typeof lazyLoad !== "undefined" ? lazyLoad : true;
+
+  // 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 = lazyLoad ? <Suspense fallback={<span>Loading...</span>}><Component /></Suspense> : <Component />;
+
+  // Wrapping around the suspense component is mandatory
+  return element;
+}
\ No newline at end of file
-- 
GitLab