import React, { useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { PencilIcon, TrashIcon, CheckCircleIcon, XCircleIcon } from '@heroicons/react/24/outline'; import { toast } from 'sonner'; import { api } from '../lib/api'; import type { ApiResponse, PaginatedResponse } from '../lib/api'; import type { Representation, City } from '../types'; import { formatDate, formatNumber } from '../lib/utils'; import PageHeader from '../components/ui/PageHeader'; import { ActiveBadge } from '../components/ui/StatusBadge'; import ConfirmDialog from '../components/ui/ConfirmDialog'; import Modal from '../components/ui/Modal'; import SearchableSelect from '../components/ui/SearchableSelect'; function DetailRow({ label, value }: { label: string; value: React.ReactNode }) { return (
{label} {value ?? '—'}
); } export default function RepresentationDetailPage() { const { uuid } = useParams<{ uuid: string }>(); const navigate = useNavigate(); const qc = useQueryClient(); const [deleteOpen, setDeleteOpen] = useState(false); const [editOpen, setEditOpen] = useState(false); const [formData, setFormData] = useState({ full_name: '', city_id: '', mobile_number: '', commission_percent: '' }); const citiesQuery = useQuery({ queryKey: ['cities-select'], queryFn: () => api.get>('/api/v1/admin/cities?limit=200'), staleTime: 5 * 60_000, }); const cities: City[] = citiesQuery.data?.data ?? []; const { data, isLoading } = useQuery({ queryKey: ['representation', uuid], queryFn: () => api.get>(`/api/v1/representation/${uuid}`), enabled: !!uuid, }); const rep: Representation | undefined = (data?.data as any)?.data ?? data?.data; const updateMutation = useMutation({ mutationFn: (d: Partial) => api.patch>(`/api/v1/representation/${uuid}`, d), onSuccess: () => { toast.success('اطلاعات بروزرسانی شد'); setEditOpen(false); qc.invalidateQueries({ queryKey: ['representation', uuid] }); qc.invalidateQueries({ queryKey: ['representations'] }); }, onError: (err: Error) => toast.error(err.message), }); const toggleActiveMutation = useMutation({ mutationFn: () => api.patch>(`/api/v1/representation/${uuid}`, { active: !(rep?.active ?? rep?.is_active), }), onSuccess: () => { toast.success('وضعیت تغییر کرد'); qc.invalidateQueries({ queryKey: ['representation', uuid] }); }, onError: (err: Error) => toast.error(err.message), }); const deleteMutation = useMutation({ mutationFn: () => api.delete>(`/api/v1/representation/${uuid}`), onSuccess: () => { toast.success('نماینده حذف شد'); navigate('/admin/representations'); }, onError: (err: Error) => toast.error(err.message), }); const openEdit = () => { if (!rep) return; setFormData({ full_name: rep.full_name ?? rep.domain ?? '', city_id: rep.city_id ? String(rep.city_id) : '', mobile_number: rep.mobile_number ?? '', commission_percent: String(rep.commission_percent), }); setEditOpen(true); }; const isActive = rep?.active ?? rep?.is_active ?? false; if (isLoading) { return (
{[1, 2, 3, 4, 5].map((i) => (
))}
); } if (!rep) { return (
نماینده‌ای با این شناسه یافت نشد.
); } const name = rep.full_name ?? rep.domain ?? '—'; return (
} />
{/* Basic Info */}

اطلاعات پایه

{rep.mobile_number} : null } /> } />
{/* Bank Account */}

اطلاعات بانکی

{rep.bank_account ? ( <> {rep.bank_account.card} : null } /> {rep.bank_account.iban} : null } /> ) : (

اطلاعات بانکی ثبت نشده

)}
{/* Edit Modal */} setEditOpen(false)} footer={ <> } >
setFormData((p) => ({ ...p, full_name: e.target.value }))} className="cp-input h-11" />
({ value: String(c.id), label: c.name }))} value={formData.city_id || null} onChange={(v) => setFormData(p => ({ ...p, city_id: v ? String(v) : '' }))} placeholder="انتخاب شهر" isClearable />
setFormData((p) => ({ ...p, mobile_number: e.target.value }))} dir="ltr" className="cp-input h-11" />
setFormData((p) => ({ ...p, commission_percent: e.target.value }))} type="number" min="0" max="100" dir="ltr" className="cp-input h-11" />
deleteMutation.mutate()} onCancel={() => setDeleteOpen(false)} />
); }