201 lines
5.8 KiB
TypeScript
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
|