import { redirect } from "next/navigation"; import { getServerSession } from "next-auth"; import { authOptions } from "@/lib/auth"; import { isAdminEmail, listAdminEmails } from "@/lib/admin"; import { payoutRepo } from "@/server/repositories/payout.repo"; import { AdminFilterBar } from "@/features/admin/components/admin-filter-bar"; import { ExportCsvLink } from "@/features/admin/components/export-csv-link"; import { PayoutReviewCard, type PayoutCardData, } from "@/features/payout/components/payout-review-card"; type Tab = "RELEASED" | "HELD" | "PAID" | "CANCELLED"; const TABS: { key: Tab; label: string }[] = [ { key: "RELEASED", label: "Siap transfer" }, { key: "HELD", label: "Ditahan (escrow)" }, { key: "PAID", label: "Selesai" }, { key: "CANCELLED", label: "Dibatalkan" }, ]; interface PageProps { searchParams: Promise<{ tab?: string; dateFrom?: string; dateTo?: string; reviewer?: string; }>; } function parseDate(value: string | undefined): Date | undefined { if (!value) return undefined; const d = new Date(value); return Number.isNaN(d.getTime()) ? undefined : d; } export default async function AdminPayoutsPage({ searchParams }: PageProps) { const session = await getServerSession(authOptions); if (!session?.user) redirect("/login?callbackUrl=/admin/payouts"); if (!isAdminEmail(session.user.email)) { return (

Halaman ini hanya untuk admin SeTrip.

); } const params = await searchParams; const tab: Tab = TABS.some((t) => t.key === params.tab) ? (params.tab as Tab) : "RELEASED"; const rows = await payoutRepo.listByStatus(tab, { dateFrom: parseDate(params.dateFrom), dateTo: parseDate(params.dateTo), processorEmail: params.reviewer || undefined, }); const items: PayoutCardData[] = rows.map((p) => ({ id: p.id, amount: p.amount, currency: p.currency, status: p.status, heldUntil: p.heldUntil, releasedAt: p.releasedAt, paidAt: p.paidAt, cancelledAt: p.cancelledAt, bankName: p.bankName, bankAccountNumber: p.bankAccountNumber, bankAccountName: p.bankAccountName, adminNote: p.adminNote, createdAt: p.createdAt, trip: p.trip, organizer: p.organizer, booking: { id: p.booking.id, amount: p.booking.amount, status: p.booking.status, user: p.booking.user, }, processedBy: p.processedBy, })); const exportQuery = new URLSearchParams({ status: tab }); if (params.dateFrom) exportQuery.set("dateFrom", params.dateFrom); if (params.dateTo) exportQuery.set("dateTo", params.dateTo); if (params.reviewer) exportQuery.set("reviewer", params.reviewer); return (

Payout Organizer

Uang peserta ditahan (escrow) sampai trip selesai + 3 hari. Setelah status Siap transfer, admin transfer manual ke rekening organizer lalu tandai sudah dibayar.

{TABS.map((t) => ( {t.label} ))}
{items.length === 0 ? (

Tidak ada payout yang cocok dengan filter ini.

) : (
{items.map((p) => ( ))}
)}
); }