diff --git a/resources/scripts/components/NavigationBarProvider.tsx b/resources/scripts/components/NavigationBarProvider.tsx new file mode 100644 index 00000000..1c23c0d1 --- /dev/null +++ b/resources/scripts/components/NavigationBarProvider.tsx @@ -0,0 +1,28 @@ +import { NavigationBarContext, RouteDefinition } from '@/components/elements/navigation/NavigationBar' +import { ReactNode, useState } from 'react' + +interface Props { + children?: ReactNode +} + +const NavigationBarProvider = ({ children }: Props) => { + const [routes, setRoutes] = useState([]) + const [breadcrumb, setBreadcrumb] = useState() + + const value = { + routes, + setRoutes, + breadcrumb, + setBreadcrumb, + } + + return ( + + {children} + + ) +} + +export default NavigationBarProvider diff --git a/resources/scripts/components/admin/servers/overview/ServerOverviewContainer.tsx b/resources/scripts/components/admin/servers/overview/ServerOverviewContainer.tsx index b1475576..4f64d9b9 100644 --- a/resources/scripts/components/admin/servers/overview/ServerOverviewContainer.tsx +++ b/resources/scripts/components/admin/servers/overview/ServerOverviewContainer.tsx @@ -9,7 +9,7 @@ const ServerOverviewContainer = () => { return ( - diff --git a/resources/scripts/components/elements/navigation/NavigationBar.tsx b/resources/scripts/components/elements/navigation/NavigationBar.tsx index e9c12566..c5b58461 100644 --- a/resources/scripts/components/elements/navigation/NavigationBar.tsx +++ b/resources/scripts/components/elements/navigation/NavigationBar.tsx @@ -3,23 +3,34 @@ import ContentContainer from '@/components/elements/ContentContainer' import Logo from '@/assets/images/logo.svg' import { Burger, LoadingOverlay } from '@mantine/core' import UserDropdown from '@/components/elements/navigation/UserDropdown' -import { useEffect, useMemo, useRef, useState } from 'react' +import { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react' import NavigationDropdown from '@/components/elements/navigation/NavigationDropdown' import { Link, useMatch } from 'react-router-dom' import http from '@/api/http' import NavLink from '@/components/elements/navigation/NavLink' +import { AdminBanner } from '@/routers/AdminDashboardRouter' -interface RouteDefinition { +export interface RouteDefinition { name: string path: string } -interface Props { +interface NavigationBarContextInterface { routes: RouteDefinition[] - breadcrumb?: string + setRoutes: (routes: RouteDefinition[]) => void + breadcrumb?: string | null + setBreadcrumb: (breadcrumb: string | null | undefined) => void } -const NavigationBar = ({ routes, breadcrumb }: Props) => { +export const NavigationBarContext = createContext({ + routes: [], + setRoutes: () => {}, + breadcrumb: null, + setBreadcrumb: () => {}, +}) + +const NavigationBar = () => { + const {routes, breadcrumb} = useContext(NavigationBarContext) const [isVisible, setIsVisible] = useState(true) const [menuVisible, setMenuVisible] = useState(false) const [isLoggingOut, setIsLoggingOut] = useState(false) @@ -78,6 +89,7 @@ const NavigationBar = ({ routes, breadcrumb }: Props) => { return (
+ {isAdminArea && }
@@ -98,8 +110,12 @@ const NavigationBar = ({ routes, breadcrumb }: Props) => { )}
- - setMenuVisible(!menuVisible)} /> + + setMenuVisible(!menuVisible)} + />
diff --git a/resources/scripts/components/servers/overview/ServerAdminBlock.tsx b/resources/scripts/components/servers/overview/ServerAdminBlock.tsx index c71fb137..bb4d6db9 100644 --- a/resources/scripts/components/servers/overview/ServerAdminBlock.tsx +++ b/resources/scripts/components/servers/overview/ServerAdminBlock.tsx @@ -15,7 +15,7 @@ const ServerAdminBlock = () => {

- diff --git a/resources/scripts/routers/admin/AdminDashboardRouter.tsx b/resources/scripts/routers/AdminDashboardRouter.tsx similarity index 64% rename from resources/scripts/routers/admin/AdminDashboardRouter.tsx rename to resources/scripts/routers/AdminDashboardRouter.tsx index 59d7c9f2..74bf3b4e 100644 --- a/resources/scripts/routers/admin/AdminDashboardRouter.tsx +++ b/resources/scripts/routers/AdminDashboardRouter.tsx @@ -1,12 +1,7 @@ import ContentContainer from '@/components/elements/ContentContainer' -import NavigationBar from '@/components/elements/navigation/NavigationBar' -import Spinner from '@/components/elements/Spinner' -import TransitionRouter from '@/routers/TransitionRouter' -import { lazy, Suspense } from 'react' -import { Link, Outlet, Route, Routes } from 'react-router-dom' -import routes from '@/routers/router' -import { NotFound } from '@/components/elements/ScreenBlock' -import { NodeContext } from '@/state/admin/node' +import { NavigationBarContext } from '@/components/elements/navigation/NavigationBar' +import { useContext, useEffect } from 'react' +import { Link, Outlet, Route, Routes, useMatches } from 'react-router-dom' const navRoutes = [ { @@ -46,11 +41,17 @@ export const AdminBanner = () => ( ) const AdminDashboardRouter = () => { + const { setRoutes } = useContext(NavigationBarContext) + const matches = useMatches() + + useEffect(() => { + if (matches[1]?.pathname === '/admin') { + setRoutes(navRoutes) + } + }, [matches]) + return ( <> - - - ) diff --git a/resources/scripts/routers/admin/NodeRouter.tsx b/resources/scripts/routers/AdminNodeRouter.tsx similarity index 77% rename from resources/scripts/routers/admin/NodeRouter.tsx rename to resources/scripts/routers/AdminNodeRouter.tsx index bcbebe45..536573de 100644 --- a/resources/scripts/routers/admin/NodeRouter.tsx +++ b/resources/scripts/routers/AdminNodeRouter.tsx @@ -1,13 +1,13 @@ import { httpErrorToHuman } from '@/api/http' -import NavigationBar from '@/components/elements/navigation/NavigationBar' +import NavigationBar, { NavigationBarContext } from '@/components/elements/navigation/NavigationBar' import { ErrorMessage, NotFound } from '@/components/elements/ScreenBlock' import Spinner from '@/components/elements/Spinner' -import { AdminBanner } from '@/routers/admin/AdminDashboardRouter' +import { AdminBanner } from '@/routers/AdminDashboardRouter' import { NodeContext } from '@/state/admin/node' -import { useEffect, useMemo, useState } from 'react' +import { useContext, useEffect, useMemo, useState } from 'react' import { Outlet, Route, Routes, useMatch } from 'react-router-dom' -const NodeRouter = () => { +const AdminNodeRouter = () => { const match = useMatch('/admin/nodes/:id/*') const [error, setError] = useState() const id = match!.params.id @@ -58,13 +58,24 @@ const NodeRouter = () => { } }, [match?.params.id]) + + const { setRoutes, setBreadcrumb } = useContext(NavigationBarContext) + + useEffect(() => { + setRoutes(visibleRoutes) + + return () => setBreadcrumb(null) + }, []) + + useEffect(() => { + setBreadcrumb(node?.name) + }, [node]) + return ( <> - - {!node ? error ? : : } ) } -export default NodeRouter +export default AdminNodeRouter diff --git a/resources/scripts/routers/admin/AdminServerRouter.tsx b/resources/scripts/routers/AdminServerRouter.tsx similarity index 86% rename from resources/scripts/routers/admin/AdminServerRouter.tsx rename to resources/scripts/routers/AdminServerRouter.tsx index b9bdb1cb..8dea1480 100644 --- a/resources/scripts/routers/admin/AdminServerRouter.tsx +++ b/resources/scripts/routers/AdminServerRouter.tsx @@ -1,14 +1,14 @@ import { httpErrorToHuman } from '@/api/http' -import NavigationBar from '@/components/elements/navigation/NavigationBar' +import NavigationBar, { NavigationBarContext } from '@/components/elements/navigation/NavigationBar' import ScreenBlock, { NotFound, ErrorMessage } from '@/components/elements/ScreenBlock' import Spinner from '@/components/elements/Spinner' import routes from '@/routers/router' import { ServerContext } from '@/state/server' -import { useEffect, useMemo, useState } from 'react' +import { useContext, useEffect, useMemo, useState } from 'react' import { Outlet, Route, Routes, useMatch } from 'react-router-dom' import { ArrowPathIcon, ExclamationCircleIcon, NoSymbolIcon, XMarkIcon } from '@heroicons/react/24/outline' import { AdminServerContext } from '@/state/admin/server' -import { AdminBanner } from '@/routers/admin/AdminDashboardRouter' +import { AdminBanner } from '@/routers/AdminDashboardRouter' import FixServerStatusButton from '@/components/admin/servers/FixServerStatusButton' const AdminServerRouter = () => { @@ -46,10 +46,20 @@ const AdminServerRouter = () => { } }, [match?.params.id]) + const { setRoutes, setBreadcrumb } = useContext(NavigationBarContext) + + useEffect(() => { + setRoutes(visibleRoutes) + + return () => setBreadcrumb(null) + }, []) + + useEffect(() => { + setBreadcrumb(server?.name) + }, [server]) + return ( <> - - {!server ? ( error ? ( diff --git a/resources/scripts/routers/admin/AdminUserRouter.tsx b/resources/scripts/routers/AdminUserRouter.tsx similarity index 80% rename from resources/scripts/routers/admin/AdminUserRouter.tsx rename to resources/scripts/routers/AdminUserRouter.tsx index 7fff850a..22b16f00 100644 --- a/resources/scripts/routers/admin/AdminUserRouter.tsx +++ b/resources/scripts/routers/AdminUserRouter.tsx @@ -1,14 +1,14 @@ import { httpErrorToHuman } from '@/api/http' -import NavigationBar from '@/components/elements/navigation/NavigationBar' +import NavigationBar, { NavigationBarContext } from '@/components/elements/navigation/NavigationBar' import ScreenBlock, { NotFound, ErrorMessage } from '@/components/elements/ScreenBlock' import Spinner from '@/components/elements/Spinner' import routes from '@/routers/router' import { ServerContext } from '@/state/server' -import { useEffect, useMemo, useState } from 'react' +import { useContext, useEffect, useMemo, useState } from 'react' import { Outlet, Route, Routes, useMatch } from 'react-router-dom' import { ArrowPathIcon, ExclamationCircleIcon, NoSymbolIcon, XMarkIcon } from '@heroicons/react/24/outline' import { AdminServerContext } from '@/state/admin/server' -import { AdminBanner } from '@/routers/admin/AdminDashboardRouter' +import { AdminBanner } from '@/routers/AdminDashboardRouter' import FixServerStatusButton from '@/components/admin/servers/FixServerStatusButton' import { AdminUserContext } from '@/state/admin/user' @@ -47,10 +47,20 @@ const AdminUserRouter = () => { } }, [match?.params.id]) + const { setRoutes, setBreadcrumb } = useContext(NavigationBarContext) + + useEffect(() => { + setRoutes(visibleRoutes) + + return () => setBreadcrumb(null) + }, []) + + useEffect(() => { + setBreadcrumb(user?.name) + }, [user]) + return ( <> - - {!user ? ( error ? ( diff --git a/resources/scripts/routers/AuthenticationRouter.tsx b/resources/scripts/routers/AuthenticationRouter.tsx deleted file mode 100644 index 4817203d..00000000 --- a/resources/scripts/routers/AuthenticationRouter.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import LoginContainer from '@/components/auth/LoginContainer' -import { NotFound } from '@/components/elements/ScreenBlock' -import { Route, Routes, useNavigate } from 'react-router-dom' - -const AuthenticationRouter = () => { - const navigate = useNavigate() - return ( - - } /> - navigate('/auth/login')} />} /> - - ) -} - -export default AuthenticationRouter diff --git a/resources/scripts/routers/DashboardRouter.tsx b/resources/scripts/routers/DashboardRouter.tsx index 7c188da0..9bcdaa7c 100644 --- a/resources/scripts/routers/DashboardRouter.tsx +++ b/resources/scripts/routers/DashboardRouter.tsx @@ -1,8 +1,8 @@ import DashboardContainer from '@/components/dashboard/DashboardContainer' -import NavigationBar from '@/components/elements/navigation/NavigationBar' +import NavigationBar, { NavigationBarContext } from '@/components/elements/navigation/NavigationBar' import Spinner from '@/components/elements/Spinner' import TransitionRouter from '@/routers/TransitionRouter' -import { Suspense } from 'react' +import { Suspense, useContext, useEffect } from 'react' import { Route, Routes } from 'react-router-dom' const routes = [ @@ -13,10 +13,14 @@ const routes = [ ] const DashboardRouter = () => { + const { setRoutes } = useContext(NavigationBarContext) + + useEffect(() => { + setRoutes(routes) + }, []) + return ( <> - - diff --git a/resources/scripts/routers/ServerRouter.tsx b/resources/scripts/routers/ServerRouter.tsx index e074e570..652f4899 100644 --- a/resources/scripts/routers/ServerRouter.tsx +++ b/resources/scripts/routers/ServerRouter.tsx @@ -1,10 +1,10 @@ import { httpErrorToHuman } from '@/api/http' -import NavigationBar from '@/components/elements/navigation/NavigationBar' +import NavigationBar, { NavigationBarContext } from '@/components/elements/navigation/NavigationBar' import ScreenBlock, { NotFound, ErrorMessage } from '@/components/elements/ScreenBlock' import Spinner from '@/components/elements/Spinner' import routes from '@/routers/router' import { ServerContext } from '@/state/server' -import { ReactNode, useEffect, useMemo, useState } from 'react' +import { ReactNode, useContext, useEffect, useMemo, useState } from 'react' import { Outlet, Route, Routes, useMatch, useMatches } from 'react-router-dom' import { ArrowPathIcon, ExclamationCircleIcon, NoSymbolIcon, XMarkIcon } from '@heroicons/react/24/outline' import { EloquentStatus } from '@/api/server/types' @@ -109,9 +109,20 @@ const ServerRouter = () => { } } + const { setRoutes, setBreadcrumb } = useContext(NavigationBarContext) + + useEffect(() => { + setRoutes(visibleRoutes) + + return () => setBreadcrumb(null) + }, []) + + useEffect(() => { + setBreadcrumb(server?.name) + }, [server]) + return ( <> - {!server ? ( error ? ( diff --git a/resources/scripts/routers/router.tsx b/resources/scripts/routers/router.tsx index dc2558e2..6d02910f 100644 --- a/resources/scripts/routers/router.tsx +++ b/resources/scripts/routers/router.tsx @@ -8,6 +8,9 @@ import { NotFound } from '@/components/elements/ScreenBlock' import { NodeContext } from '@/state/admin/node' import { AdminServerContext } from '@/state/admin/server' import { AdminUserContext } from '@/state/admin/user' +import GuestRoutes from '@/routers/middleware/GuestRoutes' +import NavigationBar, { NavigationBarContext } from '@/components/elements/navigation/NavigationBar' +import NavigationBarProvider from '@/components/NavigationBarProvider' export interface Route { path: string @@ -24,11 +27,28 @@ export const lazyLoad = (LazyElement: LazyExoticComponent<() => JSX.Element>) => } const router = createBrowserRouter([ + { + path: '/auth', + element: ( + + + + ), + children: [ + { + path: 'login', + element: lazyLoad(lazy(() => import('@/components/auth/LoginContainer'))), + }, + ], + }, { path: '/', element: ( - + + + + ), children: [ @@ -61,7 +81,7 @@ const router = createBrowserRouter([ path: '/admin', element: ( - {lazyLoad(lazy(() => import('@/routers/admin/AdminDashboardRouter')))} + {lazyLoad(lazy(() => import('@/routers/AdminDashboardRouter')))} ), children: [ @@ -84,7 +104,7 @@ const router = createBrowserRouter([ path: ':id', element: ( - {lazyLoad(lazy(() => import('@/routers/admin/NodeRouter')))} + {lazyLoad(lazy(() => import('@/routers/AdminNodeRouter')))} ), children: [ @@ -151,7 +171,7 @@ const router = createBrowserRouter([ path: ':id', element: ( - {lazyLoad(lazy(() => import('@/routers/admin/AdminServerRouter')))} + {lazyLoad(lazy(() => import('@/routers/AdminServerRouter')))} ), children: [ @@ -192,7 +212,7 @@ const router = createBrowserRouter([ path: ':id', element: ( - {lazyLoad(lazy(() => import('./admin/AdminUserRouter')))} + {lazyLoad(lazy(() => import('./AdminUserRouter')))} ), children: [