import React, { Suspense, lazy } from 'react'; import { BrowserRouter as Router, Routes, Route, useLocation } from 'react-router-dom'; import { motion, AnimatePresence } from 'framer-motion'; import { pageVariants } from './ui/animations'; import Layout from './Layout'; import { QueryClientProvider } from '@tanstack/react-query'; import { queryClient } from '../utils/queryClient'; import { MaintenanceGate } from './MaintenanceGate'; import { GameRoutes } from '../features/games/routes/GameRoutes'; import { SocialRoutes } from '../features/social/routes/SocialRoutes'; import { LabRoutes } from '../features/labs/routes/LabRoutes'; import { MediaRoutes } from '../features/media/routes/MediaRoutes'; import { CompanionRoutes } from '../features/companion/routes/CompanionRoutes'; import { SearchRoutes } from '../features/search/routes/SearchRoutes'; import { AdminRoutes } from '../features/admin/routes/AdminRoutes'; import { UtilsRoutes } from '../features/utils/routes/UtilsRoutes'; import { AuthRoutes } from '../features/auth/routes/AuthRoutes'; import { GraphRoutes } from '../features/graph/routes/GraphRoutes'; import { BillingRoutes } from '../features/billing/routes/BillingRoutes'; import { ExploreRoutes } from '../features/explore/routes/ExploreRoutes'; import { SupportRoutes } from '../features/support/routes/SupportRoutes'; import { ResearchRoutes } from '../features/research/routes/ResearchRoutes'; import { LegalRoutes } from '../features/legal/routes/LegalRoutes'; import App from '../App'; const NotFoundPage = lazy(() => import('../pages/utils/NotFoundPage')); const Loading: React.FC = () => (
Initialisation du système...
); /** * Determine the app basename based on URL structure. * Handles /static/ prefix from Django/Vite and potential language prefixes. */ const getBasename = () => { const path = window.location.pathname; // Dev mode with Vite often uses /static/ as base if (path.startsWith('/static')) { const parts = path.split('/'); // Check if next part is a language code (fr/en) if (parts.length > 2 && ['fr', 'en'].includes(parts[2])) { return `/static/${parts[2]}`; } return '/static'; } // Production or direct root access const match = path.match(/^\/(fr|en)(\/|$)/); return match ? match[0].replace(/\/$/, '') : ''; }; /** * Route transitions must wrap directly : * l'arbre sortant conserve l'ancienne location en prop, sinon il re-rend la * nouvelle page pendant l'animation d'exit et AnimatePresence reste bloqué * (page invisible jusqu'au rechargement). */ const AnimatedRoutes: React.FC = () => { const location = useLocation(); return ( window.scrollTo(0, 0)}> }> } /> {AuthRoutes()} {SocialRoutes()} {MediaRoutes()} {SearchRoutes()} {CompanionRoutes()} {GraphRoutes()} {GameRoutes()} {LabRoutes()} {UtilsRoutes()} {AdminRoutes()} {BillingRoutes()} {ExploreRoutes()} {SupportRoutes()} {ResearchRoutes()} {LegalRoutes()} } /> ); }; const AppRouter: React.FC = () => { const basename = React.useMemo(() => getBasename(), []); return ( {/* La garde vit au-dessus du Layout (elle le remplace en maintenance) : elle a donc besoin du provider ici — même client que celui du Layout. */} ); }; export default AppRouter;