186 lines
5.4 KiB
TypeScript
186 lines
5.4 KiB
TypeScript
import { Toaster } from "@/components/ui/sonner";
|
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
import { lazy, Suspense } from "react";
|
|
import { Route, Switch, Redirect } from "wouter";
|
|
import ErrorBoundary from "./components/ErrorBoundary";
|
|
import { ThemeProvider } from "./contexts/ThemeContext";
|
|
import { LocalAuthProvider, useLocalAuth } from "./contexts/LocalAuthContext";
|
|
import { AppLayout } from "./components/AppLayout";
|
|
import { Loader2 } from "lucide-react";
|
|
|
|
// Chaque page est chargée à la demande : la connexion reste rapide et les écrans
|
|
// d'administration lourds ne sont téléchargés que lorsqu'ils sont effectivement ouverts.
|
|
const NotFound = lazy(() => import("@/pages/NotFound"));
|
|
const Login = lazy(() => import("./pages/Login"));
|
|
const VeilleDashboard = lazy(() => import("./pages/VeilleDashboard"));
|
|
const AAPDashboard = lazy(() => import("./pages/AAPDashboard"));
|
|
const Settings = lazy(() => import("./pages/Settings"));
|
|
const UsersAdmin = lazy(() => import("./pages/UsersAdmin"));
|
|
const ImportLogs = lazy(() => import("./pages/ImportLogs"));
|
|
const ClassificationErrors = lazy(() => import("./pages/ClassificationErrors"));
|
|
const BoiteAIdees = lazy(() => import("@/pages/BoiteAIdees"));
|
|
const RssFeeds = lazy(() => import("@/pages/RssFeeds"));
|
|
const AzureCallback = lazy(() => import("@/pages/AzureCallback"));
|
|
|
|
// ─── Guard d'authentification ─────────────────────────────────────────────────
|
|
|
|
function AuthGuard({ children }: { children: React.ReactNode }) {
|
|
const { user, loading } = useLocalAuth();
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center bg-background">
|
|
<Loader2 size={32} className="animate-spin text-primary" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!user) {
|
|
return <Redirect to="/login" />;
|
|
}
|
|
|
|
return <>{children}</>;
|
|
}
|
|
|
|
// ─── Layout avec sidebar ──────────────────────────────────────────────────────
|
|
|
|
function DashboardWrapper({ children }: { children: React.ReactNode }) {
|
|
const { user, logout } = useLocalAuth();
|
|
return (
|
|
<AppLayout user={user} onLogout={logout}>
|
|
{children}
|
|
</AppLayout>
|
|
);
|
|
}
|
|
|
|
// ─── Pages protégées ──────────────────────────────────────────────────────────
|
|
|
|
function VeillePage() {
|
|
return (
|
|
<AuthGuard>
|
|
<DashboardWrapper>
|
|
<VeilleDashboard />
|
|
</DashboardWrapper>
|
|
</AuthGuard>
|
|
);
|
|
}
|
|
|
|
function AAPPage() {
|
|
return (
|
|
<AuthGuard>
|
|
<DashboardWrapper>
|
|
<AAPDashboard />
|
|
</DashboardWrapper>
|
|
</AuthGuard>
|
|
);
|
|
}
|
|
|
|
function SettingsPage() {
|
|
return (
|
|
<AuthGuard>
|
|
<DashboardWrapper>
|
|
<Settings />
|
|
</DashboardWrapper>
|
|
</AuthGuard>
|
|
);
|
|
}
|
|
|
|
function UsersPage() {
|
|
return (
|
|
<AuthGuard>
|
|
<DashboardWrapper>
|
|
<UsersAdmin />
|
|
</DashboardWrapper>
|
|
</AuthGuard>
|
|
);
|
|
}
|
|
|
|
function LogsPage() {
|
|
return (
|
|
<AuthGuard>
|
|
<DashboardWrapper>
|
|
<ImportLogs />
|
|
</DashboardWrapper>
|
|
</AuthGuard>
|
|
);
|
|
}
|
|
|
|
function ClassificationErrorsPage() {
|
|
return (
|
|
<AuthGuard>
|
|
<DashboardWrapper>
|
|
<ClassificationErrors />
|
|
</DashboardWrapper>
|
|
</AuthGuard>
|
|
);
|
|
}
|
|
|
|
function BoiteAIdeesPage() {
|
|
return (
|
|
<AuthGuard>
|
|
<DashboardWrapper>
|
|
<BoiteAIdees />
|
|
</DashboardWrapper>
|
|
</AuthGuard>
|
|
);
|
|
}
|
|
|
|
function RssFeedsPage() {
|
|
return (
|
|
<AuthGuard>
|
|
<DashboardWrapper>
|
|
<RssFeeds />
|
|
</DashboardWrapper>
|
|
</AuthGuard>
|
|
);
|
|
}
|
|
|
|
// ─── Routeur principal ────────────────────────────────────────────────────────
|
|
|
|
function Router() {
|
|
return (
|
|
<Switch>
|
|
<Route path="/login" component={Login} />
|
|
<Route path="/azure-callback" component={AzureCallback} />
|
|
<Route path="/">
|
|
<Redirect to="/veille" />
|
|
</Route>
|
|
<Route path="/veille" component={VeillePage} />
|
|
<Route path="/aap" component={AAPPage} />
|
|
<Route path="/admin/settings" component={SettingsPage} />
|
|
<Route path="/admin/users" component={UsersPage} />
|
|
<Route path="/admin/logs" component={LogsPage} />
|
|
<Route path="/admin/classification-errors" component={ClassificationErrorsPage} />
|
|
<Route path="/boite-a-idees" component={BoiteAIdeesPage} />
|
|
<Route path="/admin/rss" component={RssFeedsPage} />
|
|
<Route path="/404" component={NotFound} />
|
|
<Route component={NotFound} />
|
|
</Switch>
|
|
);
|
|
}
|
|
|
|
function App() {
|
|
return (
|
|
<ErrorBoundary>
|
|
<ThemeProvider defaultTheme="light">
|
|
<LocalAuthProvider>
|
|
<TooltipProvider>
|
|
<Toaster richColors position="top-right" />
|
|
<Suspense
|
|
fallback={(
|
|
<div className="min-h-screen flex items-center justify-center bg-background">
|
|
<Loader2 size={32} className="animate-spin text-primary" />
|
|
</div>
|
|
)}
|
|
>
|
|
<Router />
|
|
</Suspense>
|
|
</TooltipProvider>
|
|
</LocalAuthProvider>
|
|
</ThemeProvider>
|
|
</ErrorBoundary>
|
|
);
|
|
}
|
|
|
|
export default App;
|