db8e86b749
FMs move to a separate application. Drops Fm/FmPart tables + Repair.fmId column, deletes FM_OPENED/FM_CLOSED PartEvent rows, strips FM enums + webhook events + shared contracts, removes FM routes/services/pages/UI, and collapses dashboard admin ops to Repairs 7d/30d + trend + custody backlog. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
101 lines
4.1 KiB
TypeScript
101 lines
4.1 KiB
TypeScript
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
|
|
import { NuqsAdapter } from 'nuqs/adapters/react-router/v7';
|
|
import { TooltipProvider, Toaster } from '@vector/ui';
|
|
import { AuthProvider } from './contexts/AuthContext.js';
|
|
import { RequireAuth } from './components/auth/RequireAuth.js';
|
|
import { AppShell } from './components/layout/AppShell.js';
|
|
import { ErrorBoundary } from './components/layout/ErrorBoundary.js';
|
|
import Login from './pages/Login.js';
|
|
import Dashboard from './pages/Dashboard.js';
|
|
import Parts from './pages/Parts.js';
|
|
import PartDetail from './pages/PartDetail.js';
|
|
import Locations from './pages/Locations.js';
|
|
import BinDetail from './pages/BinDetail.js';
|
|
import Manufacturers from './pages/Manufacturers.js';
|
|
import ManufacturerDetail from './pages/ManufacturerDetail.js';
|
|
import PartModels from './pages/PartModels.js';
|
|
import PartModelDetail from './pages/PartModelDetail.js';
|
|
import CategoryDetail from './pages/CategoryDetail.js';
|
|
import Repairs from './pages/Repairs.js';
|
|
import MyCustody from './pages/MyCustody.js';
|
|
import Hosts from './pages/Hosts.js';
|
|
import HostDetail from './pages/HostDetail.js';
|
|
import Users from './pages/admin/Users.js';
|
|
import Webhooks from './pages/admin/Webhooks.js';
|
|
|
|
const queryClient = new QueryClient({
|
|
defaultOptions: {
|
|
queries: {
|
|
retry: (failureCount, error) => {
|
|
// Don't retry auth failures — the refresh interceptor handles those once already.
|
|
const status = (error as { status?: number })?.status;
|
|
if (status === 401 || status === 403) return false;
|
|
return failureCount < 2;
|
|
},
|
|
staleTime: 10_000,
|
|
refetchOnWindowFocus: false,
|
|
},
|
|
},
|
|
});
|
|
|
|
export default function App() {
|
|
return (
|
|
<ErrorBoundary>
|
|
<QueryClientProvider client={queryClient}>
|
|
<BrowserRouter>
|
|
<NuqsAdapter>
|
|
<AuthProvider>
|
|
<TooltipProvider delayDuration={150}>
|
|
<Routes>
|
|
<Route path="/login" element={<Login />} />
|
|
<Route
|
|
element={
|
|
<RequireAuth>
|
|
<AppShell />
|
|
</RequireAuth>
|
|
}
|
|
>
|
|
<Route path="/" element={<Dashboard />} />
|
|
<Route path="/parts" element={<Parts />} />
|
|
<Route path="/parts/:id" element={<PartDetail />} />
|
|
<Route path="/locations" element={<Locations />} />
|
|
<Route path="/bins/:id" element={<BinDetail />} />
|
|
<Route path="/manufacturers" element={<Manufacturers />} />
|
|
<Route path="/manufacturers/:id" element={<ManufacturerDetail />} />
|
|
<Route path="/part-models" element={<PartModels />} />
|
|
<Route path="/part-models/:id" element={<PartModelDetail />} />
|
|
<Route path="/categories/:id" element={<CategoryDetail />} />
|
|
<Route path="/repairs" element={<Repairs />} />
|
|
<Route path="/custody" element={<MyCustody />} />
|
|
<Route path="/hosts" element={<Hosts />} />
|
|
<Route path="/hosts/:id" element={<HostDetail />} />
|
|
<Route
|
|
path="/admin/users"
|
|
element={
|
|
<RequireAuth role="ADMIN">
|
|
<Users />
|
|
</RequireAuth>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/webhooks"
|
|
element={
|
|
<RequireAuth role="ADMIN">
|
|
<Webhooks />
|
|
</RequireAuth>
|
|
}
|
|
/>
|
|
</Route>
|
|
<Route path="*" element={<Navigate to="/" replace />} />
|
|
</Routes>
|
|
<Toaster position="bottom-right" />
|
|
</TooltipProvider>
|
|
</AuthProvider>
|
|
</NuqsAdapter>
|
|
</BrowserRouter>
|
|
</QueryClientProvider>
|
|
</ErrorBoundary>
|
|
);
|
|
}
|