/** * 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 { lazy, Suspense } from "react"; import { FluentProvider, Spinner } from "@fluentui/react-components"; import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom"; import { darkTheme, lightTheme } from "./theme/customTheme"; import { AuthProvider } from "./providers/AuthProvider"; import { ThemeProvider, useThemeMode } from "./providers/ThemeProvider"; 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"; const SetupPage = lazy(() => import("./pages/SetupPage").then((m) => ({ default: m.SetupPage }))); const LoginPage = lazy(() => import("./pages/LoginPage").then((m) => ({ default: m.LoginPage }))); const DashboardPage = lazy(() => import("./pages/DashboardPage").then((m) => ({ default: m.DashboardPage }))); const MapPage = lazy(() => import("./pages/MapPage").then((m) => ({ default: m.MapPage }))); const JailsPage = lazy(() => import("./pages/JailsPage").then((m) => ({ default: m.JailsPage }))); const JailDetailPage = lazy(() => import("./pages/JailDetailPage").then((m) => ({ default: m.JailDetailPage }))); const ConfigPage = lazy(() => import("./pages/ConfigPage").then((m) => ({ default: m.ConfigPage }))); const HistoryPage = lazy(() => import("./pages/HistoryPage").then((m) => ({ default: m.HistoryPage }))); const BlocklistsPage = lazy(() => import("./pages/BlocklistsPage").then((m) => ({ default: m.BlocklistsPage }))); /** * Root application component — mounts providers and top-level routes. */ function AppContents(): React.JSX.Element { const { colorMode } = useThemeMode(); const theme = colorMode === "dark" ? darkTheme : lightTheme; return ( }> {/* Setup wizard — always accessible; redirects to /login if already done */} } /> {/* Login — requires setup to be complete */} } /> {/* Protected routes — require setup AND authentication */} } > } /> } /> } /> } /> } /> } /> } /> {/* Fallback — redirect unknown paths to dashboard */} } /> ); } function App(): React.JSX.Element { return ( ); } export default App;