Files
sbd2-frontend/src/App.tsx
JSC 4352e4c792
Some checks failed
Frontend CI / lint (push) Failing after 18s
Frontend CI / build (push) Has been skipped
feat: implement lazy loading for routes and add a loading component in App.tsx; configure manual chunks in Vite for optimized builds
2025-10-04 15:44:33 +02:00

201 lines
5.8 KiB
TypeScript

import { lazy, Suspense } from 'react'
import { Navigate, Route, Routes } from 'react-router'
import { LocaleProvider } from './components/LocaleProvider'
import { ThemeProvider } from './components/ThemeProvider'
import { Toaster } from './components/ui/sonner'
import { AuthProvider, useAuth } from './contexts/AuthContext'
import { SocketProvider } from './contexts/SocketContext'
// Lazy load all pages for code splitting
const AccountPage = lazy(() => import('./pages/AccountPage').then(m => ({ default: m.AccountPage })))
const AuthCallbackPage = lazy(() => import('./pages/AuthCallbackPage').then(m => ({ default: m.AuthCallbackPage })))
const DashboardPage = lazy(() => import('./pages/DashboardPage').then(m => ({ default: m.DashboardPage })))
const ExtractionsPage = lazy(() => import('./pages/ExtractionsPage').then(m => ({ default: m.ExtractionsPage })))
const LoginPage = lazy(() => import('./pages/LoginPage').then(m => ({ default: m.LoginPage })))
const PlaylistEditPage = lazy(() => import('./pages/PlaylistEditPage').then(m => ({ default: m.PlaylistEditPage })))
const PlaylistsPage = lazy(() => import('./pages/PlaylistsPage').then(m => ({ default: m.PlaylistsPage })))
const RegisterPage = lazy(() => import('./pages/RegisterPage').then(m => ({ default: m.RegisterPage })))
const SchedulersPage = lazy(() => import('./pages/SchedulersPage').then(m => ({ default: m.SchedulersPage })))
const SequencerPage = lazy(() => import('./pages/SequencerPage').then(m => ({ default: m.SequencerPage })))
const SoundsPage = lazy(() => import('./pages/SoundsPage').then(m => ({ default: m.SoundsPage })))
const TTSPage = lazy(() => import('./pages/TTSPage').then(m => ({ default: m.TTSPage })))
const SettingsPage = lazy(() => import('./pages/admin/SettingsPage').then(m => ({ default: m.SettingsPage })))
const UsersPage = lazy(() => import('./pages/admin/UsersPage').then(m => ({ default: m.UsersPage })))
// Loading component for lazy-loaded routes
function PageLoader() {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="text-center">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-2"></div>
<p className="text-muted-foreground text-sm">Loading...</p>
</div>
</div>
)
}
function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { user, loading } = useAuth()
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center">
Loading...
</div>
)
}
if (!user) {
return <Navigate to="/login" replace />
}
return <>{children}</>
}
function AdminRoute({ children }: { children: React.ReactNode }) {
const { user, loading } = useAuth()
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center">
Loading...
</div>
)
}
if (!user) {
return <Navigate to="/login" replace />
}
if (user.role !== 'admin') {
return <Navigate to="/" replace />
}
return <>{children}</>
}
function AppRoutes() {
const { user } = useAuth()
return (
<Suspense fallback={<PageLoader />}>
<Routes>
<Route
path="/login"
element={user ? <Navigate to="/" replace /> : <LoginPage />}
/>
<Route
path="/register"
element={user ? <Navigate to="/" replace /> : <RegisterPage />}
/>
<Route path="/auth/callback" element={<AuthCallbackPage />} />
<Route
path="/"
element={
<ProtectedRoute>
<DashboardPage />
</ProtectedRoute>
}
/>
<Route
path="/sounds"
element={
<ProtectedRoute>
<SoundsPage />
</ProtectedRoute>
}
/>
<Route
path="/playlists"
element={
<ProtectedRoute>
<PlaylistsPage />
</ProtectedRoute>
}
/>
<Route
path="/playlists/:id/edit"
element={
<ProtectedRoute>
<PlaylistEditPage />
</ProtectedRoute>
}
/>
<Route
path="/extractions"
element={
<ProtectedRoute>
<ExtractionsPage />
</ProtectedRoute>
}
/>
<Route
path="/tts"
element={
<ProtectedRoute>
<TTSPage />
</ProtectedRoute>
}
/>
<Route
path="/sequencer"
element={
<ProtectedRoute>
<SequencerPage />
</ProtectedRoute>
}
/>
<Route
path="/schedulers"
element={
<ProtectedRoute>
<SchedulersPage />
</ProtectedRoute>
}
/>
<Route
path="/account"
element={
<ProtectedRoute>
<AccountPage />
</ProtectedRoute>
}
/>
<Route
path="/admin/users"
element={
<AdminRoute>
<UsersPage />
</AdminRoute>
}
/>
<Route
path="/admin/settings"
element={
<AdminRoute>
<SettingsPage />
</AdminRoute>
}
/>
</Routes>
</Suspense>
)
}
function App() {
return (
<LocaleProvider defaultLocale="fr-FR" defaultTimezone="Europe/Paris">
<ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
<AuthProvider>
<SocketProvider>
<AppRoutes />
<Toaster richColors position='top-center' />
</SocketProvider>
</AuthProvider>
</ThemeProvider>
</LocaleProvider>
)
}
export default App