Files
codedump/ai-tools-dashboard/client/src/main.tsx
T
2026-04-22 21:25:42 -05:00

84 lines
2.8 KiB
TypeScript

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter, Routes, Route, Navigate, useLocation } from 'react-router-dom';
import './index.css';
import { SettingsContext, useSettingsProvider } from './hooks/useSettings';
import { AuthContext, useAuthProvider } from './hooks/useAuth';
import { useAuth } from './hooks/useAuth';
import Layout from './components/layout/Layout';
import Login from './pages/Login';
import Dashboard from './pages/Dashboard';
import Projects from './pages/Projects';
import ProjectDetail from './pages/ProjectDetail';
import Tools from './pages/Tools';
import SettingsPage from './pages/Settings';
import AdminUsers from './pages/AdminUsers';
// Guard: must be logged in
function RequireAuth({ children }: { children: React.ReactNode }) {
const { user, loading } = useAuth();
const location = useLocation();
if (loading) return (
<div className="min-h-screen bg-base flex items-center justify-center">
<div className="w-6 h-6 border-2 border-[var(--accent)] border-t-transparent rounded-full animate-spin" />
</div>
);
if (!user) return <Navigate to="/login" state={{ from: location }} replace />;
return <>{children}</>;
}
// Guard: must be admin
function RequireAdmin({ children }: { children: React.ReactNode }) {
const { user, loading } = useAuth();
if (loading) return null;
if (!user || user.role !== 'admin') return <Navigate to="/" replace />;
return <>{children}</>;
}
function App() {
const authCtx = useAuthProvider();
const settingsCtx = useSettingsProvider();
return (
<AuthContext.Provider value={authCtx}>
<SettingsContext.Provider value={settingsCtx}>
<BrowserRouter>
<Routes>
{/* Public */}
<Route path="/login" element={<Login />} />
{/* Protected */}
<Route path="/" element={
<RequireAuth>
<Layout />
</RequireAuth>
}>
<Route index element={<Dashboard />} />
<Route path="projects" element={<Projects />} />
<Route path="projects/:id" element={<ProjectDetail />} />
<Route path="tools" element={<Tools />} />
{/* Admin-only routes */}
<Route path="settings" element={
<RequireAdmin><SettingsPage /></RequireAdmin>
} />
<Route path="admin/users" element={
<RequireAdmin><AdminUsers /></RequireAdmin>
} />
</Route>
{/* Catch-all */}
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</BrowserRouter>
</SettingsContext.Provider>
</AuthContext.Provider>
);
}
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);