"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { formatDate } from "@/lib/format-date"; import { updateOrder } from "@/actions/orders/update-order"; import { createRefund } from "@/actions/orders/create-refund"; import { useToast, AdminButton, AdminInput } from "./design-system"; type Refund = { id: string; order_id: string; amount: number; reason: string | null; processor: string | null; processor_refund_id: string | null; status: string; created_at: string; }; type OrderPaymentSectionProps = { orderId: string; brandId: string | null; orderTotal: number; payment_processor: string | null; payment_status: string | null; payment_transaction_id: string | null; refunded_amount: number; refund_reason: string | null; existingRefunds: Refund[]; }; function formatCurrency(amount: number) { return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(amount); } export default function OrderPaymentSection({ orderId, brandId, orderTotal, payment_processor, payment_status, payment_transaction_id, existingRefunds, }: OrderPaymentSectionProps) { const router = useRouter(); const { success: showSuccess, error: showError } = useToast(); const [processor, setProcessor] = useState(payment_processor ?? ""); const [status, setStatus] = useState(payment_status ?? "manual"); const [transactionId, setTransactionId] = useState(payment_transaction_id ?? ""); const [refundAmount, setRefundAmount] = useState(""); const [refundReason, setRefundReason] = useState(""); const [saving, setSaving] = useState(false); const [refunding, setRefunding] = useState(false); const [error, setError] = useState(null); const [saved, setSaved] = useState(false); const [refundSaved, setRefundSaved] = useState(false); const totalRefunded = existingRefunds .filter((r) => r.status === "completed") .reduce((sum, r) => sum + Number(r.amount), 0); const remainingBalance = Math.max(0, orderTotal - totalRefunded); // Validation for refund const [refundError, setRefundError] = useState(null); function validateRefund(): boolean { const amount = Number(refundAmount); if (!amount || amount <= 0) { setRefundError("Please enter a valid refund amount"); return false; } if (amount > remainingBalance) { setRefundError(`Amount cannot exceed remaining balance of ${formatCurrency(remainingBalance)}`); return false; } setRefundError(null); return true; } async function handleSavePayment(e: React.FormEvent) { e.preventDefault(); setSaving(true); setError(null); setSaved(false); const result = await updateOrder(orderId, brandId, { payment_processor: processor || null, payment_status: status, payment_transaction_id: transactionId || null, }); if (!result.success) { showError("Failed to save", result.error ?? "Please try again"); setError(result.error ?? "Failed to save"); } else { showSuccess("Payment saved", "Payment details have been updated"); setSaved(true); } setSaving(false); } async function handleRefund(e: React.FormEvent) { e.preventDefault(); if (!validateRefund()) return; const amount = Number(refundAmount); setRefunding(true); setError(null); setRefundSaved(false); const result = await createRefund(orderId, brandId, { amount, reason: refundReason || null, }); if (!result.success) { showError("Failed to record refund", result.error ?? "Please try again"); setError(result.error ?? "Failed to record refund"); } else { showSuccess("Refund recorded", `${formatCurrency(amount)} has been refunded`); setRefundAmount(""); setRefundReason(""); setRefundSaved(true); router.refresh(); } setRefunding(false); } return (
{/* Balance summary */}

Order Total

{formatCurrency(orderTotal)}

Refunded

{formatCurrency(totalRefunded)}

Balance Due

{formatCurrency(remainingBalance)}

{/* Payment details */}
{error && (
{error}
)} {saved && (
Payment details saved
)}
setTransactionId(e.target.value)} placeholder="External payment reference" className="w-full rounded-xl border border-stone-200 bg-white px-4 py-2.5 text-sm outline-none focus:border-[var(--admin-accent)] focus:ring-2 focus:ring-[var(--admin-accent)]/20" />
{saving ? "Saving..." : "Save Payment Details"}
{/* Refund history */} {existingRefunds.length > 0 && (

Refund History ({existingRefunds.length})

{existingRefunds.map((r) => (

{formatCurrency(Number(r.amount))}

{r.reason && (

{r.reason}

)}

{formatDate(r.created_at)}

{r.status}
))}
)} {/* Record a refund */} {remainingBalance > 0 && (

Record a Refund

{refundSaved && (
Refund recorded successfully
)}
$ { setRefundAmount(e.target.value); setRefundError(null); }} placeholder={`Max ${formatCurrency(remainingBalance)}`} className={`w-full rounded-xl border bg-white pl-8 pr-4 py-2.5 text-sm outline-none focus:ring-2 focus:ring-[var(--admin-accent)]/20 ${ refundError ? "border-red-400 bg-red-50" : "border-stone-200 focus:border-[var(--admin-accent)]" }`} />
{refundError && (

{refundError}

)}
setRefundReason(e.target.value)} placeholder="Customer request, defective product, etc." className="w-full rounded-xl border border-stone-200 bg-white px-4 py-2.5 text-sm outline-none focus:border-[var(--admin-accent)] focus:ring-2 focus:ring-[var(--admin-accent)]/20" />
{refunding ? "Processing..." : `Record Refund (Max ${formatCurrency(remainingBalance)})`}
)}
); }