From 55a13c5f42c2c01bf18d384debcff7e4e4c67c14 Mon Sep 17 00:00:00 2001 From: Van Buren Date: Wed, 17 Sep 2025 16:07:35 -0400 Subject: [PATCH 1/3] fix: use dom --- client/package.json | 2 +- client/pnpm-lock.yaml | 18 +++++++++++++++++- client/src/components/base/MainNavigation.tsx | 2 +- client/src/pages/ErrorPage.tsx | 9 +++++++++ client/src/pages/HomePage.tsx | 5 +++++ client/src/pages/LoginPage.tsx | 2 +- client/src/pages/Router.tsx | 19 +++++++++++++++---- client/src/pages/layouts/AuthorizedLayout.tsx | 2 +- .../src/pages/layouts/InitializedLayout.tsx | 2 +- 9 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 client/src/pages/ErrorPage.tsx diff --git a/client/package.json b/client/package.json index d967e56..07be697 100644 --- a/client/package.json +++ b/client/package.json @@ -18,7 +18,7 @@ "dayjs": "^1.11.18", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-router": "^7.9.1" + "react-router-dom": "^7.9.1" }, "devDependencies": { "@types/node": "^24.5.1", diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index c0ab146..75b9bcf 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -43,7 +43,7 @@ importers: react-dom: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) - react-router: + react-router-dom: specifier: ^7.9.1 version: 7.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: @@ -2573,6 +2573,16 @@ packages: integrity: sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==, } + react-router-dom@7.9.1: + resolution: + { + integrity: sha512-U9WBQssBE9B1vmRjo9qTM7YRzfZ3lUxESIZnsf4VjR/lXYz9MHjvOxHzr/aUm4efpktbVOrF09rL/y4VHa8RMw==, + } + engines: { node: '>=20.0.0' } + peerDependencies: + react: '>=18' + react-dom: '>=18' + react-router@7.9.1: resolution: { @@ -4768,6 +4778,12 @@ snapshots: react-is@19.1.1: {} + react-router-dom@7.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router: 7.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-router@7.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: cookie: 1.0.2 diff --git a/client/src/components/base/MainNavigation.tsx b/client/src/components/base/MainNavigation.tsx index 515e4da..b17f6d8 100644 --- a/client/src/components/base/MainNavigation.tsx +++ b/client/src/components/base/MainNavigation.tsx @@ -7,7 +7,7 @@ import { useTheme, } from '@mui/material'; import { SemossBlueLogo } from '@/assets'; -import { useNavigate } from 'react-router'; +import { useNavigate } from 'react-router-dom'; import { AccountCircle } from '@mui/icons-material'; import { useInsight } from '@semoss/sdk-react'; import { useState } from 'react'; diff --git a/client/src/pages/ErrorPage.tsx b/client/src/pages/ErrorPage.tsx new file mode 100644 index 0000000..ccb87a1 --- /dev/null +++ b/client/src/pages/ErrorPage.tsx @@ -0,0 +1,9 @@ +/** + * Renders a warning message for any FE errors encountered. + * + * @component + */ +export const ErrorPage = () => { + console.log('ErrorPage rendered due to an error'); + return
Error: Page not found
; +}; diff --git a/client/src/pages/HomePage.tsx b/client/src/pages/HomePage.tsx index d9301cc..bae7e67 100644 --- a/client/src/pages/HomePage.tsx +++ b/client/src/pages/HomePage.tsx @@ -1,5 +1,6 @@ import { useLoadingPixel } from '@/hooks'; import { Stack, Typography } from '@mui/material'; +import { useState } from 'react'; /** * Renders the home page. @@ -9,6 +10,8 @@ import { Stack, Typography } from '@mui/material'; export const HomePage = () => { const [data, isLoading] = useLoadingPixel('HelloUser()'); + const [test, setTest] = useState<{ b: string }>({ b: 'test' }); + return ( Home page @@ -31,6 +34,8 @@ export const HomePage = () => { + {test.b} + ); }; diff --git a/client/src/pages/LoginPage.tsx b/client/src/pages/LoginPage.tsx index 53ebe11..b5b918d 100644 --- a/client/src/pages/LoginPage.tsx +++ b/client/src/pages/LoginPage.tsx @@ -3,7 +3,7 @@ import { useLoadingState } from '@/hooks'; import { Button, Stack, TextField } from '@mui/material'; import { useInsight } from '@semoss/sdk-react'; import { ChangeEvent, useRef, useState } from 'react'; -import { Navigate, useLocation } from 'react-router'; +import { Navigate, useLocation } from 'react-router-dom'; /** * Renders a the login page if the user is not already logged in, otherwise sends them to the home page. diff --git a/client/src/pages/Router.tsx b/client/src/pages/Router.tsx index b2e5b5a..32ee3cf 100644 --- a/client/src/pages/Router.tsx +++ b/client/src/pages/Router.tsx @@ -1,8 +1,9 @@ -import { HashRouter, Navigate, Route, Routes } from 'react-router'; +import { HashRouter, Navigate, Route, Routes } from 'react-router-dom'; import { ROUTE_PATH_LOGIN_PAGE } from './routes.constants'; import { AuthorizedLayout, InitializedLayout } from './layouts'; import { HomePage } from './HomePage'; import { LoginPage } from './LoginPage'; +import { ErrorPage } from './ErrorPage'; /** * Renders pages based on url. @@ -15,11 +16,21 @@ export const Router = () => { {/* Wrap every route in InitializedLayout to ensure SEMOSS is ready to handle requests */} - }> + } + errorElement={} + > {/* Wrap pages that should only be available to logged in users */} - }> + } + errorElement={} + > {/* If the path is empty, use the home page */} - } /> + } + errorElement={} + /> {/* The login page should be available to non-logged in users (duh) */} diff --git a/client/src/pages/layouts/AuthorizedLayout.tsx b/client/src/pages/layouts/AuthorizedLayout.tsx index 28c61a5..53e8cc7 100644 --- a/client/src/pages/layouts/AuthorizedLayout.tsx +++ b/client/src/pages/layouts/AuthorizedLayout.tsx @@ -1,5 +1,5 @@ import { useInsight } from '@semoss/sdk-react'; -import { Navigate, Outlet, useLocation } from 'react-router'; +import { Navigate, Outlet, useLocation } from 'react-router-dom'; import { ROUTE_PATH_LOGIN_PAGE } from '../routes.constants'; import { useAppContext } from '@/contexts'; import { LoadingScreen } from '@/components'; diff --git a/client/src/pages/layouts/InitializedLayout.tsx b/client/src/pages/layouts/InitializedLayout.tsx index aa875fe..ac809c0 100644 --- a/client/src/pages/layouts/InitializedLayout.tsx +++ b/client/src/pages/layouts/InitializedLayout.tsx @@ -1,7 +1,7 @@ import { LoadingScreen, MainNavigation } from '@/components'; import { Stack } from '@mui/material'; import { useInsight } from '@semoss/sdk-react'; -import { Outlet } from 'react-router'; +import { Outlet } from 'react-router-dom'; /** * Renders a loading wheel if SEMOSS is not initialized. From 30aeb180b8117ec7d8258a41ff49dd21df195d03 Mon Sep 17 00:00:00 2001 From: Van Buren Date: Wed, 17 Sep 2025 16:28:21 -0400 Subject: [PATCH 2/3] feat: error boundary --- client/src/pages/HomePage.tsx | 8 ++-- client/src/pages/Router.tsx | 76 +++++++++++++++++++---------------- 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/client/src/pages/HomePage.tsx b/client/src/pages/HomePage.tsx index bae7e67..d7adf3e 100644 --- a/client/src/pages/HomePage.tsx +++ b/client/src/pages/HomePage.tsx @@ -1,6 +1,5 @@ import { useLoadingPixel } from '@/hooks'; import { Stack, Typography } from '@mui/material'; -import { useState } from 'react'; /** * Renders the home page. @@ -8,10 +7,11 @@ import { useState } from 'react'; * @component */ export const HomePage = () => { + /** + * State + */ const [data, isLoading] = useLoadingPixel('HelloUser()'); - const [test, setTest] = useState<{ b: string }>({ b: 'test' }); - return ( Home page @@ -34,8 +34,6 @@ export const HomePage = () => { - {test.b} - ); }; diff --git a/client/src/pages/Router.tsx b/client/src/pages/Router.tsx index 32ee3cf..4b140d3 100644 --- a/client/src/pages/Router.tsx +++ b/client/src/pages/Router.tsx @@ -1,48 +1,54 @@ -import { HashRouter, Navigate, Route, Routes } from 'react-router-dom'; +import { createHashRouter, Navigate, RouterProvider } from 'react-router-dom'; import { ROUTE_PATH_LOGIN_PAGE } from './routes.constants'; import { AuthorizedLayout, InitializedLayout } from './layouts'; import { HomePage } from './HomePage'; import { LoginPage } from './LoginPage'; import { ErrorPage } from './ErrorPage'; +const router = createHashRouter([ + { + // Wrap every route in InitializedLayout to ensure SEMOSS is ready to handle requests + Component: InitializedLayout, + // Catch errors in any of the initialized pages, to prevent the whole app from crashing + ErrorBoundary: ErrorPage, + children: [ + { + // Wrap pages that should only be available to logged in users + Component: AuthorizedLayout, + // Also catch errors in any of the authorized pages, allowing the navigation to continue working + ErrorBoundary: ErrorPage, + children: [ + { + // If the path is empty, use the home page + index: true, + Component: HomePage, + }, + // { + // // Example of a new page + // path: '/new-page', + // Component: NewPage, + // } + ], + }, + { + // The login page should be available to non-logged in users (duh) + path: ROUTE_PATH_LOGIN_PAGE, + Component: LoginPage, + }, + { + // Any other urls should be sent to the home page + path: '*', + Component: () => , + }, + ], + }, +]); + /** * Renders pages based on url. * * @component */ export const Router = () => { - return ( - // Semoss projects typically use HashRouters - - - {/* Wrap every route in InitializedLayout to ensure SEMOSS is ready to handle requests */} - } - errorElement={} - > - {/* Wrap pages that should only be available to logged in users */} - } - errorElement={} - > - {/* If the path is empty, use the home page */} - } - errorElement={} - /> - - - {/* The login page should be available to non-logged in users (duh) */} - } - /> - - {/* Any other urls should be sent to the home page */} - } /> - - - - ); + return ; }; From d1a780df0fe643b4449bfa882a1605e4a7e41d7f Mon Sep 17 00:00:00 2001 From: Van Buren Date: Wed, 17 Sep 2025 16:41:16 -0400 Subject: [PATCH 3/3] feat: enhance error --- client/src/pages/ErrorPage.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/client/src/pages/ErrorPage.tsx b/client/src/pages/ErrorPage.tsx index ccb87a1..6f12dff 100644 --- a/client/src/pages/ErrorPage.tsx +++ b/client/src/pages/ErrorPage.tsx @@ -1,9 +1,24 @@ +import { ErrorOutline } from '@mui/icons-material'; +import { Stack, Typography } from '@mui/material'; + /** * Renders a warning message for any FE errors encountered. * * @component */ export const ErrorPage = () => { - console.log('ErrorPage rendered due to an error'); - return
Error: Page not found
; + return ( + + + + An error has occurred. Please try again or contact support if + the problem persists. + + + ); };