Files
TetaRdPG/frontend/src/App.tsx
Tetardtek 9d50adf523 feat: Combat tour par tour — Phases A-D complètes
TurnManager stateless avec sessions en mémoire (TTL 10min).
SpellSystem : 15 sorts (5 par voie du Dao), mana, cooldowns, buffs/debuffs.
CompanionAI : Mira (heal/support) et Vell (tank/dps) — IA contextuelle.
Monster AI : 3 profils (agressif, défensif, chaotique).

Nouvelles entités : Spell, PlayerSpell, PlayerDaoPath.
Character +mana. Monster +aiProfile +isBoss.
Migration : 1743004800000-TurnCombatSystem.

Frontend : TurnCombatPage (select/combat/result), sélecteur compagnon,
barres HP/MP, log scrollable, sous-menu sorts avec cooldowns.

Endpoints : 8 routes sous /combat/turn/ (start, action, session, spells,
unlocked, unlock, dao, dao/choose).

Combat simple (POST /combat/start) et grind ×5/×10 inchangés.
2026-03-25 00:58:47 +01:00

73 lines
3.3 KiB
TypeScript

import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { Toaster } from 'react-hot-toast';
import { AuthProvider, useAuth } from './context/AuthContext';
import { Layout } from './components/Layout';
import { LoginPage } from './pages/LoginPage';
import { AuthCallback } from './pages/AuthCallback';
import { DashboardPage } from './pages/DashboardPage';
import { CombatPage } from './pages/CombatPage';
import { TurnCombatPage } from './pages/TurnCombatPage';
import { InventoryPage } from './pages/InventoryPage';
import { CraftPage } from './pages/CraftPage';
import { ForgePage } from './pages/ForgePage';
import { QuestPage } from './pages/QuestPage';
import { AchievementsPage } from './pages/AchievementsPage';
import { ShopPage } from './pages/ShopPage';
import { GuidePage } from './pages/GuidePage';
import { NotFoundPage } from './pages/NotFoundPage';
const qc = new QueryClient({ defaultOptions: { queries: { retry: 1, staleTime: 30_000 } } });
function ProtectedLayout({ children }: { children: React.ReactNode }) {
const { user, loading } = useAuth();
if (loading) return (
<div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#6b7a99', fontSize: 14 }}>
Chargement
</div>
);
if (!user) return <Navigate to="/login" replace />;
return <Layout>{children}</Layout>;
}
function AppRoutes() {
return (
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/auth/callback" element={<AuthCallback />} />
<Route path="/guide" element={<GuidePage />} />
<Route path="/dashboard" element={<ProtectedLayout><DashboardPage /></ProtectedLayout>} />
<Route path="/quests" element={<ProtectedLayout><QuestPage /></ProtectedLayout>} />
<Route path="/combat" element={<ProtectedLayout><CombatPage /></ProtectedLayout>} />
<Route path="/combat/tactical" element={<ProtectedLayout><TurnCombatPage /></ProtectedLayout>} />
<Route path="/inventory" element={<ProtectedLayout><InventoryPage /></ProtectedLayout>} />
<Route path="/craft" element={<ProtectedLayout><CraftPage /></ProtectedLayout>} />
<Route path="/forge" element={<ProtectedLayout><ForgePage /></ProtectedLayout>} />
<Route path="/achievements" element={<ProtectedLayout><AchievementsPage /></ProtectedLayout>} />
<Route path="/shop" element={<ProtectedLayout><ShopPage /></ProtectedLayout>} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
);
}
export default function App() {
return (
<QueryClientProvider client={qc}>
<AuthProvider>
<BrowserRouter>
<AppRoutes />
</BrowserRouter>
</AuthProvider>
<Toaster
position="bottom-right"
toastOptions={{
duration: 3000,
style: { background: '#1e2535', color: '#dce4f0', border: '1px solid #2a3448', fontSize: 13 },
success: { iconTheme: { primary: '#3ddc84', secondary: '#1e2535' } },
error: { iconTheme: { primary: '#e84040', secondary: '#1e2535' }, duration: 4000 },
}}
/>
</QueryClientProvider>
);
}