import { useEffect, useMemo, useState } from 'react'; import { createPortal } from 'react-dom'; import { XMarkIcon } from '@heroicons/react/24/outline'; import SearchableSelect from './ui/SearchableSelect'; import { useBankAccounts, usePosDevices } from '../hooks/usePaymentMethods'; import { formatRial, formatNumber, tomanToRial, digitsOnly } from '../lib/utils'; export type WalletMode = 'charge' | 'withdraw'; export interface WalletModalSubmit { mode: WalletMode; amount_rials: number; description?: string; payment_method?: string; reference?: string; } interface Props { open: boolean; balanceRials: number; submitting?: boolean; onClose: () => void; onSubmit: (payload: WalletModalSubmit) => void; } // مبالغ پیشنهادی سریع، به تومان. const QUICK_TOMANS = [100_000, 200_000, 300_000, 400_000]; interface MethodOption { value: string; label: string; method: string; reference: string | null } /** * مودال شارژ/برداشت کیف پول بیمار — با طراحیِ پنل و روش‌های پرداختِ واقعیِ کلینیک * (حساب بانکی/کارت‌خوان از /my/payment-methods + نقدی). مبلغ به تومان وارد و هنگام * ثبت به ریال (واحد API) تبدیل می‌شود. */ export default function WalletTransactionModal({ open, balanceRials, submitting, onClose, onSubmit }: Props) { const [mode, setMode] = useState('charge'); const [amountToman, setAmountToman] = useState(0); const [methodValue, setMethodValue] = useState('cash'); const [description, setDescription] = useState(''); const banksQ = useBankAccounts(); const posQ = usePosDevices(); const methodOptions = useMemo(() => { const opts: MethodOption[] = [{ value: 'cash', label: 'نقدی', method: 'cash', reference: null }]; for (const b of banksQ.data?.data ?? []) { if (!b.is_active) continue; opts.push({ value: `bank:${b.uuid}`, label: `کارت به کارت — ${b.bank_name}`, method: 'card', reference: `${b.bank_name}${b.card_number ? ` (${b.card_number})` : ''}` }); } for (const p of posQ.data?.data ?? []) { if (!p.is_active) continue; opts.push({ value: `pos:${p.uuid}`, label: `کارت‌خوان — ${p.bank_name}`, method: 'pos', reference: `${p.bank_name} (${p.terminal_number})` }); } return opts; }, [banksQ.data, posQ.data]); useEffect(() => { if (open) { setMode('charge'); setAmountToman(0); setMethodValue('cash'); setDescription(''); } }, [open]); useEffect(() => { if (!open) return; const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('keydown', onKey); return () => document.removeEventListener('keydown', onKey); }, [open, onClose]); if (!open) return null; const amountRials = tomanToRial(amountToman); const isWithdraw = mode === 'withdraw'; const overBalance = isWithdraw && amountRials > balanceRials; const canSubmit = amountToman > 0 && !overBalance && !submitting; const submit = () => { if (!canSubmit) return; const opt = methodOptions.find((o) => o.value === methodValue); onSubmit({ mode, amount_rials: amountRials, ...(description.trim() ? { description: description.trim() } : {}), ...(opt ? { payment_method: opt.method } : {}), ...(opt?.reference ? { reference: opt.reference } : {}), }); }; const tab = (key: WalletMode, label: string) => { const on = mode === key; return ( ); }; return createPortal(
e.stopPropagation()}>

{isWithdraw ? 'برداشت از کیف پول' : 'شارژ کیف پول'}

{/* موجودی — کارت ساده مطابق پنل (بدون گرادیان) */}
موجودی کیف پول {formatRial(balanceRials)}
{/* toggle شارژ/برداشت */}
{tab('charge', 'شارژ کیف پول')} {tab('withdraw', 'برداشت از کیف پول')}
{/* مبلغ + مبالغ سریع */}
{QUICK_TOMANS.map((t) => { const on = amountToman === t; return ( ); })}
0 ? formatNumber(amountToman) : ''} onChange={(e) => { const raw = digitsOnly(e.target.value); setAmountToman(raw ? parseInt(raw, 10) : 0); }} placeholder="مبلغ دلخواه (تومان)" style={{ textAlign: 'center', direction: 'ltr' }} />
{overBalance &&
موجودی کیف پول کافی نیست
} {/* روش پرداخت واقعی */}
({ value: o.value, label: o.label }))} value={methodValue} onChange={(v) => setMethodValue(String(v ?? 'cash'))} placeholder="روش پرداخت" height={46} />
{/* توضیحات */}