"use client"; import { useState, useEffect } from "react"; import PatientLayout from "@/components/patient-layout"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Calendar, Clock, MapPin, Phone, User, X, CalendarDays } from "lucide-react"; import { toast } from "sonner"; import { appointmentsService } from "@/services/appointmentsApi.mjs"; import { patientsService } from "@/services/patientsApi.mjs"; import { doctorsService } from "@/services/doctorsApi.mjs"; import { usersService } from "@/services/usersApi.mjs"; const APPOINTMENTS_STORAGE_KEY = "clinic-appointments"; interface UserPermissions { isAdmin: boolean; isManager: boolean; isDoctor: boolean; isSecretary: boolean; isAdminOrManager: boolean; } interface UserData { user: { id: string; email: string; email_confirmed_at: string | null; created_at: string | null; last_sign_in_at: string | null; }; profile: { id: string; full_name: string; email: string; phone: string; avatar_url: string | null; disabled: boolean; created_at: string | null; updated_at: string | null; }; roles: string[]; permissions: UserPermissions; } export default function PatientAppointments() { const [appointments, setAppointments] = useState([]); const [isLoading, setIsLoading] = useState(true); const [selectedAppointment, setSelectedAppointment] = useState(null); const [userData, setUserData] = useState(); // Modais const [rescheduleModal, setRescheduleModal] = useState(false); const [cancelModal, setCancelModal] = useState(false); // Formulário de reagendamento/cancelamento const [rescheduleData, setRescheduleData] = useState({ date: "", time: "", reason: "" }); const [cancelReason, setCancelReason] = useState(""); const timeSlots = ["08:00", "08:30", "09:00", "09:30", "10:00", "10:30", "11:00", "11:30", "14:00", "14:30", "15:00", "15:30", "16:00", "16:30", "17:00", "17:30"]; const fetchData = async () => { setIsLoading(true); try { const queryParams = "order=scheduled_at.desc"; const appointmentList = await appointmentsService.search_appointment(queryParams); const patientList = await patientsService.list(); const doctorList = await doctorsService.list(); const user = await usersService.getMe(); setUserData(user); const doctorMap = new Map(doctorList.map((d: any) => [d.id, d])); const patientMap = new Map(patientList.map((p: any) => [p.id, p])); console.log(appointmentList); // Filtra apenas as consultas do paciente logado const patientAppointments = appointmentList .filter((apt: any) => apt.patient_id === userData?.user.id) .map((apt: any) => ({ ...apt, doctor: doctorMap.get(apt.doctor_id) || { full_name: "Médico não encontrado", specialty: "N/A" }, patient: patientMap.get(apt.patient_id) || { full_name: "Paciente não encontrado" }, })); setAppointments(patientAppointments); } catch (error) { console.error("Erro ao carregar consultas:", error); toast.error("Não foi possível carregar suas consultas."); } finally { setIsLoading(false); } }; useEffect(() => { fetchData(); }, []); const getStatusBadge = (status: string) => { switch (status) { case "requested": return Solicitada; case "confirmed": return Confirmada; case "checked_in": return Check-in; case "completed": return Realizada; case "cancelled": return Cancelada; default: return {status}; } }; const handleReschedule = (appointment: any) => { setSelectedAppointment(appointment); setRescheduleData({ date: "", time: "", reason: "" }); setRescheduleModal(true); }; const handleCancel = (appointment: any) => { setSelectedAppointment(appointment); setCancelReason(""); setCancelModal(true); }; const confirmReschedule = async () => { if (!rescheduleData.date || !rescheduleData.time) { toast.error("Por favor, selecione uma nova data e horário."); return; } try { const newScheduledAt = new Date(`${rescheduleData.date}T${rescheduleData.time}:00Z`).toISOString(); await appointmentsService.update(selectedAppointment.id, { scheduled_at: newScheduledAt, status: "requested", }); setAppointments((prev) => prev.map((apt) => (apt.id === selectedAppointment.id ? { ...apt, scheduled_at: newScheduledAt, status: "requested" } : apt))); setRescheduleModal(false); toast.success("Consulta reagendada com sucesso!"); } catch (error) { console.error("Erro ao reagendar consulta:", error); toast.error("Não foi possível reagendar a consulta."); } }; const confirmCancel = async () => { if (!cancelReason.trim() || cancelReason.trim().length < 10) { toast.error("Por favor, informe um motivo de cancelamento (mínimo 10 caracteres)."); return; } try { await appointmentsService.update(selectedAppointment.id, { status: "cancelled", cancel_reason: cancelReason, }); setAppointments((prev) => prev.map((apt) => (apt.id === selectedAppointment.id ? { ...apt, status: "cancelled" } : apt))); setCancelModal(false); toast.success("Consulta cancelada com sucesso!"); } catch (error) { console.error("Erro ao cancelar consulta:", error); toast.error("Não foi possível cancelar a consulta."); } }; return (

Minhas Consultas

Veja, reagende ou cancele suas consultas

{isLoading ? (

Carregando suas consultas...

) : appointments.length > 0 ? ( appointments.map((appointment) => (
{appointment.doctor.full_name} {appointment.doctor.specialty}
{getStatusBadge(appointment.status)}
{new Date(appointment.scheduled_at).toLocaleDateString("pt-BR", { timeZone: "UTC" })}
{new Date(appointment.scheduled_at).toLocaleTimeString("pt-BR", { hour: "2-digit", minute: "2-digit", timeZone: "UTC", })}
{appointment.doctor.location || "Local a definir"}
{appointment.doctor.phone || "N/A"}
{appointment.status !== "cancelled" && (
)}
)) ) : (

Você ainda não possui consultas agendadas.

)}
{/* MODAL DE REAGENDAMENTO */} Reagendar Consulta Escolha uma nova data e horário para sua consulta com {selectedAppointment?.doctor?.full_name}.
setRescheduleData((prev) => ({ ...prev, date: e.target.value }))} min={new Date().toISOString().split("T")[0]} />