'use client' import { useState } from 'react' import type { PaginationListColumnType } from '@/types' import { addToast } from '@/lib/toast' import PaginatedList from '@/components/PaginatedList' import PageNavbar from '@/components/layouts/PageNavbar' import Button from '@/components/formElements/Button' import Input from '@/components/formElements/Input' import CloseCircleIcon from '@/components/icons/CloseCircleIcon' import FileCheckIcon from '@/components/icons/FileCheckIcon' import Modal from '@/components/modals/Modal' import AdminTableActions from '@/components/ui/AdminTableActions' import AdminTableViewButton from '@/components/ui/AdminTableViewButton' import StatusChip from '@/components/ui/StatusChip' import axiosInstance from '@/config/axios' import { APP_ROUTES } from '@/constants/routes' import { BANK_ACCOUNT_VERIFICATION_STATUS_FILTER_ITEMS, getBankAccountVerificationStatus, type BankAccountVerificationStatus, } from '@/constants/status' import { formatPersonName, coerceToString } from '@/helpers' import useAlertModal from '@/hooks/useAlertModal' import useAdminMutation from '@/hooks/useAdminMutation' import { formatPersianDate } from '@/lib/formatters' import { API_ROUTES } from '@/services/config' interface BankAccountUserSummary { mobile: string firstName: string | null lastName: string | null } interface BankAccountRow { id: string userId: string ownerType: 'guest' | 'organizer' accountHolder: string iban: string bankName: string | null nationalCode: string | null verificationStatus: BankAccountVerificationStatus rejectionReason: string | null jibitMatched: boolean | null jibitInquiredAt: string | null jibitErrorCode: string | null createdAt: string user?: BankAccountUserSummary [key: string]: unknown } const columns: PaginationListColumnType[] = [ { field: 'userId', label: 'کاربر', filterable: true, sortable: false, type: 'text', }, { field: 'ownerType', label: 'نوع', filterable: true, sortable: false, type: 'select', filterItems: [ { code: 'guest', name: 'مهمان' }, { code: 'organizer', name: 'میزبان' }, ], }, { field: 'iban', label: 'شبا', filterable: false, sortable: false, }, { field: 'nationalCode', label: 'کد ملی', filterable: false, sortable: false, }, { field: 'jibitMatched', label: 'استعلام جیبت', filterable: false, sortable: false, }, { field: 'verificationStatus', label: 'وضعیت', filterable: true, sortable: true, type: 'select', filterItems: BANK_ACCOUNT_VERIFICATION_STATUS_FILTER_ITEMS, }, { field: 'createdAt', label: 'تاریخ ثبت', filterable: false, sortable: true, type: 'date', }, { field: 'actions', label: 'عملیات', }, ] const BankAccountsPage = () => { const { showAlert } = useAlertModal() const { pendingId, runAction } = useAdminMutation({ url: API_ROUTES.BANK_ACCOUNTS.ADMIN_LIST }) const [rejectTarget, setRejectTarget] = useState(null) const [rejectReason, setRejectReason] = useState('') const isRejecting = rejectTarget?.id === pendingId const handleInquire = (row: BankAccountRow) => { showAlert('استعلام تطبیق شبا از جیبیت انجام شود؟', () => runAction(row.id, () => axiosInstance.patch(API_ROUTES.BANK_ACCOUNTS.ADMIN_JIBIT_INQUIRY(row.id)), 'نتیجه استعلام جیبیت ذخیره شد') ) } const handleApprove = (row: BankAccountRow) => { if (row.jibitMatched !== true) { addToast({ title: 'تأیید فقط پس از استعلام موفق جیبیت (matched) ممکن است', color: 'warning' }) return } showAlert(`حساب «${row.accountHolder}» تأیید شود؟`, () => runAction(row.id, () => axiosInstance.patch(API_ROUTES.BANK_ACCOUNTS.ADMIN_APPROVE(row.id)), 'حساب بانکی تأیید شد') ) } const handleReject = async () => { if (!rejectTarget) return const reason = rejectReason.trim() if (reason.length < 3) { addToast({ title: 'دلیل رد باید حداقل ۳ کاراکتر باشد', color: 'warning' }) return } const succeeded = await runAction( rejectTarget.id, () => axiosInstance.patch(API_ROUTES.BANK_ACCOUNTS.ADMIN_REJECT(rejectTarget.id), { reason }), 'حساب بانکی رد شد' ) if (succeeded) { setRejectTarget(null) setRejectReason('') } } return (
{{ userId: (row) => { const account = row as BankAccountRow return (
{formatPersonName(account.user?.firstName, account.user?.lastName)} {account.user?.mobile ? {account.user.mobile} : null}
) }, ownerType: (_row, cellValue) => (coerceToString(cellValue) === 'organizer' ? 'میزبان' : 'مهمان'), iban: (_row, cellValue) => ( {coerceToString(cellValue)} ), jibitMatched: (row) => { const account = row as BankAccountRow if (account.jibitErrorCode) return {account.jibitErrorCode} if (account.jibitMatched === true) return مطابق if (account.jibitMatched === false) return عدم تطابق return استعلام نشده }, verificationStatus: (row, cellValue) => { const account = row as BankAccountRow const { label, chipColor } = getBankAccountVerificationStatus(coerceToString(cellValue)) return ( ) }, createdAt: (_row, cellValue) => formatPersianDate(cellValue), actions: (row) => { const account = row as BankAccountRow const isBusy = pendingId === account.id const isPending = account.verificationStatus === 'pending_review' return ( {isPending ? ( <> ) : null} ) }, }}
{ void handleReject() }} onOpenChange={(open) => { if (!open && !isRejecting) { setRejectTarget(null) setRejectReason('') } }} > { setRejectReason(coerceToString(next)) }} />
) } export default BankAccountsPage