import React, { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { CheckIcon, XMarkIcon, PhoneIcon } from '@heroicons/react/24/outline'; import { toast } from 'sonner'; import { api } from '../lib/api'; import type { PaginatedResponse } from '../lib/api'; import Portal from '../components/ui/Portal'; import { formatDate } from '../lib/utils'; import PageHeader from '../components/ui/PageHeader'; import Pagination from '../components/ui/Pagination'; import ConfirmDialog from '../components/ui/ConfirmDialog'; interface PreRegistration { uuid: string; type: 'independent_doctor' | 'doctor_with_clinic' | 'clinic_manager'; name: string; mobile: string; info: string | null; status: 'pending' | 'approved' | 'rejected'; admin_note: string | null; created_at: number; } const EMPTY: PreRegistration[] = []; const TYPE_META: Record = { independent_doctor: { label: 'دکتر', color: 'blue' }, doctor_with_clinic: { label: 'دکتر + کلینیک', color: 'purple' }, clinic_manager: { label: 'مدیر کلینیک', color: 'orange' }, }; const STATUS_META: Record = { pending: { label: 'در انتظار', color: 'yellow' }, approved: { label: 'تأیید شده', color: 'green' }, rejected: { label: 'رد شده', color: 'red' }, }; const STATUS_TABS = [ { value: 'pending', label: 'در انتظار' }, { value: 'approved', label: 'تأیید شده' }, { value: 'rejected', label: 'رد شده' }, { value: 'all', label: 'همه' }, ]; export default function PreRegistrationsPage() { const qc = useQueryClient(); const [page, setPage] = useState(1); const [statusFilter, setStatusFilter] = useState('pending'); const [approveTarget, setApproveTarget] = useState(null); const [rejectTarget, setRejectTarget] = useState(null); const [rejectNote, setRejectNote] = useState(''); const limit = 20; const { data, isLoading } = useQuery>({ queryKey: ['pre-registrations', page, statusFilter], queryFn: () => api.get(`/api/v1/admin/pre-registrations?page=${page}&limit=${limit}&status=${statusFilter}`), }); const items = data?.data ?? EMPTY; const total = data?.meta?.totalRecords ?? 0; const approveMutation = useMutation({ mutationFn: (uuid: string) => api.post(`/api/v1/admin/pre-registrations/${uuid}/approve`, {}), onSuccess: () => { toast.success('درخواست تأیید شد و اطلاعات ورود ارسال گردید'); setApproveTarget(null); qc.invalidateQueries({ queryKey: ['pre-registrations'] }); }, onError: (err: Error) => toast.error(err.message), }); const rejectMutation = useMutation({ mutationFn: ({ uuid, note }: { uuid: string; note: string }) => api.post(`/api/v1/admin/pre-registrations/${uuid}/reject`, { note: note || undefined }), onSuccess: () => { toast.success('درخواست رد شد'); setRejectTarget(null); setRejectNote(''); qc.invalidateQueries({ queryKey: ['pre-registrations'] }); }, onError: (err: Error) => toast.error(err.message), }); return (
{/* Tabs */}
{STATUS_TABS.map((tab) => ( ))}
{statusFilter === 'pending' && {isLoading ? Array.from({ length: 8 }).map((_, i) => ( {Array.from({ length: 6 }).map((_, j) => ( ))} )) : items.length === 0 ? ( ) : items.map((item) => { const typeMeta = TYPE_META[item.type] ?? { label: item.type, color: 'gray' }; const statusMeta = STATUS_META[item.status] ?? { label: item.status, color: 'gray' }; return ( {statusFilter === 'pending' && ( )} ); })}
نام موبایل نوع حساب توضیحات وضعیت تاریخ درخواست}
درخواستی یافت نشد
{item.name}
{item.mobile}
{typeMeta.label} {item.info || '—'} {statusMeta.label} {item.admin_note && (
{item.admin_note}
)}
{formatDate(String(item.created_at))}
{/* Approve Dialog */} approveTarget && approveMutation.mutate(approveTarget.uuid)} onCancel={() => setApproveTarget(null)} /> {/* Reject Dialog */} {rejectTarget && (
setRejectTarget(null)}>
e.stopPropagation()}>
رد درخواست — {rejectTarget.name}

در صورت تمایل دلیل رد را وارد کنید (اختیاری)