Add payment module, BFF proxy, hub/dashboard/ops/PSP/merchant screens wired to real APIs, and mark payment-frontend complete in project status. Co-authored-by: Cursor <cursoragent@cursor.com>
85 lines
3.2 KiB
TypeScript
85 lines
3.2 KiB
TypeScript
"use client";
|
||
|
||
import { useParams } from "next/navigation";
|
||
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
||
import { toast } from "sonner";
|
||
import { useTenantId } from "@/hooks/useTenantId";
|
||
import { paymentApi } from "@/modules/payment/services/payment-api";
|
||
import { PaymentPageLoader, PaymentPageError } from "@/modules/payment/pages/shared";
|
||
import { PageHeader, Card, CardContent, Button } from "@/components/ds";
|
||
import { PaymentStatusChip } from "@/modules/payment/components/PaymentStatusChip";
|
||
|
||
export const PaymentMerchantDetail = function PaymentMerchantDetailPage() {
|
||
const params = useParams();
|
||
const id = String(params?.id ?? "");
|
||
const { tenantId } = useTenantId();
|
||
const qc = useQueryClient();
|
||
|
||
const q = useQuery({
|
||
queryKey: ["payment", tenantId, "merchant", id],
|
||
queryFn: () => paymentApi.merchants.get(tenantId!, id),
|
||
enabled: !!tenantId && !!id,
|
||
});
|
||
|
||
const actionM = useMutation({
|
||
mutationFn: (action: "submit" | "activate" | "suspend" | "close") => {
|
||
const api = paymentApi.merchants[action];
|
||
return api(tenantId!, id);
|
||
},
|
||
onSuccess: () => {
|
||
toast.success("وضعیت بهروز شد");
|
||
qc.invalidateQueries({ queryKey: ["payment", tenantId, "merchant", id] });
|
||
},
|
||
onError: (e: Error) => toast.error(e.message),
|
||
});
|
||
|
||
if (!tenantId || q.isLoading) return <PaymentPageLoader />;
|
||
if (q.error) return <PaymentPageError error={q.error} onRetry={() => q.refetch()} />;
|
||
|
||
const m = q.data!;
|
||
const status = String(m.status);
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
<PageHeader title={String(m.name ?? "پذیرنده")} description={`کد: ${String(m.code ?? "—")}`} />
|
||
<Card>
|
||
<CardContent className="space-y-3 p-4">
|
||
<div className="flex items-center gap-2">
|
||
<span className="text-sm text-[var(--muted)]">وضعیت:</span>
|
||
<PaymentStatusChip status={status} />
|
||
</div>
|
||
<div className="flex flex-wrap gap-2">
|
||
{status === "draft" ? (
|
||
<Button size="sm" loading={actionM.isPending} onClick={() => actionM.mutate("submit")}>
|
||
ارسال برای بررسی
|
||
</Button>
|
||
) : null}
|
||
{status === "pending_review" ? (
|
||
<Button size="sm" loading={actionM.isPending} onClick={() => actionM.mutate("activate")}>
|
||
فعالسازی
|
||
</Button>
|
||
) : null}
|
||
{status === "active" ? (
|
||
<Button size="sm" variant="outline" loading={actionM.isPending} onClick={() => actionM.mutate("suspend")}>
|
||
تعلیق
|
||
</Button>
|
||
) : null}
|
||
{!["closed"].includes(status) ? (
|
||
<Button size="sm" variant="outline" loading={actionM.isPending} onClick={() => actionM.mutate("close")}>
|
||
بستن
|
||
</Button>
|
||
) : null}
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
<Card>
|
||
<CardContent className="p-4">
|
||
<pre className="overflow-x-auto text-xs">{JSON.stringify(m, null, 2)}</pre>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default PaymentMerchantDetail;
|