diff --git a/src/components/AgendarConsulta/FormNovaConsulta.jsx b/src/components/AgendarConsulta/FormNovaConsulta.jsx index 1e7fb54f..a17c2211 100644 --- a/src/components/AgendarConsulta/FormNovaConsulta.jsx +++ b/src/components/AgendarConsulta/FormNovaConsulta.jsx @@ -2,7 +2,11 @@ import InputMask from "react-input-mask"; import "./style/formagendamentos.css"; import { useState, useEffect } from "react"; -const FormNovaConsulta = ({ onCancel, patientID, profissionalId }) => { +const FormNovaConsulta = ({ onCancel, patientID }) => { + const [horariosDisponiveis, setHorariosDisponiveis] = useState([]); + const [carregandoHorarios, setCarregandoHorarios] = useState(false); + + const [isModoEmergencia, setIsModoEmergencia] = useState(false); const [selectedFile, setSelectedFile] = useState(null); const [anexos, setAnexos] = useState([]); const [loadingAnexos, setLoadingAnexos] = useState(false); @@ -14,11 +18,68 @@ const FormNovaConsulta = ({ onCancel, patientID, profissionalId }) => { bebe: false, autista: false, }); + const [dadosAtendimento, setDadosAtendimento] = useState({ + profissional: "", + tipoAtendimento: "", + unidade: "", + dataAtendimento: "", + inicio: "", + termino: "", + solicitante: "", + observacoes: "", + }); - const [disponibilidades, setDisponibilidades] = useState([]); - const [horarioSelecionado, setHorarioSelecionado] = useState(""); + // Variável de controle para saber se a grade de horário deve ser mostrada + const isReadyForSchedule = + dadosAtendimento.profissional && dadosAtendimento.dataAtendimento; + + const fetchHorariosDisponiveis = async (professionalId, date) => { + if (!isReadyForSchedule || isModoEmergencia) { + setHorariosDisponiveis([]); + return; + } + + setCarregandoHorarios(true); + setHorariosDisponiveis([]); + + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + + const payload = { + doctor_id: professionalId, + date: date, + }; + + var requestOptions = { + method: "POST", + headers: myHeaders, + body: JSON.stringify(payload), + redirect: "follow", + }; + + try { + const res = await fetch( + "https://mock.apidog.com/m1/1053378-0-default/rest/v1/doctor_availability", + requestOptions + ); + const data = await res.json(); + + const slots = data.data && Array.isArray(data.data) ? data.data : []; + + setHorariosDisponiveis(slots); + + // Limpa o horário se o que estava selecionado não existe mais na nova grade + if (dadosAtendimento.inicio && !slots.includes(dadosAtendimento.inicio)) { + setDadosAtendimento((prev) => ({ ...prev, inicio: "", termino: "" })); + } + } catch (err) { + console.error("Erro ao buscar horários disponíveis:", err); + setHorariosDisponiveis([]); + } finally { + setCarregandoHorarios(false); + } + }; - // Buscar anexos do paciente useEffect(() => { if (!patientID) return; @@ -40,48 +101,22 @@ const FormNovaConsulta = ({ onCancel, patientID, profissionalId }) => { fetchAnexos(); }, [patientID]); - // Buscar disponibilidades do médico useEffect(() => { - if (!profissionalId) return; - - const fetchDisponibilidades = async () => { - try { - const res = await fetch( - `https://mock.apidog.com/m1/1053378-0-default/rest/v1/doctor_availability?doctorId=${profissionalId}` - ); - const data = await res.json(); - setDisponibilidades(data.data || []); - } catch (err) { - console.error("Erro ao buscar disponibilidades:", err); - } - }; - - fetchDisponibilidades(); - }, [profissionalId]); - - // Função para criar intervalos de 30 minutos - const gerarIntervalos = (inicio, fim) => { - const horarios = []; - let horaAtual = new Date(`1970-01-01T${inicio}:00`); - const horaFim = new Date(`1970-01-01T${fim}:00`); - - while (horaAtual < horaFim) { - const proximo = new Date(horaAtual.getTime() + 30 * 60000); - if (proximo <= horaFim) { - horarios.push( - `${horaAtual.toTimeString().slice(0, 5)} - ${proximo - .toTimeString() - .slice(0, 5)}` - ); - } - horaAtual = proximo; + // Chama a busca apenas se estivermos no modo padrão E tivermos profissional e data + if (isReadyForSchedule && !isModoEmergencia) { + fetchHorariosDisponiveis( + dadosAtendimento.profissional, + dadosAtendimento.dataAtendimento + ); + } else if (!isReadyForSchedule) { + setHorariosDisponiveis([]); } - return horarios; - }; - - const intervalosDisponiveis = disponibilidades.flatMap((disp) => - gerarIntervalos(disp.horarioInicial, disp.horarioFinal) - ); + }, [ + dadosAtendimento.profissional, + dadosAtendimento.dataAtendimento, + isModoEmergencia, + isReadyForSchedule, + ]); const handleUpload = async () => { if (!selectedFile) return; @@ -110,14 +145,20 @@ const FormNovaConsulta = ({ onCancel, patientID, profissionalId }) => { }; const handleclickAcessibilidade = (id) => { - setAcessibilidade({ - ...acessibilidade, - [id]: !acessibilidade[id], - }); + let resultado = acessibilidade[id]; + + if (resultado === false) { + setAcessibilidade({ ...acessibilidade, [id]: true }); + console.log("mudou"); + } else if (resultado === true) { + setAcessibilidade({ ...acessibilidade, [id]: false }); + } + console.log(id); }; const FormatCPF = (valor) => { const digits = String(valor).replace(/\D/g, "").slice(0, 11); + BuscarPacienteExistentePeloCPF(valor); return digits .replace(/(\d{3})(\d)/, "$1.$2") @@ -134,6 +175,58 @@ const FormNovaConsulta = ({ onCancel, patientID, profissionalId }) => { .replace(/(\d{4})(\d{4})/, "$1-$2"); }; + const BuscarCPFnoBancodeDados = async (cpf) => { + var myHeaders = new Headers(); + myHeaders.append("Authorization", "Bearer "); + myHeaders.append("Content-Type", "application/json"); + + var raw = JSON.stringify({ + cpf: cpf, + }); + + var requestOptions = { + method: "POST", + headers: myHeaders, + body: raw, + redirect: "follow", + }; + + const response = await fetch( + "https://mock.apidog.com/m1/1053378-0-default/pacientes/validar-cpf", + requestOptions + ); + const result = await response.json(); + return result; + }; + + const BuscarPacienteExistentePeloCPF = async (value) => { + if (isNaN(value[13]) === false && value.length === 14) + try { + const result = await BuscarCPFnoBancodeDados(value); + + if (result.data.existe === true) { + var myHeaders = new Headers(); + myHeaders.append("Authorization", "Bearer "); + + var requestOptions = { + method: "GET", + headers: myHeaders, + redirect: "follow", + }; + + fetch( + "https://mock.apidog.com/m1/1053378-0-default/pacientes/", + requestOptions + ) + .then((response) => response.json()) + .then((result) => setPaciente(result.data)) + .catch((error) => console.log("error", error)); + } + } catch (error) { + console.log("error", error); + } + }; + const handleChange = (e) => { const { value, name } = e.target; @@ -158,13 +251,118 @@ const FormNovaConsulta = ({ onCancel, patientID, profissionalId }) => { } }; + const handleAtendimentoChange = (e) => { + const { value, name } = e.target; + setDadosAtendimento((prev) => ({ + ...prev, + [name]: value, + })); + }; + + const handleSubmitExcecao = async () => { + console.log( + "Modo Emergência Ativado: Tentando criar Exceção com novo endpoint." + ); + + const { + profissional, + dataAtendimento, + tipoAtendimento, + inicio, + termino, + observacoes, + } = dadosAtendimento; + + if ( + !profissional || + !dataAtendimento || + !tipoAtendimento || + !inicio || + !termino + ) { + alert( + "Por favor, preencha o Profissional, Data, Tipo e Horários para a exceção." + ); + return; + } + + const payload = { + doctor_id: profissional, + date: dataAtendimento, + start_time: inicio + ":00", + end_time: termino + ":00", + kind: "liberacao", + reason: tipoAtendimento, + }; + + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + + var requestOptions = { + method: "POST", + headers: myHeaders, + body: JSON.stringify(payload), + redirect: "follow", + }; + + try { + const response = await fetch( + "https://mock.apidog.com/m1/1053378-0-default/rest/v1/doctor_exceptions", + requestOptions + ); + const result = await response.json(); + + if (response.ok || response.status === 201) { + console.log("Exceção de emergência criada com sucesso:", result); + alert( + `Consulta de emergência agendada como exceção! Detalhes: ${JSON.stringify( + result + )}` + ); + } else { + console.error("Erro ao criar exceção de emergência:", result); + alert( + `Erro ao agendar exceção. Status: ${response.status}. Detalhes: ${ + result.message || JSON.stringify(result) + }` + ); + } + } catch (error) { + console.error("Erro na requisição para criar exceção:", error); + alert( + "Erro de comunicação com o servidor ou formato de resposta inválido." + ); + } + }; + + const handleSubmitPadrao = () => { + if (!isReadyForSchedule) { + alert( + "Por favor, preencha o Profissional e a Data do Atendimento antes de salvar." + ); + return; + } + if ( + !horariosDisponiveis.includes(dadosAtendimento.inicio) || + !horariosDisponiveis.includes(dadosAtendimento.termino) + ) { + alert( + "Por favor, selecione horários válidos dentro da grade do profissional." + ); + return; + } + + console.log("Salvando agendamento."); + alert("Agendamento salvo!"); + }; + const handleSubmit = (e) => { e.preventDefault(); - alert( - `Agendamento salvo! Horário selecionado: ${ - horarioSelecionado || "não selecionado" - }` - ); + if (isModoEmergencia) { + handleSubmitExcecao(); + } else { + handleSubmitPadrao(); + } }; return ( @@ -172,14 +370,16 @@ const FormNovaConsulta = ({ onCancel, patientID, profissionalId }) => {

Informações do paciente

- {/* Campos do paciente */} -
+
{
+ { onChange={(e) => (e.target.value = FormatCPF(e.target.value))} />
+ +
+ + +
+
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+
+ + +
+
+ + +
+ +
+ + +
- {/* Informações adicionais / anexos */}

Informações adicionais

+ @@ -228,63 +499,301 @@ const FormNovaConsulta = ({ onCancel, patientID, profissionalId }) => { )) )}
- - {/* Informações do atendimento */}

