"use client"; import { useMemo, useState, useTransition } from "react"; import { PaymentMethodType } from "@prisma/client"; import { deletePaymentMethodAction, movePaymentMethodAction, togglePaymentMethodVisibilityAction, updatePaymentMethodAction } from "@/actions/payment-methods"; import { PAYMENT_METHOD_LABELS, PAYMENT_METHOD_TYPES, USDT_NETWORKS } from "@/lib/constants"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Select } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; type PaymentMethodsListProps = { methods: MethodItem[]; }; type MethodItem = { id: string; type: PaymentMethodType; label: string; value: string; network: string | null; description: string | null; sortOrder: number; isVisible: boolean; }; type EditorState = { id: string; type: PaymentMethodType; label: string; value: string; network: string; description: string; isVisible: boolean; }; function toEditor(method: MethodItem): EditorState { return { id: method.id, type: method.type, label: method.label, value: method.value, network: method.network ?? "", description: method.description ?? "", isVisible: method.isVisible }; } export function PaymentMethodsList({ methods }: PaymentMethodsListProps) { const [isPending, startTransition] = useTransition(); const [message, setMessage] = useState(null); const [isError, setIsError] = useState(false); const [editor, setEditor] = useState(null); const indexed = useMemo(() => methods.map((method, index) => ({ method, index })), [methods]); function runAction(executor: () => Promise<{ success: boolean; message: string }>) { setMessage(null); startTransition(async () => { const result = await executor(); setMessage(result.message); setIsError(!result.success); if (result.success) { setEditor(null); } }); } function handleMove(id: string, direction: "up" | "down") { runAction(async () => { const formData = new FormData(); formData.set("id", id); formData.set("direction", direction); return movePaymentMethodAction(formData); }); } function handleToggle(id: string) { runAction(async () => { const formData = new FormData(); formData.set("id", id); return togglePaymentMethodVisibilityAction(formData); }); } function handleDelete(id: string) { runAction(async () => { const formData = new FormData(); formData.set("id", id); return deletePaymentMethodAction(formData); }); } function handleUpdate() { if (!editor) { return; } runAction(async () => { const formData = new FormData(); formData.set("id", editor.id); formData.set("type", editor.type); formData.set("label", editor.label); formData.set("value", editor.value); formData.set("network", editor.network); formData.set("description", editor.description); if (editor.isVisible) { formData.set("isVisible", "on"); } return updatePaymentMethodAction(formData); }); } if (methods.length === 0) { return (
No payment methods yet. Add one above.
); } return (

Current Methods

{message ?

{message}

: null} {indexed.map(({ method, index }) => { const editing = editor?.id === method.id; return (

{method.label} ({PAYMENT_METHOD_LABELS[method.type]})

{method.value}

{method.network ?

Network: {method.network}

: null} {method.description ?

{method.description}

: null} {!method.isVisible ?

Hidden on public profile

: null}
{editing && editor ? (