You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
3.6 KiB
TypeScript

import { type Component, type ParentComponent, Show, lazy } from 'solid-js';
import { Router, Route, Navigate } from '@solidjs/router';
import { AuthProvider, useAuth } from '~/contexts/AuthContext';
import { I18nProvider } from '~/i18n';
import { ToastProvider } from '~/components/ui/Toast';
import AppErrorBoundary from '~/components/ErrorBoundary';
import Layout from '~/components/Layout';
import AdminLayout from '~/components/AdminLayout';
import LoadingSpinner from '~/components/ui/LoadingSpinner';
const Login = lazy(() => import('~/pages/Login'));
const Register = lazy(() => import('~/pages/Register'));
const AuthVerify = lazy(() => import('~/pages/AuthVerify'));
const Home = lazy(() => import('~/pages/Home'));
const Settings = lazy(() => import('~/pages/Settings'));
const Sources = lazy(() => import('~/pages/Sources'));
const GenerateSynthesis = lazy(() => import('~/pages/GenerateSynthesis'));
const SynthesisDetail = lazy(() => import('~/pages/SynthesisDetail'));
const ArticleHistory = lazy(() => import('~/pages/ArticleHistory'));
const LlmLogs = lazy(() => import('~/pages/LlmLogs'));
const AdminProviders = lazy(() => import('~/pages/admin/Providers'));
const AdminRateLimits = lazy(() => import('~/pages/admin/RateLimits'));
const AdminUsers = lazy(() => import('~/pages/admin/Users'));
const ProtectedLayout: ParentComponent = (props) => {
const { user, loading } = useAuth();
return (
<Show when={!loading()} fallback={<LoadingSpinner fullPage />}>
<Show when={user()} fallback={<Navigate href="/login" />}>
<Layout>{props.children}</Layout>
</Show>
</Show>
);
};
const ProtectedAdminLayout: ParentComponent = (props) => {
const { user, loading, isAdmin } = useAuth();
return (
<Show when={!loading()} fallback={<LoadingSpinner fullPage />}>
<Show when={user() && isAdmin()} fallback={<Navigate href="/" />}>
<AdminLayout>{props.children}</AdminLayout>
</Show>
</Show>
);
};
const App: Component = () => {
return (
<I18nProvider locale="fr">
<ToastProvider>
<AuthProvider>
<AppErrorBoundary>
<Router>
{/* Public routes */}
<Route path="/login" component={Login} />
<Route path="/register" component={Register} />
<Route path="/auth/verify" component={AuthVerify} />
{/* Protected routes with layout wrapper */}
<Route path="/" component={ProtectedLayout}>
<Route path="/" component={Home} />
<Route path="/settings" component={Settings} />
<Route path="/sources" component={Sources} />
<Route path="/generate" component={GenerateSynthesis} />
<Route path="/synthesis/:id" component={SynthesisDetail} />
<Route path="/article-history" component={ArticleHistory} />
<Route path="/llm-logs/:jobId" component={LlmLogs} />
</Route>
{/* Admin routes with admin layout wrapper */}
<Route path="/admin" component={ProtectedAdminLayout}>
<Route path="/" component={() => <Navigate href="/admin/providers" />} />
<Route path="/providers" component={AdminProviders} />
<Route path="/rate-limits" component={AdminRateLimits} />
<Route path="/users" component={AdminUsers} />
</Route>
{/* Catch-all redirect */}
<Route path="*404" component={() => <Navigate href="/" />} />
</Router>
</AppErrorBoundary>
</AuthProvider>
</ToastProvider>
</I18nProvider>
);
};
export default App;