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 */}
)}
);
}