import { useState, useEffect } from "react"; import toast from "react-hot-toast"; import { Search, Plus, Eye, Calendar, Edit, Trash2, X } from "lucide-react"; import { doctorService, userService, type Doctor, type CrmUF, } from "../../services"; import type { CreateDoctorInput } from "../../services/users/types"; interface DoctorFormData { id?: string; full_name: string; cpf: string; email: string; phone_mobile: string; crm: string; crm_uf: string; specialty: string; birth_date?: string; } const UF_OPTIONS = [ "AC", "AL", "AP", "AM", "BA", "CE", "DF", "ES", "GO", "MA", "MT", "MS", "MG", "PA", "PB", "PR", "PE", "PI", "RJ", "RN", "RS", "RO", "RR", "SC", "SP", "SE", "TO", ]; // Helper para formatar nome do médico sem duplicar "Dr." const formatDoctorName = (fullName: string): string => { const name = fullName.trim(); // Verifica se já começa com Dr. ou Dr (case insensitive) if (/^dr\.?\s/i.test(name)) { return name; } return `Dr. ${name}`; }; // Função para formatar CPF: XXX.XXX.XXX-XX const formatCPF = (value: string): string => { const numbers = value.replace(/\D/g, ""); if (numbers.length === 0) return ""; if (numbers.length <= 3) return numbers; if (numbers.length <= 6) return `${numbers.slice(0, 3)}.${numbers.slice(3)}`; if (numbers.length <= 9) return `${numbers.slice(0, 3)}.${numbers.slice(3, 6)}.${numbers.slice(6)}`; return `${numbers.slice(0, 3)}.${numbers.slice(3, 6)}.${numbers.slice( 6, 9 )}-${numbers.slice(9, 11)}`; }; // Função para formatar telefone: (XX) XXXXX-XXXX const formatPhone = (value: string): string => { const numbers = value.replace(/\D/g, ""); if (numbers.length === 0) return ""; if (numbers.length <= 2) return `(${numbers}`; if (numbers.length <= 7) return `(${numbers.slice(0, 2)}) ${numbers.slice(2)}`; if (numbers.length <= 11) return `(${numbers.slice(0, 2)}) ${numbers.slice(2, 7)}-${numbers.slice( 7 )}`; return `(${numbers.slice(0, 2)}) ${numbers.slice(2, 7)}-${numbers.slice( 7, 11 )}`; }; export function SecretaryDoctorList({ onOpenSchedule, }: { onOpenSchedule?: (doctorId: string) => void; }) { const [doctors, setDoctors] = useState([]); const [loading, setLoading] = useState(false); const [searchTerm, setSearchTerm] = useState(""); const [specialtyFilter, setSpecialtyFilter] = useState("Todas"); // Modal states const [showModal, setShowModal] = useState(false); const [modalMode, setModalMode] = useState<"create" | "edit">("create"); const [formData, setFormData] = useState({ full_name: "", cpf: "", email: "", phone_mobile: "", crm: "", crm_uf: "", specialty: "", }); const [showViewModal, setShowViewModal] = useState(false); const [selectedDoctor, setSelectedDoctor] = useState(null); const loadDoctors = async () => { setLoading(true); try { const data = await doctorService.list(); setDoctors(Array.isArray(data) ? data : []); } catch (error) { console.error("Erro ao carregar médicos:", error); toast.error("Erro ao carregar médicos"); setDoctors([]); } finally { setLoading(false); } }; useEffect(() => { loadDoctors(); }, []); // Função de filtro const filteredDoctors = doctors.filter((doctor) => { // Filtro de busca por nome, CRM ou especialidade const searchLower = searchTerm.toLowerCase(); const matchesSearch = !searchTerm || doctor.full_name?.toLowerCase().includes(searchLower) || doctor.crm?.includes(searchTerm) || doctor.specialty?.toLowerCase().includes(searchLower); // Filtro de especialidade const matchesSpecialty = specialtyFilter === "Todas" || doctor.specialty === specialtyFilter; return matchesSearch && matchesSpecialty; }); const handleSearch = () => { loadDoctors(); }; const handleClear = () => { setSearchTerm(""); setSpecialtyFilter("Todas"); loadDoctors(); }; const handleNewDoctor = () => { setModalMode("create"); setFormData({ full_name: "", cpf: "", email: "", phone_mobile: "", crm: "", crm_uf: "", specialty: "", }); setShowModal(true); }; const handleEditDoctor = (doctor: Doctor) => { setModalMode("edit"); setFormData({ id: doctor.id, full_name: doctor.full_name || "", cpf: doctor.cpf || "", email: doctor.email || "", phone_mobile: doctor.phone_mobile || "", crm: doctor.crm || "", crm_uf: doctor.crm_uf || "", specialty: doctor.specialty || "", birth_date: doctor.birth_date || "", }); setShowModal(true); }; const handleFormSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); try { if (modalMode === "edit" && formData.id) { // Para edição, usa o endpoint antigo (PATCH /doctors/:id) // Remove formatação de telefone e CPF const cleanPhone = formData.phone_mobile ? formData.phone_mobile.replace(/\D/g, "") : undefined; const cleanCpf = formData.cpf.replace(/\D/g, ""); const doctorData = { full_name: formData.full_name, cpf: cleanCpf, email: formData.email, phone_mobile: cleanPhone, crm: formData.crm, crm_uf: formData.crm_uf as CrmUF, specialty: formData.specialty, birth_date: formData.birth_date || null, }; await doctorService.update(formData.id, doctorData); toast.success("Médico atualizado com sucesso!"); } else { // Para criação, usa o novo endpoint create-doctor com validações completas // Remove formatação de telefone e CPF const cleanPhone = formData.phone_mobile ? formData.phone_mobile.replace(/\D/g, "") : undefined; const cleanCpf = formData.cpf.replace(/\D/g, ""); const createData: CreateDoctorInput = { email: formData.email, full_name: formData.full_name, cpf: cleanCpf, crm: formData.crm, crm_uf: formData.crm_uf as CrmUF, specialty: formData.specialty || undefined, phone_mobile: cleanPhone, }; await userService.createDoctor(createData); toast.success("Médico cadastrado com sucesso!"); } setShowModal(false); loadDoctors(); } catch (error) { console.error("Erro ao salvar médico:", error); toast.error("Erro ao salvar médico"); } finally { setLoading(false); } }; const getInitials = (name: string) => { return name .split(" ") .map((n) => n[0]) .join("") .toUpperCase() .slice(0, 2); }; const getAvatarColor = (index: number) => { const colors = [ "bg-red-500", "bg-green-500", "bg-blue-500", "bg-yellow-500", "bg-purple-500", "bg-pink-500", "bg-indigo-500", "bg-teal-500", ]; return colors[index % colors.length]; }; return (
{/* Header */}

