import React, { useState, useEffect, useMemo } from "react"; import { useParams, useNavigate, useLocation } from "react-router-dom"; import DoctorForm from "../components/doctors/DoctorForm"; import { useAuth } from "../components/utils/AuthProvider"; import API_KEY from "../components/utils/apiKeys"; const ENDPOINT = "https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors"; const ENDPOINT_AVAILABILITY = "https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctor_availability"; const diasDaSemana = ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]; const weekdayNumToStr = { 0: "sunday", 1: "monday", 2: "tuesday", 3: "wednesday", 4: "thursday", 5: "friday", 6: "saturday", }; const weekdayStrToNum = Object.fromEntries( Object.entries(weekdayNumToStr).map(([num, str]) => [str, Number(num)]) ); const EditDoctorPage = () => { const { id } = useParams(); const navigate = useNavigate(); const location = useLocation(); const { getAuthorizationHeader } = useAuth(); const [doctor, setDoctor] = useState(null); const [availability, setAvailability] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isSaving, setIsSaving] = useState(false); const effectiveId = id; const getHeaders = () => { const myHeaders = new Headers(); const authHeader = getAuthorizationHeader(); if (authHeader) myHeaders.append("Authorization", authHeader); myHeaders.append("Content-Type", "application/json"); if (API_KEY) myHeaders.append("apikey", API_KEY); myHeaders.append("Prefer", "return=representation"); return myHeaders; }; const salvarDisponibilidades = async (doctorId, horariosAtualizados) => { try { const headers = getHeaders(); const promises = []; const currentIds = new Set(); for (const dia of horariosAtualizados) { if (dia.isChecked && dia.blocos.length > 0) { for (const bloco of dia.blocos) { const inicio = bloco.inicio.includes(":") ? bloco.inicio : bloco.inicio + ":00"; const termino = bloco.termino.includes(":") ? bloco.termino : bloco.termino + ":00"; const payload = { doctor_id: doctorId, weekday: weekdayNumToStr[dia.weekday], start_time: inicio, end_time: termino, slot_minutes: bloco.slot_minutes || 30, appointment_type: bloco.appointment_type || "presencial", active: true, }; if (bloco.id && !bloco.isNew) { currentIds.add(bloco.id); promises.push( fetch(`${ENDPOINT_AVAILABILITY}?id=eq.${bloco.id}`, { method: "PATCH", headers, body: JSON.stringify(payload), }).then((res) => { if (!res.ok) throw new Error(`Erro no PATCH: ${res.status}`); return { type: "PATCH", id: bloco.id }; }) ); } else { promises.push( fetch(ENDPOINT_AVAILABILITY, { method: "POST", headers, body: JSON.stringify(payload), }) .then((res) => res.json()) .then((data) => { const createdItem = Array.isArray(data) ? data[0] : data; if (createdItem && createdItem.id) { return { type: "POST", id: createdItem.id }; } return { type: "POST", id: null }; }) ); } } } } const results = await Promise.all(promises); results.forEach((res) => { if (res.type === "POST" && res.id) currentIds.add(res.id); }); const existingDisponibilidadesRes = await fetch( `${ENDPOINT_AVAILABILITY}?doctor_id=eq.${String(doctorId)}`, { method: "GET", headers } ); if (existingDisponibilidadesRes.ok) { const existingDisponibilidades = await existingDisponibilidadesRes.json(); const deletePromises = existingDisponibilidades .filter((disp) => !currentIds.has(disp.id)) .map((disp) => fetch(`${ENDPOINT_AVAILABILITY}?id=eq.${disp.id}`, { method: "DELETE", headers, }) ); await Promise.all(deletePromises); } const updatedResponse = await fetch( `${ENDPOINT_AVAILABILITY}?doctor_id=eq.${doctorId}&order=weekday.asc,start_time.asc`, { method: "GET", headers } ); if (updatedResponse.ok) { const updatedData = await updatedResponse.json(); setAvailability(updatedData); } } catch (error) { throw error; } }; const normalizeAvailabilityForForm = (availabilityData) => { if (!Array.isArray(availabilityData)) return []; const disponibilidadesMedico = availabilityData.filter((d) => String(d.doctor_id) === String(effectiveId) && d.active !== false ); const blocosPorDia = {}; disponibilidadesMedico.forEach((d) => { const num = typeof d.weekday === "string" ? weekdayStrToNum[d.weekday.toLowerCase()] : d.weekday; if (num === undefined || num === null) return; if (!blocosPorDia[num]) blocosPorDia[num] = []; blocosPorDia[num].push({ id: d.id, inicio: d.start_time?.substring(0, 5) || "07:00", termino: d.end_time?.substring(0, 5) || "17:00", slot_minutes: d.slot_minutes || 30, appointment_type: d.appointment_type || "presencial", isNew: false, }); }); const resultado = [1, 2, 3, 4, 5, 6, 0].map((weekday) => { const blocosDoDia = blocosPorDia[weekday] || []; return { dia: diasDaSemana[weekday], weekday: weekday, isChecked: blocosDoDia.length > 0, blocos: blocosDoDia.length > 0 ? blocosDoDia : [ { id: null, inicio: "07:00", termino: "17:00", slot_minutes: 30, appointment_type: "presencial", isNew: true, }, ], }; }); return resultado; }; const availabilityFormatted = useMemo(() => { return normalizeAvailabilityForForm(availability); }, [availability, effectiveId]); useEffect(() => { const fetchDoctorData = async () => { if (!effectiveId || effectiveId === "edit") { alert("ID do médico não encontrado"); navigate("/secretaria/medicos"); return; } try { const doctorResponse = await fetch(`${ENDPOINT}?id=eq.${effectiveId}`, { method: "GET", headers: getHeaders(), }); if (!doctorResponse.ok) { throw new Error("Erro ao carregar dados do médico"); } const doctorData = await doctorResponse.json(); if (doctorData.length === 0) { throw new Error("Médico não encontrado"); } setDoctor(doctorData[0]); const availabilityResponse = await fetch( `${ENDPOINT_AVAILABILITY}?doctor_id=eq.${effectiveId}&order=weekday.asc,start_time.asc`, { method: "GET", headers: getHeaders(), } ); if (availabilityResponse.ok) { const availabilityData = await availabilityResponse.json(); setAvailability(availabilityData); } else { setAvailability([]); } } catch (error) { alert("Erro ao carregar dados do médico"); navigate("/secretaria/medicos"); } finally { setIsLoading(false); } }; if (effectiveId) { fetchDoctorData(); } }, [effectiveId, navigate]); const handleSave = async (formData) => { const { availability: updatedAvailability, ...doctorDataToSave } = formData; try { setIsSaving(true); const response = await fetch(`${ENDPOINT}?id=eq.${effectiveId}`, { method: "PATCH", headers: getHeaders(), body: JSON.stringify(doctorDataToSave), }); if (!response.ok) { throw new Error("Erro ao salvar dados do médico"); } if (updatedAvailability && updatedAvailability.length > 0) { await salvarDisponibilidades(effectiveId, updatedAvailability); } alert("Médico e horários atualizados com sucesso!"); navigate("/secretaria/medicos"); } catch (error) { alert(`Erro ao salvar dados: ${error.message}`); } finally { setIsSaving(false); } console.log('Horários a serem salvos:', updatedAvailability); }; const handleCancel = () => { navigate("/secretaria/medicos"); }; if (isLoading) { return (
Carregando...

Carregando dados do médico ID: {effectiveId || "..."}

); } if (!doctor) { if (!isLoading) { return (
Médico não encontrado
); } return null; } const formData = { ...doctor, availability: (doctor && doctor.availability) ? doctor.availability : availabilityFormatted, }; return (

Editar Médico

); }; export default EditDoctorPage;