mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 22:18:12 +00:00
Merge branch 'dev'
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useEffect } from "react";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
Navigate,
|
||||
Outlet,
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
} from "react-router-dom";
|
||||
|
||||
import { FreightDashboardLayout, type SidebarItem } from "@/components/layout";
|
||||
import { api } from "@/services/api";
|
||||
import { useAuth } from "./auth/useAuth";
|
||||
import LoadingScreen from "./components/LoadingScreen";
|
||||
import LoginPage from "./pages/auth/LoginPage";
|
||||
@@ -36,15 +38,13 @@ import CustomerDetailPage from "./pages/customers/CustomerDetailPage";
|
||||
import CustomersPage from "./pages/customers/CustomersPage";
|
||||
import ShippingLineCompaniesPage from "./pages/shipping-lines/ShippingLineCompaniesPage";
|
||||
import InvoiceDetailPage from "./pages/invoices/InvoiceDetailPage";
|
||||
import InvoicesPage from "./pages/invoices/InvoicesPage";
|
||||
import UsdPaymentsPage from "./pages/invoices/UsdPaymentsPage";
|
||||
import FinanceHubPage from "./pages/invoices/FinanceHubPage";
|
||||
import MyProfilePage from "./pages/dashboard/MyProfilePage";
|
||||
import OverviewPage from "./pages/dashboard/OverviewPage";
|
||||
import ReportsHubPage from "./pages/reports/ReportsHubPage";
|
||||
import ReportsIndexRedirect from "./pages/reports/ReportsIndexRedirect";
|
||||
import ReportPage from "./pages/reports/ReportPage";
|
||||
import AuditLogsPage from "./pages/AuditLogsPage";
|
||||
import AiBookingMockTestPage from "./pages/ai/AiBookingMockTestPage";
|
||||
import PaymentsPage from "./pages/payments/PaymentsPage";
|
||||
//import EmployeesPage from "./pages/dashboard/user-management/EmployeesPage";
|
||||
import { RequirePermission } from "./components/auth/RequirePermission";
|
||||
import { FREIGHT_PERMS } from "./lib/permissions";
|
||||
@@ -53,6 +53,7 @@ import NoAccessPage from "./pages/NoAccessPage";
|
||||
import FileUploadSettingsPage from "./pages/documents/FileUploadSettingsPage";
|
||||
import DropdownSettingsPage from "./pages/dropdown_settings/DropdownSettingsPage";
|
||||
import CompanyStampSettingsPage from "./pages/settings/CompanyStampSettingsPage";
|
||||
import LogoSettingsPage from "./pages/settings/LogoSettingsPage";
|
||||
import ContractTemplatesPage from "./pages/contract_templates/ContractTemplatesPage";
|
||||
import PortalContentPage from "./pages/portal_content/PortalContentPage";
|
||||
import ContractTemplateEditorPage from "./pages/contract_templates/ContractTemplateEditorPage";
|
||||
@@ -82,7 +83,6 @@ import TrainScheduleTrackPage from "./pages/trainScheduling/TrainScheduleTrackPa
|
||||
import TrainSchedulingGlobalRulesPage from "./pages/trainScheduling/TrainSchedulingGlobalRulesPage";
|
||||
import TradeAccessPage from "./pages/configuration/TradeAccessPage";
|
||||
import ExchangeRateSettingsCard from "./pages/settings/ExchangeRateSettingsCard";
|
||||
import ContractValidityPeriodsPage from "./pages/configuration/ContractValidityPeriodsPage";
|
||||
import FirstMilePage from "./pages/operations/FirstMilePage";
|
||||
import LastMilePage from "./pages/operations/LastMilePage";
|
||||
import TrainDetailPage from "./pages/trains/TrainDetailPage";
|
||||
@@ -140,8 +140,18 @@ const DashboardShell = () => {
|
||||
|
||||
const demoItems: SidebarItem[] = [];
|
||||
|
||||
const { data: reportCatalog } = useQuery(api.reports.catalog.queryOptions());
|
||||
const reportItems: SidebarItem[] = useMemo(
|
||||
() =>
|
||||
(reportCatalog ?? []).map((report) => ({
|
||||
label: report.title,
|
||||
href: `/dashboard/reports/${report.key}`,
|
||||
})),
|
||||
[reportCatalog],
|
||||
);
|
||||
|
||||
const sidebarSections = filterSidebarByPermission(
|
||||
buildSidebarSections(demoItems),
|
||||
buildSidebarSections(demoItems, reportItems),
|
||||
user,
|
||||
);
|
||||
const displayName = user?.name?.en || user?.username || user?.email || "User";
|
||||
@@ -200,12 +210,43 @@ const App = () => {
|
||||
{/* Landing is per-user: /dashboard/overview is gated on overview:view, so
|
||||
a fixed target strands anyone without that key on a blank page. */}
|
||||
<Route path="/" element={<Navigate to={landingPath} replace />} />
|
||||
<Route path="/dashboard" element={<Navigate to={landingPath} replace />} />
|
||||
<Route
|
||||
path="/dashboard"
|
||||
element={<Navigate to={landingPath} replace />}
|
||||
/>
|
||||
<Route path="/dashboard" element={<DashboardShell />}>
|
||||
<Route path="overview" element={<RequirePermission permission={FREIGHT_PERMS.overview.view}><OverviewPage /></RequirePermission>} />
|
||||
<Route path="reports" element={<RequirePermission permission={FREIGHT_PERMS.reports.view}><ReportsHubPage /></RequirePermission>} />
|
||||
<Route path="reports/:reportKey" element={<RequirePermission permission={FREIGHT_PERMS.reports.view}><ReportPage /></RequirePermission>} />
|
||||
<Route path="audit-logs" element={<RequirePermission permission={FREIGHT_PERMS.auditLog.view}><AuditLogsPage /></RequirePermission>} />
|
||||
<Route
|
||||
path="overview"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.overview.view}>
|
||||
<OverviewPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="reports"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.reports.view}>
|
||||
<ReportsIndexRedirect />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="reports/:reportKey"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.reports.view}>
|
||||
<ReportPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="audit-logs"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.auditLog.view}>
|
||||
<AuditLogsPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
{/* Dev/testing page for the mock AI booking assistant. */}
|
||||
<Route
|
||||
path="ai-booking-mock-test"
|
||||
@@ -217,16 +258,28 @@ const App = () => {
|
||||
/>
|
||||
<Route path="profile" element={<MyProfilePage />} />
|
||||
|
||||
<Route path="booking-requests" element={<RequirePermission permission={FREIGHT_PERMS.bookings.view}><BookingRequestsPage /></RequirePermission>} />
|
||||
<Route
|
||||
path="payments"
|
||||
path="booking-requests"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.payments.view}>
|
||||
<PaymentsPage />
|
||||
<RequirePermission permission={FREIGHT_PERMS.bookings.view}>
|
||||
<BookingRequestsPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
{/* Payments used to be its own page; it's now the "payments" tab on
|
||||
the merged Invoices hub. Old bookmarks/links still land there. */}
|
||||
<Route
|
||||
path="payments"
|
||||
element={<Navigate to="/dashboard/invoices?tab=payments" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="support"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.support.agentView}>
|
||||
<SupportInboxPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route path="support" element={<RequirePermission permission={FREIGHT_PERMS.support.agentView}><SupportInboxPage /></RequirePermission>} />
|
||||
<Route
|
||||
path="customers"
|
||||
element={
|
||||
@@ -243,6 +296,11 @@ const App = () => {
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
{/* Merged Invoices / Payments / USD Payments hub — tabs switch via
|
||||
?tab=invoices|payments|usd-payments (default invoices). Access is
|
||||
OR'd across both keys so a user with just one still gets in; each
|
||||
tab hides itself if the user lacks the permission it used to be
|
||||
routed on. */}
|
||||
<Route
|
||||
path="shipping-lines"
|
||||
element={
|
||||
@@ -254,18 +312,19 @@ const App = () => {
|
||||
<Route
|
||||
path="invoices"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.invoices.view}>
|
||||
<InvoicesPage />
|
||||
<RequirePermission
|
||||
permission={[
|
||||
FREIGHT_PERMS.invoices.view,
|
||||
FREIGHT_PERMS.payments.view,
|
||||
]}
|
||||
>
|
||||
<FinanceHubPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="usd-payments"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.invoices.view}>
|
||||
<UsdPaymentsPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
element={<Navigate to="/dashboard/invoices?tab=usd-payments" replace />}
|
||||
/>
|
||||
<Route
|
||||
path="invoices/:id"
|
||||
@@ -275,7 +334,14 @@ const App = () => {
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route path="booking-requests/new" element={<RequirePermission permission={FREIGHT_PERMS.bookings.view}><NewBookingPage /></RequirePermission>} />
|
||||
<Route
|
||||
path="booking-requests/new"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.bookings.view}>
|
||||
<NewBookingPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="wagon-cancellations"
|
||||
element={
|
||||
@@ -484,25 +550,195 @@ const App = () => {
|
||||
path="bookings/:id/milestones"
|
||||
element={<BookingMilestonesRedirect />}
|
||||
/>
|
||||
<Route path="warehouses" element={<RequirePermission permission={FREIGHT_PERMS.warehouses.view}><WarehouseListPage /></RequirePermission>} />
|
||||
<Route path="warehouses/:id" element={<RequirePermission permission={FREIGHT_PERMS.warehouses.view}><WarehouseDetailPage /></RequirePermission>} />
|
||||
<Route path="warehouse-inventory" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><WarehouseInventoryPage /></RequirePermission>} />
|
||||
<Route path="import-warehouse" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><ImportWarehouseFlowPage /></RequirePermission>} />
|
||||
<Route path="export-warehouse" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><ExportWarehouseFlowPage /></RequirePermission>} />
|
||||
<Route path="arrival-queue" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><ArrivalQueuePage /></RequirePermission>} />
|
||||
<Route path="loading-queue" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><LoadingQueuePage /></RequirePermission>} />
|
||||
<Route path="intercity" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><IntercityPage /></RequirePermission>} />
|
||||
<Route path="trucks-on-site" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><TrucksOnSitePage /></RequirePermission>} />
|
||||
<Route path="import-trucks" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><ImportTrucksPage /></RequirePermission>} />
|
||||
<Route path="container-returns" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><ContainerReturnsPage /></RequirePermission>} />
|
||||
<Route path="loaded-inventory" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><LoadedInventoryPage /></RequirePermission>} />
|
||||
<Route path="dispatch-queue" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><DispatchQueuePage /></RequirePermission>} />
|
||||
<Route path="export-djibouti-unloading" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><ExportDjiboutiUnloadingQueuePage /></RequirePermission>} />
|
||||
<Route path="interchange-documents" element={<RequirePermission permission={FREIGHT_PERMS.interchangeDocuments.view}><InterchangeDocumentsPage /></RequirePermission>} />
|
||||
<Route path="inventory-inquiry" element={<RequirePermission permission={FREIGHT_PERMS.warehouseInventory.view}><InventoryInquiryPage /></RequirePermission>} />
|
||||
<Route path="warehouse-rules" element={<RequirePermission permission={[FREIGHT_PERMS.warehouseAllocationRules.view, FREIGHT_PERMS.warehouseFeeRules.view]}><WarehouseRulesPage /></RequirePermission>} />
|
||||
<Route path="warehouse-fee-invoices" element={<RequirePermission permission={FREIGHT_PERMS.warehouseFeeInvoices.view}><WarehouseInvoicesPage /></RequirePermission>} />
|
||||
<Route path="warehouse-dashboard" element={<RequirePermission permission={FREIGHT_PERMS.warehouseDashboard.view}><WarehouseDashboardPage /></RequirePermission>} />
|
||||
<Route
|
||||
path="warehouses"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.warehouses.view}>
|
||||
<WarehouseListPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="warehouses/:id"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.warehouses.view}>
|
||||
<WarehouseDetailPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse-inventory"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<WarehouseInventoryPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="import-warehouse"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<ImportWarehouseFlowPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="export-warehouse"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<ExportWarehouseFlowPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="arrival-queue"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<ArrivalQueuePage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="loading-queue"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<LoadingQueuePage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="intercity"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<IntercityPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="trucks-on-site"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<TrucksOnSitePage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="import-trucks"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<ImportTrucksPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="container-returns"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<ContainerReturnsPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="loaded-inventory"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<LoadedInventoryPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="dispatch-queue"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<DispatchQueuePage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="export-djibouti-unloading"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<ExportDjiboutiUnloadingQueuePage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="interchange-documents"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.interchangeDocuments.view}
|
||||
>
|
||||
<InterchangeDocumentsPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="inventory-inquiry"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseInventory.view}
|
||||
>
|
||||
<InventoryInquiryPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse-rules"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={[
|
||||
FREIGHT_PERMS.warehouseAllocationRules.view,
|
||||
FREIGHT_PERMS.warehouseFeeRules.view,
|
||||
]}
|
||||
>
|
||||
<WarehouseRulesPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse-fee-invoices"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseFeeInvoices.view}
|
||||
>
|
||||
<WarehouseInvoicesPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse-dashboard"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.warehouseDashboard.view}
|
||||
>
|
||||
<WarehouseDashboardPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="operations/train-scheduling"
|
||||
@@ -781,7 +1017,9 @@ const App = () => {
|
||||
<Route
|
||||
path="file-settings"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.settings.fileUpload.view}>
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.settings.fileUpload.view}
|
||||
>
|
||||
<FileUploadSettingsPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
@@ -789,7 +1027,9 @@ const App = () => {
|
||||
<Route
|
||||
path="dropdown-settings"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.settings.dropdown.view}>
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.settings.dropdown.view}
|
||||
>
|
||||
<DropdownSettingsPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
@@ -804,9 +1044,7 @@ const App = () => {
|
||||
<Route
|
||||
path="stamp-settings"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.settings.stamp.view}
|
||||
>
|
||||
<RequirePermission permission={FREIGHT_PERMS.settings.stamp.view}>
|
||||
<CompanyStampSettingsPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
@@ -816,6 +1054,15 @@ const App = () => {
|
||||
path="invoice-stamp-settings"
|
||||
element={<Navigate to="/dashboard/stamp-settings" replace />}
|
||||
/>
|
||||
{/* The ONE company logo, shown in the header of every generated document. */}
|
||||
<Route
|
||||
path="logo-settings"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.settings.logo.view}>
|
||||
<LogoSettingsPage />
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="contract-templates"
|
||||
element={
|
||||
@@ -875,7 +1122,9 @@ const App = () => {
|
||||
<Route
|
||||
path="configuration/exchange-rate"
|
||||
element={
|
||||
<RequirePermission permission={FREIGHT_PERMS.settings.exchangeRate.view}>
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.settings.exchangeRate.view}
|
||||
>
|
||||
<div className="p-4">
|
||||
<ExchangeRateSettingsCard />
|
||||
</div>
|
||||
@@ -943,4 +1192,3 @@ function LegacyGlEthiopiaClearanceRedirect() {
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user