import { useState, useEffect, useCallback } from 'react'; import { DollarSign, Clock, CheckCircle, AlertCircle } from 'lucide-react'; import { DataTable } from '../../components/ui/DataTable'; import { Badge } from '../../components/ui/Badge'; import { Button } from '../../components/ui/Button'; import { StatCard } from '../../components/ui/StatCard'; import { api } from '../../api/client'; import { formatCurrency } from '../../utils/format'; import type { Payout, PayoutStatus } from '../../types/rental'; const STATUS_TABS: (PayoutStatus | 'ALL')[] = ['ALL', 'PENDING', 'PROCESSING', 'COMPLETED', 'FAILED']; interface PayoutStats { totalPending: number; totalProcessing: number; totalCompleted: number; totalFailed: number; pendingAmount: number; completedAmount: number; } export function AdminRentalPayoutsPage() { const [payouts, setPayouts] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [search, setSearch] = useState(''); const [tab, setTab] = useState('ALL'); const [stats] = useState(null); const fetchPayouts = useCallback(async () => { const params = new URLSearchParams({ page: String(page), pageSize: '20' }); if (search) params.set('search', search); if (tab !== 'ALL') params.set('status', tab); try { const res = await api.get<{ data: Payout[]; total: number }>(`/admin/rental-payouts?${params}`); setPayouts(res.data); setTotal(res.total); } catch { setPayouts([]); } }, [page, search, tab]); useEffect(() => { fetchPayouts(); }, [fetchPayouts]); const handleRetry = async (payoutId: string) => { try { await api.patch(`/admin/rental-payouts/${payoutId}/retry`); fetchPayouts(); } catch {} }; const statusBadge = (status: PayoutStatus) => { const v = status === 'COMPLETED' ? 'success' : status === 'FAILED' ? 'error' : status === 'PROCESSING' ? 'info' : 'warning'; return {status}; }; return (

Rental Payouts

{/* Stats */} {stats && (
)} {/* Status filter tabs */}
{STATUS_TABS.map((t) => ( ))}
(

{p.booking?.rentalListing?.title ?? 'N/A'}

{p.booking ? `${new Date(p.booking.startDate).toLocaleDateString()} - ${new Date(p.booking.endDate).toLocaleDateString()}` : ''}

), }, { key: 'tenant', header: 'Tenant', render: (p: Payout) => p.booking?.tenant?.fullName ?? 'N/A', }, { key: 'gross', header: 'Gross', render: (p: Payout) => formatCurrency(p.grossAmount), }, { key: 'commission', header: 'Commission', render: (p: Payout) => formatCurrency(p.commissionAmount), }, { key: 'net', header: 'Net Payout', render: (p: Payout) => {formatCurrency(p.netAmount)}, }, { key: 'status', header: 'Status', render: (p: Payout) => statusBadge(p.status), }, { key: 'createdAt', header: 'Date', render: (p: Payout) => new Date(p.createdAt).toLocaleDateString(), }, ]} data={payouts} total={total} page={page} pageSize={20} onPageChange={setPage} searchValue={search} onSearch={(v) => { setSearch(v); setPage(1); }} searchPlaceholder="Search payouts..." actions={(p: Payout) => (
{p.status === 'FAILED' && ( )}
)} />
); }