Informações do atendimento

+
+ + {isModoEmergencia && ( +

+ ⚠️ As informações de data e horário serão enviadas como uma + exceção fora da grade normal. +

+ )} +
+ +
+
handleclickAcessibilidade(e.currentTarget.id)} + > + accessible +
+ +
handleclickAcessibilidade(e.currentTarget.id)} + > + elderly +
+ +
handleclickAcessibilidade(e.currentTarget.id)} + > + + pregnant_woman + +
+ +
handleclickAcessibilidade(e.currentTarget.id)} + > + + + + + + +
+ +
handleclickAcessibilidade(e.currentTarget.id)} + > + + + +
+
- + {/* INPUT: Nome do profissional (usado para habilitar a busca de horários) */} +
-
- -
-
- - {/* Seção de datas e horários */} -
-
- - -
- -
- - -
- -
- - - - {intervalosDisponiveis.map((horario, i) => ( - - ))} - + value={dadosAtendimento.tipoAtendimento} + onChange={handleAtendimentoChange} + />
-
- - -
+
+
+
+
+ + +
+ +
+ + {/* INPUT: Data de Atendimento (usada para habilitar a busca de horários) */} + +
+
+ +
+ {isModoEmergencia ? ( + // MODO EMERGÊNCIA: Input type="time" simples, sem restrição + <> +
+ + +
+
+ + +
+ + ) : // MODO PADRÃO + isReadyForSchedule ? ( + // ESTADO 2: Médico e Data ESCOLHIDOS -> Restringe para grade (SELECT) + <> +
+ + {carregandoHorarios ? ( + + ) : ( + + )} +
+ +
+ + +
+ + ) : ( + // ESTADO 1: Médico ou Data PENDENTE -> Permite entrada de tempo livre (INPUT TYPE="TIME") + <> +
+ + +
+
+ + +
+ + )} + +
+ + +
+
+
+ +
+
+ + +
+
+