import React, { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import { toast } from 'sonner'; import { api } from '../lib/api'; import type { ApiResponse, PaginatedResponse } from '../lib/api'; import type { SmsWalletBalance, SmsWalletLog, SmsSettings } from '../types'; import { formatRial, formatNumber, formatDateTime } from '../lib/utils'; import Modal from '../components/ui/Modal'; import Pagination from '../components/ui/Pagination'; import PageHeader from '../components/ui/PageHeader'; const chargeSchema = z.object({ amount_rials: z.coerce.number().min(10000, 'حداقل مبلغ ۱۰,۰۰۰ ریال است'), }); type ChargeForm = z.infer; const EMPTY_LOGS: SmsWalletLog[] = []; export default function SmsWalletPage() { const qc = useQueryClient(); const [chargeOpen, setChargeOpen] = useState(false); const [gateway, setGateway] = useState<'mellat' | 'sep'>('mellat'); const [logPage, setLogPage] = useState(1); const { data: balanceData, isLoading: balanceLoading } = useQuery>({ queryKey: ['sms-wallet-balance'], queryFn: () => api.get('/api/v1/sms/wallet/balance'), }); const { data: logsData, isLoading: logsLoading } = useQuery>({ queryKey: ['sms-wallet-logs', logPage], queryFn: () => api.get(`/api/v1/sms/wallet/logs?page=${logPage}&limit=20`), }); const { data: settingsData } = useQuery>({ queryKey: ['sms-settings'], queryFn: () => api.get('/api/v1/sms/settings'), }); const balance = balanceData?.data; const logs = logsData?.data ?? EMPTY_LOGS; const total = logsData?.meta?.totalRecords ?? 0; const settings = settingsData?.data; const chargeForm = useForm({ resolver: zodResolver(chargeSchema) }); const chargeMutation = useMutation({ mutationFn: ({ amount_rials }: ChargeForm) => api.post<{ data: { payment_url: string } }>('/api/v1/sms/wallet/charge', { gateway, amount_rials }), onSuccess: (res: any) => { const url = res?.data?.payment_url; if (url) window.location.href = url; else toast.error('خطا در دریافت لینک پرداخت'); }, onError: (e: any) => toast.error(e.message), }); const [localSettings, setLocalSettings] = useState(null); const currentSettings = localSettings ?? settings; const saveMutation = useMutation({ mutationFn: (body: SmsSettings) => api.patch('/api/v1/sms/settings', body), onSuccess: () => { qc.invalidateQueries({ queryKey: ['sms-settings'] }); toast.success('تنظیمات ذخیره شد'); }, onError: (e: any) => toast.error(e.message), }); return ( <>
{/* کارت موجودی */}
موجودی کیف پول
{balanceLoading ? (
) : ( <>
{formatRial(balance?.balance_rials ?? 0)}
معادل {formatNumber(balance?.estimated_sms_count ?? 0)} پیامک {balance?.sms_price_rials ? ` (هر پیامک ${formatRial(balance.sms_price_rials)})` : ''}
)}
{/* تنظیمات پیامک */}
تنظیمات ارسال
{currentSettings ? (
{currentSettings.reminder_enabled && (
setLocalSettings({ ...currentSettings, reminder_hours_before: +e.target.value })} dir="ltr" style={{ width: 80 }} />
)} {currentSettings.post_visit_enabled && (