PawTrace / frontend /src /App.tsx
Elliott Duke
PawTrace read-only demo: reid model + 1000-dog haystack
b5442b0
Raw
History Blame Contribute Delete
4.94 kB
import { Navigate, Route, Routes } from "react-router-dom";
import { useEffect, useState, type ReactNode } from "react";
import Layout from "./components/Layout";
import { useAuth } from "./auth";
import { api } from "./api";
import DemoApp from "./demo/DemoApp";
import Home from "./pages/Home";
import Login from "./pages/Login";
import Register from "./pages/Register";
import MyDogs from "./pages/MyDogs";
import DogDetail from "./pages/DogDetail";
import ReportLost from "./pages/ReportLost";
import ReportFound from "./pages/ReportFound";
import MyCases from "./pages/MyCases";
import CaseDetail from "./pages/CaseDetail";
import NextSteps from "./pages/NextSteps";
import Admin from "./pages/Admin";
import AdminData from "./pages/AdminData";
import AdminDogs from "./pages/AdminDogs";
import AdminCases from "./pages/AdminCases";
import AdminOwners from "./pages/AdminOwners";
import AdminOwnerDetail from "./pages/AdminOwnerDetail";
import AdminPending from "./pages/AdminPending";
import AdminTestMatch from "./pages/AdminTestMatch";
import DatasetDetail from "./pages/DatasetDetail";
function RequireAuth({ children }: { children: ReactNode }) {
const { user, loading } = useAuth();
if (loading) return <div className="p-8 text-center text-gray-500">Loading…</div>;
if (!user) return <Navigate to="/login" replace />;
return <>{children}</>;
}
export default function App() {
// On load, ask the backend which UI to render. DEMO_MODE=1 -> the read-only 3-page demo shell;
// otherwise the full app. (The backend also hard-blocks writes in demo mode — this is just the UI.)
const [config, setConfig] = useState<{ demo_mode: boolean; haystack_size: number } | null>(null);
useEffect(() => {
api
.getConfig()
.then(setConfig)
.catch(() => setConfig({ demo_mode: false, haystack_size: 0 }));
}, []);
if (config === null) return <div className="p-8 text-center text-gray-500">Loading…</div>;
if (config.demo_mode) return <DemoApp haystackSize={config.haystack_size} />;
return (
<Layout>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/report/found" element={<ReportFound />} />
<Route
path="/dogs"
element={
<RequireAuth>
<MyDogs />
</RequireAuth>
}
/>
<Route
path="/dogs/:id"
element={
<RequireAuth>
<DogDetail />
</RequireAuth>
}
/>
<Route
path="/report/lost"
element={
<RequireAuth>
<ReportLost />
</RequireAuth>
}
/>
<Route
path="/cases"
element={
<RequireAuth>
<MyCases />
</RequireAuth>
}
/>
<Route
path="/cases/:id"
element={
<RequireAuth>
<CaseDetail />
</RequireAuth>
}
/>
<Route
path="/matches/:id/reclaim"
element={
<RequireAuth>
<NextSteps />
</RequireAuth>
}
/>
<Route
path="/admin"
element={
<RequireAuth>
<Admin />
</RequireAuth>
}
/>
<Route
path="/admin/data"
element={
<RequireAuth>
<AdminData />
</RequireAuth>
}
/>
<Route
path="/admin/dogs"
element={
<RequireAuth>
<AdminDogs />
</RequireAuth>
}
/>
<Route
path="/admin/pending"
element={
<RequireAuth>
<AdminPending />
</RequireAuth>
}
/>
<Route
path="/admin/cases"
element={
<RequireAuth>
<AdminCases />
</RequireAuth>
}
/>
<Route
path="/admin/owners"
element={
<RequireAuth>
<AdminOwners />
</RequireAuth>
}
/>
<Route
path="/admin/owners/:id"
element={
<RequireAuth>
<AdminOwnerDetail />
</RequireAuth>
}
/>
<Route
path="/admin/test-match"
element={
<RequireAuth>
<AdminTestMatch />
</RequireAuth>
}
/>
<Route
path="/admin/data/:id"
element={
<RequireAuth>
<DatasetDetail />
</RequireAuth>
}
/>
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Layout>
);
}