// ARQUIVO COMPLETO COM A INTERFACE CORRIGIDA: app/doctor/consultas/page.tsx "use client"; import type React from "react"; import { useState, useEffect, useMemo } from "react"; import DoctorLayout from "@/components/doctor-layout"; import { useAuthLayout } from "@/hooks/useAuthLayout"; import { appointmentsService } from "@/services/appointmentsApi.mjs"; import { patientsService } from "@/services/patientsApi.mjs"; import { doctorsService } from "@/services/doctorsApi.mjs"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Calendar as CalendarShadcn } from "@/components/ui/calendar"; import { Separator } from "@/components/ui/separator"; import { Clock, Calendar as CalendarIcon, User, X, RefreshCw, Loader2, MapPin, Phone, List } from "lucide-react"; import { format, isFuture, parseISO, isValid, isToday, isTomorrow } from "date-fns"; import { ptBR } from "date-fns/locale"; import { toast } from "sonner"; // Interfaces (sem alteração) interface EnrichedAppointment { id: string; patientName: string; patientPhone: string; scheduled_at: string; status: "requested" | "confirmed" | "completed" | "cancelled" | "checked_in" | "no_show"; location: string; } export default function DoctorAppointmentsPage() { const { user, isLoading: isAuthLoading } = useAuthLayout({ requiredRole: 'medico' }); const [allAppointments, setAllAppointments] = useState([]); const [isLoading, setIsLoading] = useState(true); const [selectedDate, setSelectedDate] = useState(new Date()); const fetchAppointments = async (authUserId: string) => { setIsLoading(true); try { const allDoctors = await doctorsService.list(); const currentDoctor = allDoctors.find((doc: any) => doc.user_id === authUserId); if (!currentDoctor) { toast.error("Perfil de médico não encontrado para este usuário."); return setIsLoading(false); } const doctorId = currentDoctor.id; const [appointmentsList, patientsList] = await Promise.all([ appointmentsService.search_appointment(`doctor_id=eq.${doctorId}&order=scheduled_at.asc`), patientsService.list() ]); const patientsMap = new Map( patientsList.map((p: any) => [p.id, { name: p.full_name, phone: p.phone_mobile }]) ); const enrichedAppointments = appointmentsList.map((apt: any) => ({ id: apt.id, patientName: patientsMap.get(apt.patient_id)?.name || "Paciente Desconhecido", patientPhone: patientsMap.get(apt.patient_id)?.phone || "N/A", scheduled_at: apt.scheduled_at, status: apt.status, location: "Consultório Principal", })); setAllAppointments(enrichedAppointments); } catch (error) { console.error("Erro ao carregar a agenda:", error); toast.error("Não foi possível carregar sua agenda."); } finally { setIsLoading(false); } }; useEffect(() => { if (user?.id) { fetchAppointments(user.id); } }, [user]); const groupedAppointments = useMemo(() => { const appointmentsToDisplay = selectedDate ? allAppointments.filter(app => app.scheduled_at && app.scheduled_at.startsWith(format(selectedDate, "yyyy-MM-dd"))) : allAppointments.filter(app => { if (!app.scheduled_at) return false; const dateObj = parseISO(app.scheduled_at); return isValid(dateObj) && isFuture(dateObj); }); return appointmentsToDisplay.reduce((acc, appointment) => { const dateKey = format(parseISO(appointment.scheduled_at), "yyyy-MM-dd"); if (!acc[dateKey]) acc[dateKey] = []; acc[dateKey].push(appointment); return acc; }, {} as Record); }, [allAppointments, selectedDate]); const bookedDays = useMemo(() => { return allAppointments .map(app => app.scheduled_at ? new Date(app.scheduled_at) : null) .filter((date): date is Date => date !== null); }, [allAppointments]); const formatDisplayDate = (dateString: string) => { const date = parseISO(dateString); if (isToday(date)) return `Hoje, ${format(date, "dd 'de' MMMM", { locale: ptBR })}`; if (isTomorrow(date)) return `Amanhã, ${format(date, "dd 'de' MMMM", { locale: ptBR })}`; return format(date, "EEEE, dd 'de' MMMM", { locale: ptBR }); }; const getStatusVariant = (status: EnrichedAppointment['status']) => { switch (status) { case "confirmed": case "checked_in": return "default"; case "completed": return "secondary"; case "cancelled": case "no_show": return "destructive"; case "requested": return "outline"; default: return "outline"; } }; const handleCancel = async (id: string) => { // ... (função sem alteração) }; const handleReSchedule = (id: string) => { // ... (função sem alteração) }; if (isAuthLoading) { return
Carregando...
; } return (

Agenda Médica

Consultas para {user?.name || "você"}

{selectedDate ? `Agenda de ${format(selectedDate, "dd/MM/yyyy")}` : "Próximas Consultas"}

Filtrar por DataSelecione um dia para ver os detalhes.
{isLoading ? (
) : Object.keys(groupedAppointments).length === 0 ? ( Nenhuma consulta encontrada

{selectedDate ? "Não há agendamentos para esta data." : "Não há próximas consultas agendadas."}

) : ( Object.entries(groupedAppointments).map(([date, appointmentsForDay]) => (

{formatDisplayDate(date)}

{appointmentsForDay.map((appointment) => { const showActions = appointment.status === "requested" || appointment.status === "confirmed"; const scheduledAtDate = parseISO(appointment.scheduled_at); return ( // *** INÍCIO DA MUDANÇA NO CARD *** {/* Coluna 1: Nome e Hora */}
{appointment.patientName}
{format(scheduledAtDate, "HH:mm")}
{/* Coluna 2: Status e Telefone */}
{appointment.status.replace('_', ' ')}
{appointment.patientPhone}
{/* Coluna 3: Ações */}
{showActions && (
)}
// *** FIM DA MUDANÇA NO CARD *** ); })}
)) )}
); }