- Replace hand-coded skeleton CSS/JSX with boneyard-js auto-generated bones - Remove skeleton.css and @keyframes shimmer from base.css - Add <Skeleton> wrappers with fixtures to all 25+ page components - Generate 20 bone captures via boneyard CLI (CDP auth-gated capture) - Refactor data fetching from useEffect+useState to TanStack Query - Extract query hooks into src/admin/lib/queries/ and apiAdapter - Add usePaginatedQuery hook replacing useApiCall/useListData - Fix parseFloat || 0 anti-pattern in OfferDetail and OffersTemplates inputs - Fix customer_id mandatory validation on offer creation - Fix leave-requests comma-separated status filter (Prisma enum in: []) - Add cross-entity cache invalidation for orders/offers/invoices/projects - Make rate limits configurable via env vars (RATE_LIMIT_MAX, RATE_LIMIT_REFRESH, etc.) - Add boneyard.config.json with routes and breakpoints Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
140 lines
5.9 KiB
TypeScript
140 lines
5.9 KiB
TypeScript
import { lazy, Suspense } from "react";
|
|
import { Routes, Route } from "react-router-dom";
|
|
import { QueryClientProvider } from "@tanstack/react-query";
|
|
import { AuthProvider } from "./context/AuthContext";
|
|
import { AlertProvider } from "./context/AlertContext";
|
|
import { queryClient } from "./lib/queryClient";
|
|
import ErrorBoundary from "./components/ErrorBoundary";
|
|
import AdminLayout from "./components/AdminLayout";
|
|
import AlertContainer from "./components/AlertContainer";
|
|
import Login from "./pages/Login";
|
|
import Dashboard from "./pages/Dashboard";
|
|
import "./variables.css";
|
|
import "./base.css";
|
|
import "./forms.css";
|
|
import "./buttons.css";
|
|
import "./layout.css";
|
|
import "./components.css";
|
|
import "./tables.css";
|
|
import "./datepicker.css";
|
|
import "./bones/registry";
|
|
import "./filemanager.css";
|
|
import "./pagination.css";
|
|
import "./responsive.css";
|
|
import "./login.css";
|
|
import "./dashboard.css";
|
|
import "./attendance.css";
|
|
import "./settings.css";
|
|
import "./offers.css";
|
|
import "./invoices.css";
|
|
|
|
const Users = lazy(() => import("./pages/Users"));
|
|
const Attendance = lazy(() => import("./pages/Attendance"));
|
|
const AttendanceHistory = lazy(() => import("./pages/AttendanceHistory"));
|
|
const AttendanceAdmin = lazy(() => import("./pages/AttendanceAdmin"));
|
|
const AttendanceBalances = lazy(() => import("./pages/AttendanceBalances"));
|
|
const AttendanceCreate = lazy(() => import("./pages/AttendanceCreate"));
|
|
const LeaveRequests = lazy(() => import("./pages/LeaveRequests"));
|
|
const LeaveApproval = lazy(() => import("./pages/LeaveApproval"));
|
|
const AttendanceLocation = lazy(() => import("./pages/AttendanceLocation"));
|
|
const Trips = lazy(() => import("./pages/Trips"));
|
|
const TripsHistory = lazy(() => import("./pages/TripsHistory"));
|
|
const TripsAdmin = lazy(() => import("./pages/TripsAdmin"));
|
|
const Vehicles = lazy(() => import("./pages/Vehicles"));
|
|
const Offers = lazy(() => import("./pages/Offers"));
|
|
const OfferDetail = lazy(() => import("./pages/OfferDetail"));
|
|
const OffersCustomers = lazy(() => import("./pages/OffersCustomers"));
|
|
const OffersTemplates = lazy(() => import("./pages/OffersTemplates"));
|
|
const Orders = lazy(() => import("./pages/Orders"));
|
|
const OrderDetail = lazy(() => import("./pages/OrderDetail"));
|
|
const Projects = lazy(() => import("./pages/Projects"));
|
|
const ProjectDetail = lazy(() => import("./pages/ProjectDetail"));
|
|
const Invoices = lazy(() => import("./pages/Invoices"));
|
|
const InvoiceDetail = lazy(() => import("./pages/InvoiceDetail"));
|
|
const Settings = lazy(() => import("./pages/Settings"));
|
|
const AuditLog = lazy(() => import("./pages/AuditLog"));
|
|
const NotFound = lazy(() => import("./pages/NotFound"));
|
|
|
|
export default function AdminApp() {
|
|
return (
|
|
<AuthProvider>
|
|
<AlertProvider>
|
|
<QueryClientProvider client={queryClient}>
|
|
<AlertContainer />
|
|
<ErrorBoundary>
|
|
<Suspense
|
|
fallback={
|
|
<div className="admin-loading">
|
|
<div className="admin-spinner" />
|
|
</div>
|
|
}
|
|
>
|
|
<Routes>
|
|
<Route path="login" element={<Login />} />
|
|
<Route element={<AdminLayout />}>
|
|
<Route index element={<Dashboard />} />
|
|
<Route path="users" element={<Users />} />
|
|
<Route path="attendance" element={<Attendance />} />
|
|
<Route
|
|
path="attendance/history"
|
|
element={<AttendanceHistory />}
|
|
/>
|
|
<Route
|
|
path="attendance/admin"
|
|
element={<AttendanceAdmin />}
|
|
/>
|
|
<Route
|
|
path="attendance/balances"
|
|
element={<AttendanceBalances />}
|
|
/>
|
|
<Route
|
|
path="attendance/requests"
|
|
element={<LeaveRequests />}
|
|
/>
|
|
<Route
|
|
path="attendance/approval"
|
|
element={<LeaveApproval />}
|
|
/>
|
|
<Route
|
|
path="attendance/create"
|
|
element={<AttendanceCreate />}
|
|
/>
|
|
<Route
|
|
path="attendance/location/:id"
|
|
element={<AttendanceLocation />}
|
|
/>
|
|
<Route path="trips" element={<Trips />} />
|
|
<Route path="trips/history" element={<TripsHistory />} />
|
|
<Route path="trips/admin" element={<TripsAdmin />} />
|
|
<Route path="vehicles" element={<Vehicles />} />
|
|
<Route path="offers" element={<Offers />} />
|
|
<Route path="offers/new" element={<OfferDetail />} />
|
|
<Route path="offers/:id" element={<OfferDetail />} />
|
|
<Route
|
|
path="offers/customers"
|
|
element={<OffersCustomers />}
|
|
/>
|
|
<Route
|
|
path="offers/templates"
|
|
element={<OffersTemplates />}
|
|
/>
|
|
<Route path="orders" element={<Orders />} />
|
|
<Route path="orders/:id" element={<OrderDetail />} />
|
|
<Route path="projects" element={<Projects />} />
|
|
<Route path="projects/:id" element={<ProjectDetail />} />
|
|
<Route path="invoices" element={<Invoices />} />
|
|
<Route path="invoices/new" element={<InvoiceDetail />} />
|
|
<Route path="invoices/:id" element={<InvoiceDetail />} />
|
|
<Route path="settings" element={<Settings />} />
|
|
<Route path="audit-log" element={<AuditLog />} />
|
|
</Route>
|
|
<Route path="*" element={<NotFound />} />
|
|
</Routes>
|
|
</Suspense>
|
|
</ErrorBoundary>
|
|
</QueryClientProvider>
|
|
</AlertProvider>
|
|
</AuthProvider>
|
|
);
|
|
}
|