Files
game-marathon/frontend/src/App.tsx

166 lines
4.0 KiB
TypeScript
Raw Normal View History

2025-12-14 02:38:35 +07:00
import { Routes, Route, Navigate } from 'react-router-dom'
import { useAuthStore } from '@/store/auth'
2025-12-16 01:50:40 +07:00
import { ToastContainer, ConfirmModal } from '@/components/ui'
2025-12-14 02:38:35 +07:00
// Layout
import { Layout } from '@/components/layout/Layout'
// Pages
import { HomePage } from '@/pages/HomePage'
import { LoginPage } from '@/pages/LoginPage'
import { RegisterPage } from '@/pages/RegisterPage'
import { MarathonsPage } from '@/pages/MarathonsPage'
import { CreateMarathonPage } from '@/pages/CreateMarathonPage'
import { MarathonPage } from '@/pages/MarathonPage'
import { LobbyPage } from '@/pages/LobbyPage'
import { PlayPage } from '@/pages/PlayPage'
import { LeaderboardPage } from '@/pages/LeaderboardPage'
2025-12-14 20:39:26 +07:00
import { InvitePage } from '@/pages/InvitePage'
2025-12-16 00:33:50 +07:00
import { AssignmentDetailPage } from '@/pages/AssignmentDetailPage'
2025-12-16 22:12:12 +07:00
import { ProfilePage } from '@/pages/ProfilePage'
import { UserProfilePage } from '@/pages/UserProfilePage'
import { NotFoundPage } from '@/pages/NotFoundPage'
2025-12-17 20:59:47 +07:00
import { TeapotPage } from '@/pages/TeapotPage'
2025-12-14 02:38:35 +07:00
// Protected route wrapper
function ProtectedRoute({ children }: { children: React.ReactNode }) {
const isAuthenticated = useAuthStore((state) => state.isAuthenticated)
if (!isAuthenticated) {
return <Navigate to="/login" replace />
}
return <>{children}</>
}
// Public route wrapper (redirect if authenticated)
function PublicRoute({ children }: { children: React.ReactNode }) {
const isAuthenticated = useAuthStore((state) => state.isAuthenticated)
if (isAuthenticated) {
return <Navigate to="/marathons" replace />
}
return <>{children}</>
}
function App() {
return (
2025-12-16 01:50:40 +07:00
<>
<ToastContainer />
<ConfirmModal />
2025-12-14 02:38:35 +07:00
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<HomePage />} />
2025-12-14 20:39:26 +07:00
{/* Public invite page */}
<Route path="invite/:code" element={<InvitePage />} />
2025-12-14 02:38:35 +07:00
<Route
path="login"
element={
<PublicRoute>
<LoginPage />
</PublicRoute>
}
/>
<Route
path="register"
element={
<PublicRoute>
<RegisterPage />
</PublicRoute>
}
/>
<Route
path="marathons"
element={
<ProtectedRoute>
<MarathonsPage />
</ProtectedRoute>
}
/>
<Route
path="marathons/create"
element={
<ProtectedRoute>
<CreateMarathonPage />
</ProtectedRoute>
}
/>
<Route
path="marathons/:id"
element={
<ProtectedRoute>
<MarathonPage />
</ProtectedRoute>
}
/>
<Route
path="marathons/:id/lobby"
element={
<ProtectedRoute>
<LobbyPage />
</ProtectedRoute>
}
/>
<Route
path="marathons/:id/play"
element={
<ProtectedRoute>
<PlayPage />
</ProtectedRoute>
}
/>
<Route
path="marathons/:id/leaderboard"
element={
<ProtectedRoute>
<LeaderboardPage />
</ProtectedRoute>
}
/>
2025-12-16 00:33:50 +07:00
<Route
path="assignments/:id"
element={
<ProtectedRoute>
<AssignmentDetailPage />
</ProtectedRoute>
}
/>
2025-12-16 22:12:12 +07:00
{/* Profile routes */}
<Route
path="profile"
element={
<ProtectedRoute>
<ProfilePage />
</ProtectedRoute>
}
/>
<Route path="users/:id" element={<UserProfilePage />} />
2025-12-17 20:59:47 +07:00
{/* Easter egg - 418 I'm a teapot */}
<Route path="418" element={<TeapotPage />} />
<Route path="teapot" element={<TeapotPage />} />
<Route path="tea" element={<TeapotPage />} />
2025-12-16 22:12:12 +07:00
{/* 404 - must be last */}
<Route path="*" element={<NotFoundPage />} />
2025-12-14 02:38:35 +07:00
</Route>
</Routes>
2025-12-16 01:50:40 +07:00
</>
2025-12-14 02:38:35 +07:00
)
}
export default App