"use client"; import { usersService } from "services/usersApi.mjs"; import { doctorsService } from "services/doctorsApi.mjs"; import { appointmentsService } from "services/appointmentsApi.mjs"; import { AvailabilityService } from "services/availabilityApi.mjs"; import { useState, useEffect, useCallback } from "react"; import { Calendar, Clock, User } from "lucide-react"; import PatientLayout from "@/components/patient-layout"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; const API_URL = " https://yuanqfswhberkoevtmfr.supabase.co/"; interface Doctor { id: string; full_name: string; specialty: string; } interface Disponibilidade { weekday: string; start_time: string; end_time: string; slot_minutes?: number; } export default function ScheduleAppointment() { const [selectedDoctor, setSelectedDoctor] = useState(""); const [selectedDate, setSelectedDate] = useState(""); const [selectedTime, setSelectedTime] = useState(""); const [doctors, setDoctors] = useState([]); const [availableTimes, setAvailableTimes] = useState([]); const [loadingSlots, setLoadingSlots] = useState(false); const [loadingDoctors, setLoadingDoctors] = useState(true); const [tipoConsulta, setTipoConsulta] = useState("presencial"); const [duracao, setDuracao] = useState("30"); const [notes, setNotes] = useState(""); const fetchDoctors = useCallback(async () => { setLoadingDoctors(true); try { const data: Doctor[] = await doctorsService.list(); setDoctors(data || []); } catch (e) { console.error("Erro ao buscar médicos:", e); } finally { setLoadingDoctors(false); } }, []); const fetchAvailableSlots = useCallback( async (doctorId: string, date: string) => { if (!doctorId || !date) return; setLoadingSlots(true); setAvailableTimes([]); try { const disponibilidades: Disponibilidade[] = await AvailabilityService.listById(doctorId); const consultas = await appointmentsService.search_appointment( `doctor_id=eq.${doctorId}&scheduled_at=gte.${date}&scheduled_at=lt.${date}T23:59:59` ); const diaJS = new Date(date).getDay(); // Ajuste: Sunday = 0 -> API pode esperar 1-7 const diaAPI = diaJS === 0 ? 7 : diaJS; console.log("Disponibilidades recebidas: ", disponibilidades); console.log("Consultas do dia: ", consultas); const disponibilidadeDia = disponibilidades.find( (d: Disponibilidade) => Number(diaAPI) === getWeekdayNumber(d.weekday) ); if (!disponibilidadeDia) { console.log("Nenhuma disponibilidade para este dia"); setAvailableTimes([]); setLoadingSlots(false); return; } const [startHour, startMin] = disponibilidadeDia.start_time .split(":") .map(Number); const [endHour, endMin] = disponibilidadeDia.end_time .split(":") .map(Number); const slot = disponibilidadeDia.slot_minutes || 30; const horariosGerados: string[] = []; let atual = new Date(date); atual.setHours(startHour, startMin, 0, 0); const end = new Date(date); end.setHours(endHour, endMin, 0, 0); while (atual < end) { horariosGerados.push(atual.toTimeString().slice(0, 5)); atual = new Date(atual.getTime() + slot * 60 * 1000); } const ocupados = consultas.map((c: any) => c.scheduled_at.split("T")[1].slice(0, 5) ); const livres = horariosGerados.filter((h) => !ocupados.includes(h)); setAvailableTimes(livres); } catch (err) { console.error(err); setAvailableTimes([]); } finally { setLoadingSlots(false); } }, [] ); const getWeekdayNumber = (weekday: string) => { // Converte weekday API para número: 1=Monday ... 7=Sunday switch (weekday.toLowerCase()) { case "monday": return 1; case "tuesday": return 2; case "wednesday": return 3; case "thursday": return 4; case "friday": return 5; case "saturday": return 6; case "sunday": return 7; default: return 0; } }; useEffect(() => { fetchDoctors(); }, [fetchDoctors]); useEffect(() => { if (selectedDoctor && selectedDate) { fetchAvailableSlots(selectedDoctor, selectedDate); } else { setAvailableTimes([]); } setSelectedTime(""); }, [selectedDoctor, selectedDate, fetchAvailableSlots]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!selectedDoctor || !selectedDate || !selectedTime) { alert("Selecione médico, data e horário."); return; } const doctor = doctors.find((d) => d.id === selectedDoctor); const scheduledISO = `${selectedDate}T${selectedTime}:00Z`; const paciente = await usersService.getMe(); const body = { doctor_id: doctor?.id, patient_id: paciente.user.id, scheduled_at: scheduledISO, duration_minutes: Number(duracao), created_by: paciente.user.id, }; try { const res = await fetch(`${API_URL}/appointments`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); if (!res.ok) throw new Error("Erro ao agendar consulta"); alert("Consulta agendada com sucesso!"); setSelectedDoctor(""); setSelectedDate(""); setSelectedTime(""); setAvailableTimes([]); } catch (err) { console.error(err); alert("Falha ao agendar consulta"); } }; return (

Agendar Consulta

Dados da Consulta Escolha o médico, data e horário
{/* Médico */}
{/* Data */}
setSelectedDate(e.target.value)} min={new Date().toISOString().split("T")[0]} disabled={!selectedDoctor} />
{/* Horário */}
{/* Tipo e duração */}
setDuracao(e.target.value)} min={10} max={120} />
{/* Observações */}