import React, { useState, useEffect, useCallback } from 'react'; import { Plus, Search, Edit2, Trash2, UserCheck, Star, X, ImageIcon, Phone, Mail, FileText, CheckCircle2, ShieldCheck, Globe } from 'lucide-react'; import { toast } from 'react-hot-toast'; import api, { BASE_DOMAIN } from '../services/api'; import ConfirmModal from '../components/ui/ConfirmModal'; import MediaSelector from '../components/ui/MediaSelector'; import Spinner from '../components/ui/Spinner'; import Button from '../components/ui/Button'; import Modal from '../components/ui/Modal'; export interface Doctor { id: string; name: string; title?: string; clinicName?: string; avatarUrl?: string; bio?: string; cv?: string; phone?: string; email?: string; instagram?: string; isActive: boolean; order: number; _count?: { videos: number; }; createdAt: string; } export default function DoctorsManager() { const [doctors, setDoctors] = useState([]); const [isLoading, setIsLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(''); const [isModalOpen, setIsModalOpen] = useState(false); const [editingDoctor, setEditingDoctor] = useState(null); const [deleteTargetId, setDeleteTargetId] = useState(null); const [isAvatarMediaOpen, setIsAvatarMediaOpen] = useState(false); const [isCvDetailsOpen, setIsCvDetailsOpen] = useState(null); const [formData, setFormData] = useState({ name: '', title: '', clinicName: '', avatarUrl: '', bio: '', cv: '', phone: '', email: '', instagram: '', isActive: true, order: 0, }); const fetchDoctors = useCallback(async () => { try { setIsLoading(true); const res = await api.get('/doctors', { params: { search: searchTerm, limit: 100 }, }); const raw = res.data; const list = Array.isArray(raw?.doctors) ? raw.doctors : Array.isArray(raw?.data?.doctors) ? raw.data.doctors : Array.isArray(raw?.data) ? raw.data : Array.isArray(raw) ? raw : []; setDoctors(list); } catch (err) { console.error('Failed to fetch doctors:', err); toast.error('خطا در دریافت لیست پزشکان'); setDoctors([]); } finally { setIsLoading(false); } }, [searchTerm]); useEffect(() => { fetchDoctors(); }, [fetchDoctors]); const handleOpenModal = (doc?: Doctor) => { if (doc) { setEditingDoctor(doc); setFormData({ name: doc.name || '', title: doc.title || '', clinicName: doc.clinicName || '', avatarUrl: doc.avatarUrl || '', bio: doc.bio || '', cv: doc.cv || '', phone: doc.phone || '', email: doc.email || '', instagram: doc.instagram || '', isActive: doc.isActive !== false, order: doc.order || 0, }); } else { setEditingDoctor(null); setFormData({ name: '', title: 'دامپزشک و متخصص تغذیه', clinicName: '', avatarUrl: '', bio: '', cv: '', phone: '', email: '', instagram: '', isActive: true, order: doctors.length + 1, }); } setIsModalOpen(true); }; const handleSave = async (e: React.FormEvent) => { e.preventDefault(); if (!formData.name.trim()) { toast.error('لطفاً نام پزشک را وارد کنید'); return; } try { if (editingDoctor) { await api.put(`/doctors/${editingDoctor.id}`, formData); toast.success('اطلاعات پزشک با موفقیت بروزرسانی شد'); } else { await api.post('/doctors', formData); toast.success('پزشک جدید با موفقیت افزوده شد'); } setIsModalOpen(false); await fetchDoctors(); } catch (err) { console.error('Save failed:', err); toast.error('خطا در ذخیره‌سازی اطلاعات پزشک'); } }; const handleDelete = async () => { if (!deleteTargetId) return; try { await api.delete(`/doctors/${deleteTargetId}`); toast.success('پزشک با موفقیت حذف شد'); setDeleteTargetId(null); await fetchDoctors(); } catch (err) { console.error('Delete failed:', err); toast.error('خطا در حذف پزشک'); } }; return (
{/* Header */}

مدیریت پزشکان و کادر علمی

ثبت اطلاعات و رزومه (CV) دامپزشکان جهت انتساب به ویدئوها، مشاوره‌ها و معرفی کادر تخصصی

{/* Filter / Search */}
setSearchTerm(e.target.value)} className="w-full pl-4 pr-11 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-purple-600 transition-colors" />
مجموع: {doctors.length} نفر
{/* Grid List */} {isLoading ? (
) : doctors.length === 0 ? (

پزشکی یافت نشد

اولین پزشک یا متخصص کادر علمی را به سامانه اضافه کنید.

) : (
{doctors.map((doc) => (
{/* Status Badge */}
{doc.isActive ? 'فعال' : 'غیرفعال'}
{/* Avatar & Main Info */}
{doc.avatarUrl ? ( {doc.name} ) : ( )}

{doc.name}

{doc.title || 'پزشک متخصص'}

{doc.clinicName && (

{doc.clinicName}

)}
{/* Bio Summary */} {doc.bio && (

{doc.bio}

)} {/* Contact & CV Trigger */}
{doc.phone && ( {doc.phone} )} {doc.instagram && ( {doc.instagram} )} {doc.cv && ( )}
))}
)} {/* Modal Add/Edit */} {isModalOpen && ( setIsModalOpen(false)} title={editingDoctor ? 'ویرایش اطلاعات پزشک' : 'افزودن پزشک جدید به کادر علمی'} icon={UserCheck} maxWidth="2xl" footer={
} >
setFormData({ ...formData, name: e.target.value })} className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-xs focus:outline-none focus:border-purple-600 font-bold" />
setFormData({ ...formData, title: e.target.value })} className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-xs focus:outline-none focus:border-purple-600 font-bold" />
setFormData({ ...formData, clinicName: e.target.value })} className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-xs focus:outline-none focus:border-purple-600" />
setFormData({ ...formData, order: parseInt(e.target.value) || 0 })} className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-xs focus:outline-none focus:border-purple-600 font-bold" />
{/* Avatar Picker */}
{formData.avatarUrl ? ( Avatar preview ) : ( )}
setFormData({ ...formData, avatarUrl: e.target.value })} className="flex-1 px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-xs font-mono" dir="ltr" />
{/* Bio & CV */}