- PROJECT_STATUS added to documentStatus.ts (aktivni=info, dokonceny=success, zruseny=error — app convention); Projects/ProjectDetail local maps deleted; status Select derives its MenuItems from the shared map. - ProjectDetail linked-order status now rendered via the received-order map (was the project map with zero key overlap → raw DB token). - Cancelled label unified across received/issued orders in documentStatus.ts. - 'Chyba pripojeni' → 'Chyba připojení' (Dashboard, AuthContext). - Dashboard lazy-loaded like every other route — its 7 subcomponents leave the Login critical path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
277 lines
12 KiB
TypeScript
277 lines
12 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 AppShell from "./ui/AppShell";
|
|
import AlertContainer from "./components/AlertContainer";
|
|
import UpdateBanner from "./components/UpdateBanner";
|
|
import { lazyWithReload } from "./utils/lazyWithReload";
|
|
import MuiProvider from "./ui/MuiProvider";
|
|
import { LoadingState } from "./ui";
|
|
import Login from "./pages/Login";
|
|
|
|
const Dashboard = lazyWithReload(() => import("./pages/Dashboard"));
|
|
const Odin = lazyWithReload(() => import("./pages/Odin"));
|
|
const Users = lazyWithReload(() => import("./pages/Users"));
|
|
const Attendance = lazyWithReload(() => import("./pages/Attendance"));
|
|
const AttendanceHistory = lazyWithReload(
|
|
() => import("./pages/AttendanceHistory"),
|
|
);
|
|
const AttendanceAdmin = lazyWithReload(() => import("./pages/AttendanceAdmin"));
|
|
const AttendanceBalances = lazyWithReload(
|
|
() => import("./pages/AttendanceBalances"),
|
|
);
|
|
const AttendanceCreate = lazyWithReload(
|
|
() => import("./pages/AttendanceCreate"),
|
|
);
|
|
const LeaveRequests = lazyWithReload(() => import("./pages/LeaveRequests"));
|
|
const LeaveApproval = lazyWithReload(() => import("./pages/LeaveApproval"));
|
|
const AttendanceLocation = lazyWithReload(
|
|
() => import("./pages/AttendanceLocation"),
|
|
);
|
|
const PlanWork = lazyWithReload(() => import("./pages/PlanWork"));
|
|
const Trips = lazyWithReload(() => import("./pages/Trips"));
|
|
const TripsHistory = lazyWithReload(() => import("./pages/TripsHistory"));
|
|
const TripsAdmin = lazyWithReload(() => import("./pages/TripsAdmin"));
|
|
const Vehicles = lazyWithReload(() => import("./pages/Vehicles"));
|
|
const Offers = lazyWithReload(() => import("./pages/Offers"));
|
|
const OfferDetail = lazyWithReload(() => import("./pages/OfferDetail"));
|
|
const OffersCustomers = lazyWithReload(() => import("./pages/OffersCustomers"));
|
|
const OffersTemplates = lazyWithReload(() => import("./pages/OffersTemplates"));
|
|
const Orders = lazyWithReload(() => import("./pages/Orders"));
|
|
const OrderDetail = lazyWithReload(() => import("./pages/OrderDetail"));
|
|
const IssuedOrderDetail = lazyWithReload(
|
|
() => import("./pages/IssuedOrderDetail"),
|
|
);
|
|
const Projects = lazyWithReload(() => import("./pages/Projects"));
|
|
const ProjectDetail = lazyWithReload(() => import("./pages/ProjectDetail"));
|
|
const Invoices = lazyWithReload(() => import("./pages/Invoices"));
|
|
const InvoiceDetail = lazyWithReload(() => import("./pages/InvoiceDetail"));
|
|
const Settings = lazyWithReload(() => import("./pages/Settings"));
|
|
const AuditLog = lazyWithReload(() => import("./pages/AuditLog"));
|
|
const NotFound = lazyWithReload(() => import("./pages/NotFound"));
|
|
const Warehouse = lazyWithReload(() => import("./pages/Warehouse"));
|
|
const WarehouseItems = lazyWithReload(() => import("./pages/WarehouseItems"));
|
|
const WarehouseItemDetail = lazyWithReload(
|
|
() => import("./pages/WarehouseItemDetail"),
|
|
);
|
|
const WarehouseReceipts = lazyWithReload(
|
|
() => import("./pages/WarehouseReceipts"),
|
|
);
|
|
const WarehouseReceiptDetail = lazyWithReload(
|
|
() => import("./pages/WarehouseReceiptDetail"),
|
|
);
|
|
const WarehouseReceiptForm = lazyWithReload(
|
|
() => import("./pages/WarehouseReceiptForm"),
|
|
);
|
|
const WarehouseIssues = lazyWithReload(() => import("./pages/WarehouseIssues"));
|
|
const WarehouseIssueDetail = lazyWithReload(
|
|
() => import("./pages/WarehouseIssueDetail"),
|
|
);
|
|
const WarehouseIssueForm = lazyWithReload(
|
|
() => import("./pages/WarehouseIssueForm"),
|
|
);
|
|
const WarehouseReservations = lazyWithReload(
|
|
() => import("./pages/WarehouseReservations"),
|
|
);
|
|
const WarehouseInventory = lazyWithReload(
|
|
() => import("./pages/WarehouseInventory"),
|
|
);
|
|
const WarehouseInventoryDetail = lazyWithReload(
|
|
() => import("./pages/WarehouseInventoryDetail"),
|
|
);
|
|
const WarehouseInventoryForm = lazyWithReload(
|
|
() => import("./pages/WarehouseInventoryForm"),
|
|
);
|
|
const WarehouseReports = lazyWithReload(
|
|
() => import("./pages/WarehouseReports"),
|
|
);
|
|
const WarehouseSuppliers = lazyWithReload(
|
|
() => import("./pages/WarehouseSuppliers"),
|
|
);
|
|
const WarehouseLocations = lazyWithReload(
|
|
() => import("./pages/WarehouseLocations"),
|
|
);
|
|
const WarehouseCategories = lazyWithReload(
|
|
() => import("./pages/WarehouseCategories"),
|
|
);
|
|
const UiKit = import.meta.env.DEV ? lazy(() => import("./pages/UiKit")) : null;
|
|
|
|
export default function AdminApp() {
|
|
return (
|
|
<MuiProvider>
|
|
<AuthProvider>
|
|
<AlertProvider>
|
|
<QueryClientProvider client={queryClient}>
|
|
<AlertContainer />
|
|
<UpdateBanner />
|
|
<ErrorBoundary>
|
|
<Suspense fallback={<LoadingState />}>
|
|
<Routes>
|
|
<Route path="login" element={<Login />} />
|
|
{import.meta.env.DEV && UiKit && (
|
|
<Route path="ui-kit" element={<UiKit />} />
|
|
)}
|
|
{/*
|
|
Auth gating is delegated to <AppShell>: every authenticated
|
|
page is nested under this layout route, and AppShell
|
|
redirects to /login when there is no user (per-page
|
|
permission checks live in the pages themselves). NOTE: any
|
|
NEW top-level route added OUTSIDE this <AppShell> wrapper
|
|
(like `login`/`ui-kit` above) is PUBLIC by default — wrap it
|
|
in AppShell or add its own guard if it needs auth.
|
|
*/}
|
|
<Route element={<AppShell />}>
|
|
<Route index element={<Dashboard />} />
|
|
<Route path="odin" element={<Odin />} />
|
|
<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="plan-work" element={<PlanWork />} />
|
|
<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/issued/new"
|
|
element={<IssuedOrderDetail />}
|
|
/>
|
|
<Route
|
|
path="orders/issued/:id"
|
|
element={<IssuedOrderDetail />}
|
|
/>
|
|
<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 path="warehouse" element={<Warehouse />} />
|
|
<Route
|
|
path="warehouse/items"
|
|
element={<WarehouseItems />}
|
|
/>
|
|
<Route
|
|
path="warehouse/items/:id"
|
|
element={<WarehouseItemDetail />}
|
|
/>
|
|
<Route
|
|
path="warehouse/receipts"
|
|
element={<WarehouseReceipts />}
|
|
/>
|
|
<Route
|
|
path="warehouse/receipts/new"
|
|
element={<WarehouseReceiptForm />}
|
|
/>
|
|
<Route
|
|
path="warehouse/receipts/:id"
|
|
element={<WarehouseReceiptDetail />}
|
|
/>
|
|
<Route
|
|
path="warehouse/receipts/:id/edit"
|
|
element={<WarehouseReceiptForm />}
|
|
/>
|
|
<Route
|
|
path="warehouse/issues"
|
|
element={<WarehouseIssues />}
|
|
/>
|
|
<Route
|
|
path="warehouse/issues/new"
|
|
element={<WarehouseIssueForm />}
|
|
/>
|
|
<Route
|
|
path="warehouse/issues/:id"
|
|
element={<WarehouseIssueDetail />}
|
|
/>
|
|
<Route
|
|
path="warehouse/issues/:id/edit"
|
|
element={<WarehouseIssueForm />}
|
|
/>
|
|
<Route
|
|
path="warehouse/reservations"
|
|
element={<WarehouseReservations />}
|
|
/>
|
|
<Route
|
|
path="warehouse/inventory"
|
|
element={<WarehouseInventory />}
|
|
/>
|
|
<Route
|
|
path="warehouse/inventory/new"
|
|
element={<WarehouseInventoryForm />}
|
|
/>
|
|
<Route
|
|
path="warehouse/inventory/:id"
|
|
element={<WarehouseInventoryDetail />}
|
|
/>
|
|
<Route
|
|
path="warehouse/reports"
|
|
element={<WarehouseReports />}
|
|
/>
|
|
<Route
|
|
path="warehouse/suppliers"
|
|
element={<WarehouseSuppliers />}
|
|
/>
|
|
<Route
|
|
path="warehouse/locations"
|
|
element={<WarehouseLocations />}
|
|
/>
|
|
<Route
|
|
path="warehouse/categories"
|
|
element={<WarehouseCategories />}
|
|
/>
|
|
</Route>
|
|
<Route path="*" element={<NotFound />} />
|
|
</Routes>
|
|
</Suspense>
|
|
</ErrorBoundary>
|
|
</QueryClientProvider>
|
|
</AlertProvider>
|
|
</AuthProvider>
|
|
</MuiProvider>
|
|
);
|
|
}
|