import React, { useEffect, useState, useCallback } from "react"; import { X, Loader2 } from "lucide-react"; import { appointmentService, patientService, doctorService, type Appointment, type Patient, type Doctor, } from "../../services"; import { useAuth } from "../../hooks/useAuth"; // Type aliases para compatibilidade com código antigo type Consulta = Appointment & { pacienteId?: string; medicoId?: string; dataHora?: string; observacoes?: string; }; type Paciente = Patient; type Medico = Doctor; interface ConsultaModalProps { isOpen: boolean; onClose: () => void; onSaved: (c: Consulta) => void; editing?: Consulta | null; defaultPacienteId?: string; defaultMedicoId?: string; lockPaciente?: boolean; // quando abrir a partir do prontuário lockMedico?: boolean; // quando médico logado não deve mudar } const TIPO_SUGESTOES = [ "Primeira consulta", "Retorno", "Acompanhamento", "Exame", "Telemedicina", ]; const ConsultaModal: React.FC = ({ isOpen, onClose, onSaved, editing, defaultPacienteId, defaultMedicoId, lockPaciente = false, lockMedico = false, }) => { const { user } = useAuth(); const [pacientes, setPacientes] = useState([]); const [medicos, setMedicos] = useState([]); const [loadingLists, setLoadingLists] = useState(false); const [pacienteId, setPacienteId] = useState(""); const [medicoId, setMedicoId] = useState(""); const [dataHora, setDataHora] = useState(""); // value for datetime-local const [tipo, setTipo] = useState(""); const [motivo, setMotivo] = useState(""); const [observacoes, setObservacoes] = useState(""); const [status, setStatus] = useState("agendada"); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); // Load supporting lists useEffect(() => { if (!isOpen) return; let active = true; (async () => { try { setLoadingLists(true); const [patients, doctors] = await Promise.all([ patientService.list().catch(() => []), doctorService.list().catch(() => []), ]); if (!active) return; setPacientes(patients); setMedicos(doctors); } finally { if (active) setLoadingLists(false); } })(); return () => { active = false; }; }, [isOpen]); // Initialize form when opening / editing changes useEffect(() => { if (!isOpen) return; if (editing) { setPacienteId(editing.pacienteId); setMedicoId(editing.medicoId); // Convert ISO to local datetime-local value try { const d = new Date(editing.dataHora); const local = new Date(d.getTime() - d.getTimezoneOffset() * 60000) .toISOString() .slice(0, 16); setDataHora(local); } catch { setDataHora(""); } setTipo(editing.tipo || ""); setMotivo(editing.motivo || ""); setObservacoes(editing.observacoes || ""); setStatus(editing.status || "agendada"); } else { setPacienteId(defaultPacienteId || ""); setMedicoId(defaultMedicoId || ""); setDataHora(""); setTipo(""); setMotivo(""); setObservacoes(""); setStatus("agendada"); } setError(null); setSaving(false); }, [isOpen, editing, defaultPacienteId, defaultMedicoId, user]); const closeOnEsc = useCallback( (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); }, [onClose] ); useEffect(() => { if (!isOpen) return; window.addEventListener("keydown", closeOnEsc); return () => window.removeEventListener("keydown", closeOnEsc); }, [isOpen, closeOnEsc]); if (!isOpen) return null; const validate = (): boolean => { if (!pacienteId) { setError("Selecione um paciente."); return false; } if (!medicoId) { setError("Selecione um médico."); return false; } if (!dataHora) { setError("Informe data e hora."); return false; } return true; }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!validate()) return; setSaving(true); setError(null); try { // Convert local datetime back to ISO const iso = new Date(dataHora).toISOString(); if (editing) { const payload: ConsultaUpdate = { dataHora: iso, tipo: tipo || undefined, motivo: motivo || undefined, observacoes: observacoes || undefined, status: status, }; const resp = await consultasService.atualizar(editing.id, payload); if (!resp.success || !resp.data) { throw new Error(resp.error || "Falha ao atualizar consulta"); } onSaved(resp.data); } else { const payload: ConsultaCreate = { pacienteId, medicoId, dataHora: iso, tipo: tipo || undefined, motivo: motivo || undefined, observacoes: observacoes || undefined, }; const resp = await consultasService.criar(payload); if (!resp.success || !resp.data) { throw new Error(resp.error || "Falha ao criar consulta"); } onSaved(resp.data); } onClose(); } catch (err) { const msg = err instanceof Error ? err.message : "Erro ao salvar"; setError(msg); } finally { setSaving(false); } }; const title = editing ? "Editar Consulta" : "Nova Consulta"; return (

{title}

{error && (
{error}
)}
setDataHora(e.target.value)} />
setTipo(e.target.value)} placeholder="Ex: Retorno" /> {TIPO_SUGESTOES.map((t) => (
setMotivo(e.target.value)} placeholder="Motivo principal" />