import { useEffect, useState, useMemo } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { ArrowLeft, House, CreditCard, BadgeCheck, User } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { Separator } from "@/components/ui/separator"; import AppBreadcrumb from "@/components/generic/Breadcrumb/AppBreadcrumb"; import { useTiers } from "@/contexts/AdminTiersContext"; import { useDateFormat } from "@/hooks/useDateFormat"; import { PageMeta } from "@/contexts/MetadataContext"; import api from "@/utils/api.util"; import { resolveTierBadge } from "@/utils/tierBadge.util"; const STATUS_BADGE = { pending: "secondary", completed: "default", failed: "destructive", cancelled: "outline", expired: "outline", refunded: "outline", }; // ─── Provider label map (extend as you add more providers) ─────────────────── const PROVIDER_LABELS = { paypal: "PayPal", stripe: "Stripe", gcash: "GCash", }; function InfoRow({ label, children }) { return (
{label} {children ?? —}
); } function SectionCard({ icon: Icon, title, children }) { return (
{Icon && }

{title}

{children}
); } // ─── Provider reference section — renders differently per provider ──────────── function ProviderReference({ payment }) { const provider = payment.provider ?? "paypal"; const payload = payment.provider_payload ?? {}; const title = `${PROVIDER_LABELS[provider] ?? provider} Reference`; return (
{/* PayPal */} {provider === "paypal" && ( <> {payload.order_id} {payload.capture_id} {payload.payer_id} {payload.checkout && ( <> {payment.currency} {Number(payload.checkout.subtotal ?? 0).toFixed(2)} {Number(payload.checkout.discount) > 0 && ( {payload.checkout.promo_code} — -{payment.currency}{" "} {Number(payload.checkout.discount).toFixed(2)} )} )} )} {/* Stripe — extend when needed */} {provider === "stripe" && ( <> {payload.payment_intent_id} {payload.charge_id} {payload.customer_id} )} {/* GCash / other — generic fallback */} {provider !== "paypal" && provider !== "stripe" && ( <> {payload.reference_id} {payload.transaction_id} )} {/* Cancelled info — shown for any provider */} {payload.cancelled_at && ( {fmtDateTime(payload.cancelled_at)} )}
); } // ─── Main ───────────────────────────────────────────────────────────────────── export default function ViewPayment() { const navigate = useNavigate(); const { paymentId } = useParams(); const { fetchPayment, payment, loading } = useTiers(); const { fmtDateTime } = useDateFormat(); const [tierCategories, setTierCategories] = useState([]); const tierMap = useMemo(() => Object.fromEntries(tierCategories.map((c) => [c.slug, c])), [tierCategories]); useEffect(() => { fetchPayment(paymentId); api.get("/admin/tiers/categories").then(({ data }) => setTierCategories(data.data ?? [])).catch(() => {}); }, [paymentId]); return (
, to: "/admin" }, { label: "Payments", to: "/admin/tiers/payments" }, { label: `Payment #${paymentId}` }, ]} />

Payment Details

Payment #{paymentId}

{loading && !payment ? (
{[...Array(3)].map((_, i) => )}
) : !payment ? (

Payment not found.

) : (
{/* Transaction */}
{payment.status} {PROVIDER_LABELS[payment.provider] ?? payment.provider ?? "—"} {payment.currency} {Number(payment.amount).toFixed(2)} {Number(payment.discount) > 0 && ( -{payment.currency} {Number(payment.discount).toFixed(2)} {payment.promo_code && ` (${payment.promo_code})`} )} {payment.paid_at ? fmtDateTime(payment.paid_at) : "—"} {payment.createdAt ? fmtDateTime(payment.createdAt) : "—"}
{/* User */}
{String(payment.user_id)} {payment.user?.email}
{/* Plan */} {payment.plan && (
{payment.plan.label} {(() => { const { cls, label } = resolveTierBadge(payment.plan.tier, tierMap); return {label}; })()} {payment.plan.duration_days} days
)} {/* Provider reference — dynamic per provider */}
)}
); }