From 6c0c7d75b8c22b291113cad9412a77214b4dc392 Mon Sep 17 00:00:00 2001 From: Seu Nome Date: Sun, 2 Nov 2025 22:41:13 -0300 Subject: [PATCH] =?UTF-8?q?Descri=C3=A7=C3=A3o=20curta=20do=20que=20foi=20?= =?UTF-8?q?alterado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../secretaria/SecretaryAppointmentList.tsx | 195 ++++++++++++++++-- .../secretaria/SecretaryDoctorList.tsx | 67 +++++- .../secretaria/SecretaryDoctorSchedule.tsx | 9 + .../secretaria/SecretaryPatientList.tsx | 81 +++++++- .../secretaria/SecretaryReportList.tsx | 27 ++- src/pages/PainelSecretaria.tsx | 20 +- src/services/reports/reportService.ts | 3 + 7 files changed, 376 insertions(+), 26 deletions(-) diff --git a/src/components/secretaria/SecretaryAppointmentList.tsx b/src/components/secretaria/SecretaryAppointmentList.tsx index 0dc9e2995..2ea1d4ab0 100644 --- a/src/components/secretaria/SecretaryAppointmentList.tsx +++ b/src/components/secretaria/SecretaryAppointmentList.tsx @@ -1,6 +1,6 @@ import { useState, useEffect } from "react"; import toast from "react-hot-toast"; -import { Search, Plus, Eye, Edit, Trash2 } from "lucide-react"; +import { Search, Plus, Eye, Edit, Trash2, X } from "lucide-react"; import { appointmentService, type Appointment, @@ -25,9 +25,14 @@ export function SecretaryAppointmentList() { const [statusFilter, setStatusFilter] = useState("Todos"); const [typeFilter, setTypeFilter] = useState("Todos"); const [showCreateModal, setShowCreateModal] = useState(false); + const [modalMode, setModalMode] = useState<"create" | "edit">("create"); + const [selectedAppointment, setSelectedAppointment] = useState< + AppointmentWithDetails | null + >(null); const [patients, setPatients] = useState([]); const [doctors, setDoctors] = useState([]); - const [formData, setFormData] = useState({ + const [formData, setFormData] = useState({ + id: undefined, patient_id: "", doctor_id: "", scheduled_at: "", @@ -81,6 +86,28 @@ export function SecretaryAppointmentList() { loadDoctorsAndPatients(); }, []); + // Se outro componente pediu para abrir o modal de criação com paciente pré-selecionado + useEffect(() => { + const openFromSession = () => { + const patientId = sessionStorage.getItem("selectedPatientForAppointment"); + if (patientId) { + setFormData((prev: any) => ({ ...prev, patient_id: patientId })); + setModalMode("create"); + setShowCreateModal(true); + sessionStorage.removeItem("selectedPatientForAppointment"); + } + }; + + // Try on mount + openFromSession(); + + // Listen for explicit events + const handler = () => openFromSession(); + window.addEventListener("open-create-appointment", handler); + return () => window.removeEventListener("open-create-appointment", handler); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + // Função de filtro const filteredAppointments = appointments.filter((appointment) => { // Filtro de busca por nome do paciente ou médico @@ -91,13 +118,36 @@ export function SecretaryAppointmentList() { appointment.doctor?.full_name?.toLowerCase().includes(searchLower) || appointment.order_number?.toString().includes(searchTerm); + // Mapeia o valor selecionado no select para o valor real usado na API/data + const mapStatusFilterToValue = (label: string) => { + if (label === "Todos") return null; + const map: Record = { + Confirmada: "confirmed", + Agendada: "requested", + Cancelada: "cancelled", + "Concluída": "completed", + Concluida: "completed", + }; + return map[label] || label.toLowerCase(); + }; + + const mapTypeFilterToValue = (label: string) => { + if (label === "Todos") return null; + const map: Record = { + Presencial: "presencial", + Telemedicina: "telemedicina", + }; + return map[label] || label.toLowerCase(); + }; + + const statusValue = mapStatusFilterToValue(statusFilter); + const typeValue = mapTypeFilterToValue(typeFilter); + // Filtro de status - const matchesStatus = - statusFilter === "Todos" || appointment.status === statusFilter; + const matchesStatus = statusValue === null || appointment.status === statusValue; // Filtro de tipo - const matchesType = - typeFilter === "Todos" || appointment.appointment_type === typeFilter; + const matchesType = typeValue === null || appointment.appointment_type === typeValue; return matchesSearch && matchesStatus && matchesType; }); @@ -135,16 +185,25 @@ export function SecretaryAppointmentList() { } try { - await appointmentService.create({ - patient_id: formData.patient_id, - doctor_id: formData.doctor_id, - scheduled_at: new Date(formData.scheduled_at).toISOString(), - appointment_type: formData.appointment_type as - | "presencial" - | "telemedicina", - }); - - toast.success("Consulta agendada com sucesso!"); + if (modalMode === "edit" && formData.id) { + // Update only allowed fields per API types + const updatePayload: any = {}; + if (formData.scheduled_at) updatePayload.scheduled_at = new Date(formData.scheduled_at).toISOString(); + if (formData.notes) updatePayload.notes = formData.notes; + await appointmentService.update(formData.id, updatePayload); + toast.success("Consulta atualizada com sucesso!"); + } else { + await appointmentService.create({ + patient_id: formData.patient_id, + doctor_id: formData.doctor_id, + scheduled_at: new Date(formData.scheduled_at).toISOString(), + appointment_type: formData.appointment_type as + | "presencial" + | "telemedicina", + patient_notes: formData.notes, + }); + toast.success("Consulta agendada com sucesso!"); + } setShowCreateModal(false); loadAppointments(); } catch (error) { @@ -157,6 +216,23 @@ export function SecretaryAppointmentList() { loadAppointments(); }; + const handleViewAppointment = (appointment: AppointmentWithDetails) => { + setSelectedAppointment(appointment); + }; + + const handleEditAppointment = (appointment: AppointmentWithDetails) => { + setModalMode("edit"); + setFormData({ + id: appointment.id, + patient_id: appointment.patient_id || "", + doctor_id: appointment.doctor_id || "", + scheduled_at: appointment.scheduled_at || "", + appointment_type: appointment.appointment_type || "presencial", + notes: appointment.notes || "", + }); + setShowCreateModal(true); + }; + const handleClear = () => { setSearchTerm(""); setStatusFilter("Todos"); @@ -411,12 +487,14 @@ export function SecretaryAppointmentList() {
+
+
+ +