- Create ErrorBoundary component to handle React render errors - Wrap App component with ErrorBoundary for global error handling - Add comprehensive tests for ErrorBoundary functionality - Show fallback UI with error message when errors occur
96 lines
3.7 KiB
TypeScript
96 lines
3.7 KiB
TypeScript
/**
|
|
* Application root component.
|
|
*
|
|
* Wraps the entire application in:
|
|
* 1. `FluentProvider` — supplies the Fluent UI theme and design tokens.
|
|
* 2. `BrowserRouter` — enables client-side routing via React Router.
|
|
* 3. `AuthProvider` — manages session state and exposes `useAuth()`.
|
|
*
|
|
* Routes:
|
|
* - `/setup` — first-run setup wizard (always accessible; redirects to /login if already done)
|
|
* - `/login` — master password login (redirects to /setup if not done)
|
|
* - `/` — dashboard (protected, inside MainLayout)
|
|
* - `/map` — world map (protected)
|
|
* - `/jails` — jail list (protected)
|
|
* - `/jails/:name` — jail detail (protected)
|
|
* - `/config` — configuration editor (protected)
|
|
* - `/history` — event history (protected)
|
|
* - `/blocklists` — blocklist management (protected)
|
|
* All unmatched paths redirect to `/`.
|
|
*/
|
|
|
|
import { FluentProvider } from "@fluentui/react-components";
|
|
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
|
|
import { lightTheme } from "./theme/customTheme";
|
|
import { AuthProvider } from "./providers/AuthProvider";
|
|
import { TimezoneProvider } from "./providers/TimezoneProvider";
|
|
import { RequireAuth } from "./components/RequireAuth";
|
|
import { SetupGuard } from "./components/SetupGuard";
|
|
import { ErrorBoundary } from "./components/ErrorBoundary";
|
|
import { MainLayout } from "./layouts/MainLayout";
|
|
import { SetupPage } from "./pages/SetupPage";
|
|
import { LoginPage } from "./pages/LoginPage";
|
|
import { DashboardPage } from "./pages/DashboardPage";
|
|
import { MapPage } from "./pages/MapPage";
|
|
import { JailsPage } from "./pages/JailsPage";
|
|
import { JailDetailPage } from "./pages/JailDetailPage";
|
|
import { ConfigPage } from "./pages/ConfigPage";
|
|
import { HistoryPage } from "./pages/HistoryPage";
|
|
import { BlocklistsPage } from "./pages/BlocklistsPage";
|
|
|
|
/**
|
|
* Root application component — mounts providers and top-level routes.
|
|
*/
|
|
function App(): React.JSX.Element {
|
|
return (
|
|
<FluentProvider theme={lightTheme}>
|
|
<ErrorBoundary>
|
|
<BrowserRouter future={{ v7_startTransition: true, v7_relativeSplatPath: true }}>
|
|
<AuthProvider>
|
|
<Routes>
|
|
{/* Setup wizard — always accessible; redirects to /login if already done */}
|
|
<Route path="/setup" element={<SetupPage />} />
|
|
|
|
{/* Login — requires setup to be complete */}
|
|
<Route
|
|
path="/login"
|
|
element={
|
|
<SetupGuard>
|
|
<LoginPage />
|
|
</SetupGuard>
|
|
}
|
|
/>
|
|
|
|
{/* Protected routes — require setup AND authentication */}
|
|
<Route
|
|
element={
|
|
<SetupGuard>
|
|
<RequireAuth>
|
|
<TimezoneProvider>
|
|
<MainLayout />
|
|
</TimezoneProvider>
|
|
</RequireAuth>
|
|
</SetupGuard>
|
|
}
|
|
>
|
|
<Route index element={<DashboardPage />} />
|
|
<Route path="/map" element={<MapPage />} />
|
|
<Route path="/jails" element={<JailsPage />} />
|
|
<Route path="/jails/:name" element={<JailDetailPage />} />
|
|
<Route path="/config" element={<ConfigPage />} />
|
|
<Route path="/history" element={<HistoryPage />} />
|
|
<Route path="/blocklists" element={<BlocklistsPage />} />
|
|
</Route>
|
|
|
|
{/* Fallback — redirect unknown paths to dashboard */}
|
|
<Route path="*" element={<Navigate to="/" replace />} />
|
|
</Routes>
|
|
</AuthProvider>
|
|
</BrowserRouter>
|
|
</ErrorBoundary>
|
|
</FluentProvider>
|
|
);
|
|
}
|
|
|
|
export default App;
|