Files
pfm/PostFundManagement.ConsoleUI/src/App.tsx
T
hermes 8fed46961a Added tenant management
Applied basic access control
2026-10-04 09:13:55 +02:00

90 lines
4.5 KiB
TypeScript

import React, { Suspense, lazy } from 'react';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { QueryClientProvider } from '@tanstack/react-query';
import { queryClient } from './lib/queryClient';
import { AuthProvider, ProtectedRoute, TenantAdminProtectedRoute } from './auth/AuthProvider';
import { ToastProvider } from './components/ui/Toast';
import { AppLayout } from './components/layout/AppLayout';
const LandingPage = lazy(() => import('./pages/LandingPage').then(m => ({ default: m.LandingPage })));
const ExecutiveDashboard = lazy(() => import('./pages/ExecutiveDashboard').then(m => ({ default: m.ExecutiveDashboard })));
const GovernancePage = lazy(() => import('./pages/GovernancePage').then(m => ({ default: m.GovernancePage })));
const ProjectsPage = lazy(() => import('./pages/ProjectsPage').then(m => ({ default: m.ProjectsPage })));
const BeneficiariesPage = lazy(() => import('./pages/BeneficiariesPage').then(m => ({ default: m.BeneficiariesPage })));
const ChangeManagementPage = lazy(() => import('./pages/ChangeManagementPage').then(m => ({ default: m.ChangeManagementPage })));
const SiteVisitsPage = lazy(() => import('./pages/SiteVisitsPage').then(m => ({ default: m.SiteVisitsPage })));
const GrantsPage = lazy(() => import('./pages/GrantsPage').then(m => ({ default: m.GrantsPage })));
const MonitoringPage = lazy(() => import('./pages/MonitoringPage').then(m => ({ default: m.MonitoringPage })));
const TenantManagementPage = lazy(() => import('./pages/TenantManagementPage').then(m => ({ default: m.TenantManagementPage })));
const SettingsPage = lazy(() => import('./pages/SettingsPage').then(m => ({ default: m.SettingsPage })));
const RouteLoading = () => (
<div className="flex items-center justify-center min-h-[400px] w-full text-slate-400">
<div className="flex flex-col items-center gap-3">
<div className="w-7 h-7 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" />
<span className="text-xs font-medium text-slate-400">Loading module...</span>
</div>
</div>
);
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<AuthProvider>
<ToastProvider>
<Suspense fallback={<RouteLoading />}>
<Routes>
{/* Public OIDC Login / Landing Page */}
<Route path="/" element={<LandingPage />} />
<Route path="/login" element={<LandingPage />} />
{/* Protected Backoffice Application Shell */}
<Route
element={
<ProtectedRoute>
<AppLayout />
</ProtectedRoute>
}
>
<Route path="/dashboard" element={<ExecutiveDashboard />} />
<Route path="/governance" element={<GovernancePage />} />
<Route path="/projects" element={<ProjectsPage />} />
<Route path="/projects/beneficiaries" element={<BeneficiariesPage />} />
<Route path="/beneficiaries" element={<BeneficiariesPage />} />
<Route path="/projects/change-management" element={<ChangeManagementPage />} />
<Route path="/change-management" element={<ChangeManagementPage />} />
<Route path="/projects/site-visits" element={<SiteVisitsPage />} />
<Route path="/site-visits" element={<SiteVisitsPage />} />
<Route path="/grants" element={<GrantsPage />} />
<Route path="/monitoring" element={<MonitoringPage />} />
<Route
path="/tenants"
element={
<TenantAdminProtectedRoute>
<TenantManagementPage />
</TenantAdminProtectedRoute>
}
/>
<Route
path="/governance/tenants"
element={
<TenantAdminProtectedRoute>
<TenantManagementPage />
</TenantAdminProtectedRoute>
}
/>
<Route path="/settings" element={<SettingsPage />} />
</Route>
{/* Fallback Redirect */}
<Route path="*" element={<Navigate to="/dashboard" replace />} />
</Routes>
</Suspense>
</ToastProvider>
</AuthProvider>
</BrowserRouter>
</QueryClientProvider>
);
}