mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
133 lines
4.7 KiB
TypeScript
133 lines
4.7 KiB
TypeScript
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "@/shared/common/ui/card";
|
|
import { Badge } from "@/shared/common/ui/badge";
|
|
import { Switch } from "@/shared/common/ui/switch";
|
|
import { Skeleton } from "@/shared/common/ui/skeleton";
|
|
import { AlertTriangle, Banknote, Landmark } from "lucide-react";
|
|
|
|
import { useAuth } from "@/auth/useAuth";
|
|
import { FREIGHT_PERMS, hasPermission } from "@/lib/permissions";
|
|
import {
|
|
useManualPaymentSettingsQuery,
|
|
useUpdateManualPaymentSettings,
|
|
} from "@/hooks/useManualPaymentSettings";
|
|
|
|
type Currency = "ETB" | "USD";
|
|
|
|
const CURRENCIES: {
|
|
code: Currency;
|
|
field: "etbEnabled" | "usdEnabled";
|
|
icon: typeof Banknote;
|
|
title: string;
|
|
description: string;
|
|
}[] = [
|
|
{
|
|
code: "ETB",
|
|
field: "etbEnabled",
|
|
icon: Banknote,
|
|
title: "Birr (ETB) invoices",
|
|
description:
|
|
"ETB invoices are normally paid online by the customer. Switch this on when Finance also needs to settle them by hand — a bank transfer or a payment at the counter.",
|
|
},
|
|
{
|
|
code: "USD",
|
|
field: "usdEnabled",
|
|
icon: Landmark,
|
|
title: "Dollar (USD) invoices",
|
|
description:
|
|
"USD invoices are paid by bank transfer and have no online channel. Switching this off leaves USD customers with no way to be marked as paid.",
|
|
},
|
|
];
|
|
|
|
/**
|
|
* Switches the manual (offline) payment channel on or off per currency.
|
|
*
|
|
* Off means gone, not greyed out: the Manual Payments worklist lists only
|
|
* enabled currencies, and the API refuses a confirmation in a disabled one —
|
|
* so a stale tab or a direct call cannot slip a payment through.
|
|
*/
|
|
export default function ManualPaymentSettingsCard() {
|
|
const { user } = useAuth();
|
|
const canManage =
|
|
hasPermission(user, FREIGHT_PERMS.settings.manualPayment.manage) ||
|
|
hasPermission(user, FREIGHT_PERMS.admin);
|
|
|
|
const { data, isLoading } = useManualPaymentSettingsQuery();
|
|
const update = useUpdateManualPaymentSettings();
|
|
|
|
const noneEnabled = Boolean(data && !data.etbEnabled && !data.usdEnabled);
|
|
|
|
return (
|
|
<Card className="shadow-lg border-gray-200 dark:border-gray-700">
|
|
<CardHeader>
|
|
<CardTitle>Manual payments</CardTitle>
|
|
<CardDescription>
|
|
Whether Finance staff may mark invoices as paid by hand, from
|
|
Invoices → Manual Payments. Each currency is switched separately.
|
|
Confirming still requires the payment slip and the booking's pay
|
|
window to be open.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
|
|
<CardContent className="space-y-4">
|
|
{noneEnabled && (
|
|
<div className="flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-100">
|
|
<AlertTriangle className="mt-0.5 h-4 w-4 shrink-0" />
|
|
<p>
|
|
Both currencies are off — the Manual Payments list is empty and
|
|
Finance cannot settle any invoice by hand.
|
|
</p>
|
|
</div>
|
|
)}
|
|
|
|
{isLoading || !data
|
|
? CURRENCIES.map((c) => (
|
|
<Skeleton key={c.code} className="h-[86px] w-full rounded-md" />
|
|
))
|
|
: CURRENCIES.map(({ code, field, icon: Icon, title, description }) => {
|
|
const enabled = data[field];
|
|
return (
|
|
<div
|
|
key={code}
|
|
className="flex items-start justify-between gap-4 rounded-md border p-4 dark:border-gray-700"
|
|
>
|
|
<div className="space-y-1">
|
|
<div className="flex items-center gap-2">
|
|
<Icon className="h-4 w-4 text-muted-foreground" />
|
|
<p className="font-medium">{title}</p>
|
|
<Badge variant={enabled ? "default" : "secondary"}>
|
|
{enabled ? "Enabled" : "Disabled"}
|
|
</Badge>
|
|
</div>
|
|
<p className="text-sm text-muted-foreground">
|
|
{description}
|
|
</p>
|
|
</div>
|
|
<Switch
|
|
checked={enabled}
|
|
disabled={!canManage || update.isPending}
|
|
aria-label={`Allow manual payment for ${code} invoices`}
|
|
onCheckedChange={(checked) =>
|
|
update.mutate({ [field]: checked })
|
|
}
|
|
/>
|
|
</div>
|
|
);
|
|
})}
|
|
|
|
{!canManage && (
|
|
<p className="text-sm text-muted-foreground">
|
|
You can see these settings but not change them — that needs the
|
|
manual-payment settings permission.
|
|
</p>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|