import React, { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; import { EyeIcon, CheckIcon, XMarkIcon, MagnifyingGlassIcon } from '@heroicons/react/24/outline'; import { toast } from 'sonner'; import { api } from '../lib/api'; import type { ApiResponse, PaginatedResponse } from '../lib/api'; import type { Settlement } from '../types'; import { formatDate, formatRial } from '../lib/utils'; import DataTable, { Column } from '../components/ui/DataTable'; import StatusBadge from '../components/ui/StatusBadge'; import Pagination from '../components/ui/Pagination'; import ConfirmDialog from '../components/ui/ConfirmDialog'; import Modal from '../components/ui/Modal'; const STATUS_FILTERS = [ { value: '', label: 'همه' }, { value: 'pending', label: 'در انتظار' }, { value: 'approved', label: 'تأیید شده' }, { value: 'paid', label: 'پرداخت شده' }, { value: 'rejected', label: 'رد شده' }, ]; export default function SettlementsPage() { const navigate = useNavigate(); const qc = useQueryClient(); const [page, setPage] = useState(1); const [search, setSearch] = useState(''); const [statusFilter, setStatusFilter] = useState('pending'); const [approveTarget, setApproveTarget] = useState(null); const [rejectTarget, setRejectTarget] = useState(null); const [rejectReason, setRejectReason] = useState(''); const limit = 15; const { data, isLoading } = useQuery({ queryKey: ['settlements', page, search, statusFilter], queryFn: () => { const params = new URLSearchParams({ page: String(page), limit: String(limit) }); if (statusFilter) params.set('status', statusFilter); if (search) params.set('search', search); return api.get>(`/api/v1/admin/settlements?${params}`); }, }); const approveMutation = useMutation({ mutationFn: (s: Settlement) => api.post>(`/api/v1/settlement/${s.uuid}/approve`, {}), onSuccess: () => { toast.success('تسویه تأیید شد'); setApproveTarget(null); qc.invalidateQueries({ queryKey: ['settlements'] }); }, onError: (err: Error) => toast.error(err.message), }); const rejectMutation = useMutation({ mutationFn: ({ s, reason }: { s: Settlement; reason: string }) => api.post>(`/api/v1/settlement/${s.uuid}/reject`, { reason }), onSuccess: () => { toast.success('تسویه رد شد'); setRejectTarget(null); setRejectReason(''); qc.invalidateQueries({ queryKey: ['settlements'] }); }, onError: (err: Error) => toast.error(err.message), }); const columns: Column[] = [ { key: 'representation_name', header: 'نماینده', render: (s) => {s.representation_name} }, { key: 'amount', header: 'مبلغ', render: (s) => formatRial(s.amount) }, { key: 'bank_card', header: 'شماره کارت', render: (s) => s.bank_card ? {s.bank_card} : '—' }, { key: 'bank_name', header: 'بانک' }, { key: 'status', header: 'وضعیت', render: (s) => }, { key: 'requested_at', header: 'تاریخ درخواست', render: (s) => formatDate(s.requested_at) }, ]; const items = data?.data ?? []; const total = data?.meta?.totalRecords ?? 0; return (

تسویه‌حساب

{total} درخواست تسویه
{ setSearch(e.target.value); setPage(1); }} placeholder="جستجو بر اساس نام نماینده..." />
{STATUS_FILTERS.map((f) => ( ))}
columns={columns} data={items} loading={isLoading} emptyMessage="هیچ درخواست تسویه‌ای یافت نشد" actions={(s) => ( <> {s.status === 'pending' && ( <> )} )} />
approveTarget && approveMutation.mutate(approveTarget)} onCancel={() => setApproveTarget(null)} /> { setRejectTarget(null); setRejectReason(''); }} footer={ <> } >