import React, { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { api } from '@/lib/api'; import { __ } from '@/lib/i18n'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from '@/components/ui/select'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Search, Filter, X, Download } from 'lucide-react'; import { formatMoney } from '@/lib/currency'; interface Affiliate { id: number; user_id: number; user_name?: string; referral_code: string; } interface Referral { id: number; affiliate_id: number; affiliate_name?: string; order_id: number; status: string; commission_amount: string; currency: string; created_at: string; approved_at?: string; } export default function AffiliatesReferrals() { const [filters, setFilters] = useState({ affiliate_id: '', status: '', date_start: '', date_end: '', order_id: '', }); const [showFilters, setShowFilters] = useState(false); const [searchQuery, setSearchQuery] = useState(''); // Fetch affiliates for filter dropdown const { data: affiliates = [] } = useQuery({ queryKey: ['admin-affiliates'], queryFn: async () => { const response: any = await api.get('/admin/affiliates'); return Array.isArray(response) ? response : (response?.data || []); }, }); // Build query params const queryParams = new URLSearchParams(); if (filters.affiliate_id) queryParams.set('affiliate_id', filters.affiliate_id); if (filters.status) queryParams.set('status', filters.status); if (filters.date_start) queryParams.set('date_start', filters.date_start); if (filters.date_end) queryParams.set('date_end', filters.date_end); if (filters.order_id) queryParams.set('order_id', filters.order_id); // Fetch referrals with filters const { data: referrals = [], isLoading } = useQuery({ queryKey: ['admin-referrals', filters], queryFn: async () => { const queryString = queryParams.toString(); const url = queryString ? `/admin/affiliates/referrals?${queryString}` : '/admin/affiliates/referrals'; const response: any = await api.get(url); return Array.isArray(response) ? response : (response?.data || []); }, }); // Client-side search filter (must be after referrals is defined) const filteredReferrals = (referrals || []).filter((ref) => { if (searchQuery) { const query = searchQuery.toLowerCase(); return ( ref.order_id.toString().includes(query) || (ref.affiliate_name || '').toLowerCase().includes(query) ); } return true; }); // Export to CSV const exportToCSV = () => { const headers = ['ID', 'Affiliate', 'Order ID', 'Status', 'Commission', 'Currency', 'Created At']; const rows = filteredReferrals.map(ref => [ ref.id, ref.affiliate_name || `Affiliate #${ref.affiliate_id}`, ref.order_id, ref.status, ref.commission_amount, ref.currency, new Date(ref.created_at).toISOString() ]); const csvContent = [ headers.join(','), ...rows.map(row => row.map(cell => `"${cell}"`).join(',')) ].join('\n'); const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = `affiliate-referrals-${new Date().toISOString().split('T')[0]}.csv`; link.click(); }; const clearFilters = () => { setFilters({ affiliate_id: '', status: '', date_start: '', date_end: '', order_id: '', }); setSearchQuery(''); }; const hasActiveFilters = Object.values(filters).some(v => v !== ''); const formatCurrency = (amount: string | number, currency?: string) => { try { return formatMoney(amount, { currency }); } catch { const num = typeof amount === 'string' ? parseFloat(amount) : amount; if (isNaN(num)) return '—'; return `${currency || 'IDR'} ${num.toLocaleString()}`; } }; // Stats const totalCommissions = filteredReferrals.reduce((sum, r) => sum + parseFloat(r.commission_amount || 0), 0); const pendingCount = filteredReferrals.filter(r => r.status === 'pending').length; const approvedCount = filteredReferrals.filter(r => r.status === 'approved').length; return (
{/* Header with search, filter toggle, and export */}
setSearchQuery(e.target.value)} className="!pl-9" />
{/* Stats summary text */}

{filteredReferrals.length} referral(s) {hasActiveFilters || searchQuery ? '(filtered)' : ''}

{/* Filter Panel */} {showFilters && (

{__('Filter Referrals')}

{hasActiveFilters && ( )}
{/* Affiliate Filter */}
{/* Status Filter */}
{/* Order ID Filter */}
setFilters({ ...filters, order_id: e.target.value })} />
{/* Date Start */}
setFilters({ ...filters, date_start: e.target.value })} />
{/* Date End */}
setFilters({ ...filters, date_end: e.target.value })} />
)} {/* Stats Summary */}
{__('Total Referrals')}
{filteredReferrals.length}
{__('Total Commission')}
{formatCurrency(totalCommissions)}
{__('Pending')}
{pendingCount}
{__('Approved')}
{approvedCount}
{/* Referrals Table */} {isLoading ? (
{__('Loading referrals...')}
) : filteredReferrals.length === 0 ? (
{hasActiveFilters || searchQuery ? __('No referrals match your filters') : __('No referrals yet')}
) : (
{__('ID')} {__('Affiliate')} {__('Order ID')} {__('Status')} {__('Date')} {__('Commission')} {filteredReferrals.map((ref) => ( #{ref.id}
{ref.affiliate_name || `Affiliate #${ref.affiliate_id}`}
#{ref.order_id} {ref.status} {new Date(ref.created_at).toLocaleDateString('id-ID', { year: 'numeric', month: 'short', day: 'numeric' })} {formatCurrency(ref.commission_amount, ref.currency)}
))}
)}
); }