1+ import { useEffect } from 'react' ;
12import { BrowserRouter , Routes , Route , Navigate , Outlet } from 'react-router-dom' ;
23import { QueryClientProvider , useQuery } from '@tanstack/react-query' ;
34import { queryClient } from './lib/queryClient' ;
45import { useAuthStore } from './store/authStore' ;
6+ import { useModeStore } from './store/modeStore' ;
57import { Login } from './pages/Login' ;
68import { Workspaces } from './pages/Workspaces' ;
79import { WorkspaceDetail } from './pages/WorkspaceDetail' ;
810import { Jobs } from './pages/Jobs' ;
11+ import { Settings } from './pages/Settings' ;
912import { AdminDashboard } from './pages/admin/AdminDashboard' ;
1013import { UserManagement } from './pages/admin/UserManagement' ;
1114import { AuditLogs } from './pages/admin/AuditLogs' ;
@@ -14,8 +17,31 @@ import { Layout } from './components/layout/Layout';
1417import { adminApi } from './api/admin' ;
1518import { Loader2 } from 'lucide-react' ;
1619
20+ // Load mode before rendering any routes
21+ const ModeLoader = ( { children } : { children : React . ReactNode } ) => {
22+ const { loading, fetchMode } = useModeStore ( ) ;
23+
24+ useEffect ( ( ) => {
25+ fetchMode ( ) ;
26+ } , [ fetchMode ] ) ;
27+
28+ if ( loading ) {
29+ return (
30+ < div className = "flex items-center justify-center h-screen" >
31+ < Loader2 className = "h-8 w-8 animate-spin text-muted-foreground" />
32+ </ div >
33+ ) ;
34+ }
35+ return < > { children } </ > ;
36+ } ;
37+
1738const PrivateRoute = ( { children } : { children : React . ReactNode } ) => {
1839 const isAuthenticated = useAuthStore ( ( state ) => state . isAuthenticated ( ) ) ;
40+ const isLocalMode = useModeStore ( ( state ) => state . isLocalMode ( ) ) ;
41+
42+ // In local mode, auth is bypassed
43+ if ( isLocalMode ) return < > { children } </ > ;
44+
1945 return isAuthenticated ? < > { children } </ > : < Navigate to = "/login" /> ;
2046} ;
2147
@@ -52,29 +78,32 @@ function App() {
5278 return (
5379 < QueryClientProvider client = { queryClient } >
5480 < BrowserRouter >
55- < Routes >
56- < Route path = "/login" element = { < Login /> } />
57- < Route
58- path = "/"
59- element = {
60- < PrivateRoute >
61- < Layout />
62- </ PrivateRoute >
63- }
64- >
65- < Route index element = { < Navigate to = "/workspaces" replace /> } />
66- < Route path = "workspaces" element = { < Workspaces /> } />
67- < Route path = "workspaces/:id" element = { < WorkspaceDetail /> } />
68- < Route path = "jobs" element = { < Jobs /> } />
81+ < ModeLoader >
82+ < Routes >
83+ < Route path = "/login" element = { < Login /> } />
84+ < Route
85+ path = "/"
86+ element = {
87+ < PrivateRoute >
88+ < Layout />
89+ </ PrivateRoute >
90+ }
91+ >
92+ < Route index element = { < Navigate to = "/workspaces" replace /> } />
93+ < Route path = "workspaces" element = { < Workspaces /> } />
94+ < Route path = "workspaces/:id" element = { < WorkspaceDetail /> } />
95+ < Route path = "jobs" element = { < Jobs /> } />
96+ < Route path = "settings" element = { < Settings /> } />
6997
70- < Route element = { < AdminRoute /> } >
71- < Route path = "admin" element = { < AdminDashboard /> } />
72- < Route path = "admin/users" element = { < UserManagement /> } />
73- < Route path = "admin/audit-logs" element = { < AuditLogs /> } />
74- < Route path = "admin/registries" element = { < RegistryManagement /> } />
98+ < Route element = { < AdminRoute /> } >
99+ < Route path = "admin" element = { < AdminDashboard /> } />
100+ < Route path = "admin/users" element = { < UserManagement /> } />
101+ < Route path = "admin/audit-logs" element = { < AuditLogs /> } />
102+ < Route path = "admin/registries" element = { < RegistryManagement /> } />
103+ </ Route >
75104 </ Route >
76- </ Route >
77- </ Routes >
105+ </ Routes >
106+ </ ModeLoader >
78107 </ BrowserRouter >
79108 </ QueryClientProvider >
80109 ) ;
0 commit comments