From c3fac169c80b61c70b53f5496a3e2404841213c6 Mon Sep 17 00:00:00 2001 From: "Embruch, Gerd" <gerd.embruch@uni-hamburg.de> Date: Mon, 1 Jul 2024 13:56:13 +0200 Subject: [PATCH] added clean layout, helmet & 404-page --- .env | 2 ++ package-lock.json | 36 +++++++++++++++++++++++++++++++ package.json | 1 + src/App.jsx | 6 +++++- src/layouts/CleanLayout.jsx | 43 +++++++++++++++++++++++++++++++++++++ src/pages/Err404.jsx | 33 ++++++++++++++++++++++++++++ src/routes/Sitemap.jsx | 7 ++++++ 7 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 .env create mode 100644 src/layouts/CleanLayout.jsx create mode 100644 src/pages/Err404.jsx diff --git a/.env b/.env new file mode 100644 index 0000000..f92bf9c --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +VITE_APP_NAME=ZBH Portal +VITE_PAGE_AFTER_LOGIN=/ diff --git a/package-lock.json b/package-lock.json index 60347a3..b901065 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "hamburger-react": "^2.5.1", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-helmet-async": "^2.0.5", "react-icons": "^5.2.1", "react-router-dom": "^6.24.0" }, @@ -3550,6 +3551,15 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/is-array-buffer": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", @@ -4935,6 +4945,26 @@ "react": "^18.3.1" } }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-helmet-async": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.5.tgz", + "integrity": "sha512-rYUYHeus+i27MvFE+Jaa4WsyBKGkL6qVgbJvSBoX8mbsWoABJXdEO0bZyi0F6i+4f0NuIb8AvqPMj3iXFHkMwg==", + "license": "Apache-2.0", + "dependencies": { + "invariant": "^2.2.4", + "react-fast-compare": "^3.2.2", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-icons": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", @@ -5281,6 +5311,12 @@ "node": ">= 0.4" } }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index 4dd3acf..723c6e7 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "hamburger-react": "^2.5.1", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-helmet-async": "^2.0.5", "react-icons": "^5.2.1", "react-router-dom": "^6.24.0" }, diff --git a/src/App.jsx b/src/App.jsx index e5f4371..2075f13 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,12 +1,16 @@ import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import { sitemap } from "./routes/Sitemap"; +import { HelmetProvider } from 'react-helmet-async'; function App() { let pages = createBrowserRouter(sitemap); return ( - <RouterProvider router={pages} /> + <HelmetProvider> + <RouterProvider router={pages} /> + </HelmetProvider> + ); } diff --git a/src/layouts/CleanLayout.jsx b/src/layouts/CleanLayout.jsx new file mode 100644 index 0000000..ab0e1ee --- /dev/null +++ b/src/layouts/CleanLayout.jsx @@ -0,0 +1,43 @@ +import React, { useEffect } from 'react'; +import { Outlet } from 'react-router-dom'; +import Header from './partials/Header'; + +function CleanLayout() { + // ################################# + // HOOKS + // ################################# + // SET BODY CLASSES + useEffect(() => { + // ### on run exec this code + document.body.className = ''; + document.body.classList.add('overflow-x-hidden', 'h-full', 'flex', 'justify-center', 'relative'); + + document.getElementById('root').classList.remove('grid-rows-[auto_1fr_auto]', 'min-h-full', 'w-screen', 'max-h-full', 'sm:grid-rows-[auto_auto_auto_1fr]'); + document.getElementById('root').classList.add('grid-rows-[auto_1fr]', 'h-full'); + }, []); + + // ################################# + // FUNCTIONS + // ################################# + + // ################################# + // OUTPUT + // ################################# + return ( + <> + <div className="grid grid-cols-1 grid-rows-[auto_1fr] h-full min-w-xs text-UhhGrey"> + <Header layout="clean" /> + <main role="main"> + <div className="box-border overflow-x-hidden overflow-y-auto px-4 mt-2 "> + <div> + <Outlet /> + </div> + </div> + </main> + </div> + + </> + ); +} + +export default React.memo(CleanLayout); \ No newline at end of file diff --git a/src/pages/Err404.jsx b/src/pages/Err404.jsx new file mode 100644 index 0000000..c718859 --- /dev/null +++ b/src/pages/Err404.jsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { Helmet } from 'react-helmet-async'; +import { useNavigate } from "react-router-dom"; + +function Err404() { + // ################################# + // HOOKS + // ################################# + const redirect = useNavigate(); + // ################################# + // FUNCTIONS + // ################################# + function handleClick(event) { + event.preventDefault(); + redirect(-1); + } + + // ################################# + // OUTPUT + // ################################# + return ( + <> + {/* render page title */} + <Helmet><title>[{import.meta.env.VITE_APP_NAME}] Error</title></Helmet> + <h1 className="text-8xl text-center text-UhhGrey">404</h1> + <h2>Page not found</h2> + <p className="mt-8">We're sorry for the inconvenience, but we can lead you</p> + <span className="inline-block w-full h-16 px-8 mb-4 border-box leading-[4rem] text-center align-middle bg-UhhBlue text-UhhWhite font-UhhBC cursor-pointer" onClick={handleClick}>back</span> + </> + ); +} + +export default React.memo(Err404); diff --git a/src/routes/Sitemap.jsx b/src/routes/Sitemap.jsx index 3d0fe9a..0635aed 100644 --- a/src/routes/Sitemap.jsx +++ b/src/routes/Sitemap.jsx @@ -1,6 +1,8 @@ import MainLayout from "../layouts/MainLayout"; import { loadComponent } from "./WrapRoutes"; import { Link } from 'react-router-dom'; +import CleanLayout from '../layouts/CleanLayout'; + export const sitemap = [{ title: 'MenuBar', element: <MainLayout />, @@ -24,4 +26,9 @@ export const sitemap = [{ ] } ] +}, { + title: 'Others', element: <CleanLayout />, children: [ + // ERROR + { path: '*', element: loadComponent('Err404') } + ] }]; \ No newline at end of file -- GitLab