Files
edr-platform/apps/edr-freight-web/backoffice/src/pages/invoices/FinanceHubPage.tsx
Marshal 1ca7776143 Enhance manual payment processing for USD and ETB invoices
- Updated API documentation and summaries to reflect support for both USD and ETB invoices.
- Modified data structures to include trade direction for invoices.
- Adjusted UI components to accommodate manual payment confirmations and display relevant information.
- Implemented filtering options for currency in the manual payments worklist.
2026-08-17 09:13:09 +00:00

95 lines
2.9 KiB
TypeScript

import { Tabs } from "@mantine/core";
import { Landmark, Receipt } from "lucide-react";
import { useSearchParams } from "react-router-dom";
import { useAuth } from "@/auth/useAuth";
import { PageContainer, PageHeader } from "@/components/page";
import { FREIGHT_PERMS, hasPermission } from "@/lib/permissions";
import InvoicesPanel from "./InvoicesPage";
import UsdPaymentsPanel from "./UsdPaymentsPage";
/**
* Invoices and USD Payments used to be separate routes/pages with
* near-identical chrome. They're merged here as URL-linkable tabs (`?tab=`)
* on one page — each tab keeps the permission it was individually gated on
* before, and just doesn't render if the user lacks it.
*
* The Payments tab was removed; its summary (total collected, ETB/USD) now
* lives as a card at the top of the Invoices tab instead.
*/
const TABS = [
{
key: "invoices",
label: "Invoices",
icon: Receipt,
permission: FREIGHT_PERMS.invoices.view,
subtitle:
"Every invoice issued across bookings, warehouse fees and clearance charges.",
Panel: InvoicesPanel,
},
{
key: "manual-payments",
label: "Manual Payments",
icon: Landmark,
// Same gate as Invoices, not a dedicated key — mirrors the old route.
permission: FREIGHT_PERMS.invoices.view,
subtitle:
"Import and export invoices in USD or ETB that Finance settles by hand (bank transfer or counter). Upload the customer's slip and confirm the payment before the pay window closes.",
Panel: UsdPaymentsPanel,
},
] as const;
type TabKey = (typeof TABS)[number]["key"];
export default function FinanceHubPage() {
const { user } = useAuth();
const [searchParams, setSearchParams] = useSearchParams();
const visibleTabs = TABS.filter((tab) => hasPermission(user, tab.permission));
const requested = searchParams.get("tab");
const active: TabKey =
visibleTabs.find((tab) => tab.key === requested)?.key ??
visibleTabs[0]?.key ??
"invoices";
const activeTab = visibleTabs.find((tab) => tab.key === active);
const handleChange = (value: string | null) => {
if (!value) return;
setSearchParams(
(prev) => {
const next = new URLSearchParams(prev);
next.set("tab", value);
return next;
},
{ replace: true },
);
};
return (
<PageContainer>
<PageHeader title={activeTab?.label ?? "Invoices"} subtitle={activeTab?.subtitle} />
<Tabs value={active} onChange={handleChange} keepMounted={false}>
<Tabs.List>
{visibleTabs.map((tab) => (
<Tabs.Tab
key={tab.key}
value={tab.key}
leftSection={<tab.icon size={16} />}
>
{tab.label}
</Tabs.Tab>
))}
</Tabs.List>
{visibleTabs.map((tab) => (
<Tabs.Panel key={tab.key} value={tab.key} pt="lg">
<tab.Panel />
</Tabs.Panel>
))}
</Tabs>
</PageContainer>
);
}