Médicos

Gerencie os médicos cadastrados

{/* Search and Filters */}
setSearchTerm(e.target.value)} className="w-full pl-10 pr-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent" />
Especialidade:
{/* Table */}
{loading ? ( ) : filteredDoctors.length === 0 ? ( ) : ( filteredDoctors.map((doctor, index) => ( )) )}
Médico Especialidade CRM Próxima Disponível Ações
Carregando médicos...
{searchTerm || specialtyFilter !== "Todas" ? "Nenhum médico encontrado com esses filtros" : "Nenhum médico encontrado"}
{getInitials(doctor.full_name || "")}

{formatDoctorName(doctor.full_name)}

{doctor.email}

{doctor.phone_mobile}

{doctor.specialty || "—"} {doctor.crm || "—"} {/* TODO: Buscar próxima disponibilidade */}—
{/* Modal de Formulário */} {showModal && (
{/* Header */}

{modalMode === "create" ? "Novo Médico" : "Editar Médico"}

{/* Form Content */}
setFormData({ ...formData, full_name: e.target.value }) } className="form-input" required placeholder="Dr. João Silva" />
setFormData({ ...formData, cpf: formatCPF(e.target.value), }) } className="form-input" required maxLength={14} placeholder="000.000.000-00" />
setFormData({ ...formData, birth_date: e.target.value, }) } className="form-input" />
setFormData({ ...formData, crm: e.target.value }) } className="form-input" required placeholder="123456" />
setFormData({ ...formData, email: e.target.value }) } className="form-input" required placeholder="medico@exemplo.com" />
setFormData({ ...formData, phone_mobile: formatPhone(e.target.value), }) } className="form-input" maxLength={15} placeholder="(11) 98888-8888" />
)} {/* Modal de Visualizar Médico */} {showViewModal && selectedDoctor && (

Visualizar Médico

Nome

{selectedDoctor.full_name}

Especialidade

{selectedDoctor.specialty || "—"}

CRM

{selectedDoctor.crm || "—"}

Email

{selectedDoctor.email || "—"}

)}
); }