'use client'; import { useState, useEffect, useCallback } from 'react'; import { useAuth } from '@/contexts/AuthContext'; import { purchasesApi } from '@/lib/api/purchases'; import { packagesApi } from '@/lib/api/packages'; import PageHeader from '@/components/admin/PageHeader'; import { Purchase, Paginated, PurchaseFilters, PAYMENT_GATEWAYS, PURCHASE_STATUSES, getGatewayLabel, getPurchaseStatusLabel, } from '@/types/purchase'; import { PackageName } from '@/types/package'; import { formatPrice, formatDate, formatTime, getProductTypeLabel, getPurchaseFinalPrice } from '@/lib/utils'; import { MagnifyingGlassIcon, ArrowPathIcon } from '@heroicons/react/24/outline'; const statusBadgeClass = (status: number): string => { switch (status) { case 2: return 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300'; case 3: return 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300'; default: return 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300'; } }; const emptyFilters: PurchaseFilters = { email: '', mobile: '', package_name: '', gateway: '', status: undefined, }; export default function PurchasesPage() { const { token } = useAuth(); const [packages, setPackages] = useState([]); const [filters, setFilters] = useState(emptyFilters); const [result, setResult] = useState | null>(null); const [page, setPage] = useState(1); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const loadPurchases = useCallback(async (targetPage: number, activeFilters: PurchaseFilters) => { if (!token) return; setIsLoading(true); setError(null); try { const data = await purchasesApi.getPurchases( { ...activeFilters, page: targetPage, per_page: 30 }, token ); setResult(data); } catch (err) { setError(err instanceof Error ? err.message : 'خطا در دریافت لیست خریدها'); } finally { setIsLoading(false); } }, [token]); useEffect(() => { if (!token) return; packagesApi.getAllPackages(token).then(setPackages).catch(() => setPackages([])); loadPurchases(1, emptyFilters); }, [token, loadPurchases]); const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFilters((prev) => ({ ...prev, [name]: name === 'status' ? (value === '' ? undefined : parseInt(value)) : value, })); }; const handleSearch = (e: React.FormEvent) => { e.preventDefault(); setPage(1); loadPurchases(1, filters); }; const handleReset = () => { setFilters(emptyFilters); setPage(1); loadPurchases(1, emptyFilters); }; const goToPage = (targetPage: number) => { setPage(targetPage); loadPurchases(targetPage, filters); }; const inputClass = 'block w-full px-3 py-2.5 text-gray-900 dark:text-gray-100 border border-gray-200 dark:border-gray-700 rounded-xl shadow-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent sm:text-sm dark:bg-gray-800/80 transition-colors'; const labelClass = 'block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5'; return (
{/* Filters */}
{error && (

{error}

)} {/* Results */}

{result ? `${formatPrice(result.total)} خرید یافت شد` : 'در حال بارگذاری...'}

{isLoading ? (
) : !result || result.data.length === 0 ? (

هیچ خریدی با این فیلترها یافت نشد

) : ( <> {/* Mobile: stacked cards */}
    {result.data.map((purchase) => (
  • {purchase.product?.title || '—'}

    {purchase.product?.package_name?.title || purchase.product?.package_name?.name || '—'} {purchase.product ? ` • ${getProductTypeLabel(purchase.product.type)}` : ''}

    {getPurchaseStatusLabel(purchase.status)}

    {purchase.user?.full_name?.trim() || 'بدون نام'}

    {purchase.user?.email && (

    {purchase.user.email}

    )} {purchase.user?.mobile && (

    {purchase.user.mobile}

    )}
    {formatPrice(getPurchaseFinalPrice(purchase))} تومان
    {getGatewayLabel(purchase.gateway)} {formatDate(purchase.created_at)} {formatTime(purchase.created_at)}
  • ))}
{/* Desktop: table */}
{result.data.map((purchase) => ( ))}
کاربر پکیج محصول قیمت نهایی منبع پرداخت وضعیت تاریخ و ساعت
{purchase.user?.full_name?.trim() || 'بدون نام'}
{purchase.user?.email || '—'}
{purchase.user?.mobile || '—'}
{purchase.product?.package_name?.title || purchase.product?.package_name?.name || '—'}
{purchase.product?.title || '—'}
{purchase.product ? getProductTypeLabel(purchase.product.type) : ''}
{formatPrice(getPurchaseFinalPrice(purchase))} تومان {getGatewayLabel(purchase.gateway)} {getPurchaseStatusLabel(purchase.status)} {formatDate(purchase.created_at)} {formatTime(purchase.created_at)}
)} {/* Pagination */} {result && result.last_page > 1 && (
صفحه {result.current_page} از {result.last_page}
)}
); }