diff --git a/src/components/AgendarConsulta/CardConsulta.jsx b/src/components/AgendarConsulta/CardConsulta.jsx index 250a534d..acd627c7 100644 --- a/src/components/AgendarConsulta/CardConsulta.jsx +++ b/src/components/AgendarConsulta/CardConsulta.jsx @@ -1,23 +1,86 @@ -import React from 'react' +import React, { useState, useEffect } from 'react';import { GetDoctorByID } from '../utils/Functions-Endpoints/Doctor'; +import { GetPatientByID } from '../utils/Functions-Endpoints/Patient'; +import { useAuth } from '../utils/AuthProvider'; +import { useNavigate } from 'react-router-dom'; +import { useMemo } from 'react'; -const CardConsulta = ( {DadosConsulta, TabelaAgendamento} ) => { +const CardConsulta = ( {DadosConsulta, TabelaAgendamento, setShowDeleteModal} ) => { + const navigate = useNavigate(); + const {getAuthorizationHeader} = useAuth() + const authHeader = getAuthorizationHeader() + const [Paciente, setPaciente] = useState() + const [Medico, setMedico] = useState() - // Status (agendado, confirmado, realizado, cancelado) + const ids = useMemo(() => { + return { + doctor_id: DadosConsulta?.doctor_id, + patient_id: DadosConsulta?.patient_id, + status: DadosConsulta?.status + }; + }, [DadosConsulta]); + + + useEffect(() => { + const BuscarMedicoEPaciente = async () => { + if (!ids.doctor_id || !ids.patient_id || ids.status === 'nada') return; + + try { + const [Doctor, Patient] = await Promise.all([ + GetDoctorByID(ids.doctor_id, authHeader), + GetPatientByID(ids.patient_id, authHeader) + ]); + + setMedico(Doctor?.[0] || null); + setPaciente(Patient?.[0] || null); + } catch (error) { + console.error('Erro ao buscar médico/paciente:', error); + } + }; + + BuscarMedicoEPaciente(); + }, [ids, authHeader]); return (
- {DadosConsulta.status !== 'vazio'? + {DadosConsulta.id? +
-
-

{DadosConsulta.horario}|GEAP| {DadosConsulta.medico}

-
-
-

{DadosConsulta.paciente} - {DadosConsulta.motivo} - 23 anos

-
+
+
+

{DadosConsulta.horario} {Medico?.full_name}

+
+ +
+

{Paciente?.full_name} - {DadosConsulta.exam}

+
+
+ +
+ + + + + +
+
: null diff --git a/src/components/AgendarConsulta/FormNovaConsulta.jsx b/src/components/AgendarConsulta/FormNovaConsulta.jsx index 435bc8ee..bdae91d9 100644 --- a/src/components/AgendarConsulta/FormNovaConsulta.jsx +++ b/src/components/AgendarConsulta/FormNovaConsulta.jsx @@ -1,57 +1,21 @@ import InputMask from "react-input-mask"; import "./style/formagendamentos.css"; import { useState, useEffect } from "react"; +import { GetPatientByCPF } from "../utils/Functions-Endpoints/Patient"; +import { GetDoctorByName } from "../utils/Functions-Endpoints/Doctor"; +import { useAuth } from "../utils/AuthProvider"; +const FormNovaConsulta = ({ onCancel, onSave, setAgendamento, agendamento }) => { + const {getAuthorizationHeader} = useAuth() -const FormNovaConsulta = ({ onCancel, patientID }) => { - const [selectedFile, setSelectedFile] = useState(null); const [anexos, setAnexos] = useState([]); const [loadingAnexos, setLoadingAnexos] = useState(false); - const [paciente, setPaciente] = useState({}) + + const [acessibilidade, setAcessibilidade] = useState({cadeirante:false,idoso:false,gravida:false,bebe:false, autista:false }) - useEffect(() => { - if (!patientID) return; - - const fetchAnexos = async () => { - setLoadingAnexos(true); - try { - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}/anexos`); - const data = await res.json(); - setAnexos(data.data || []); - } catch (err) { - console.error("Erro ao buscar anexos:", err); - } finally { - setLoadingAnexos(false); - } - }; - - fetchAnexos(); - }, [patientID]); - - const handleUpload = async () => { - if (!selectedFile) return; - - const formData = new FormData(); - formData.append("file", selectedFile); - - try { - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}/anexos`, { - method: "POST", - body: formData - }); - if (res.ok) { - const novoAnexo = await res.json(); - setAnexos(prev => [...prev, novoAnexo]); - setSelectedFile(null); - } else { - console.error("Erro ao enviar anexo"); - } - } catch (err) { - console.error("Erro ao enviar anexo:", err); - } - }; + let authHeader = getAuthorizationHeader() const handleclickAcessibilidade = (id) => { @@ -62,112 +26,65 @@ const FormNovaConsulta = ({ onCancel, patientID }) => { else if(resultado === true){ setAcessibilidade({...acessibilidade, [id]:false})} console.log(id) } - - const FormatCPF = (valor) => { - console.log(valor) + const FormatCPF = (valor) => { const digits = String(valor).replace(/\D/g, '').slice(0, 11); - BuscarPacienteExistentePeloCPF(valor) - return digits .replace(/(\d{3})(\d)/, '$1.$2') .replace(/(\d{3})(\d)/, '$1.$2') .replace(/(\d{3})(\d{1,2})$/, '$1-$2'); } - - const FormatTelefones = (valor) => { - const digits = String(valor).replace(/\D/g, '').slice(0, 11); - return digits - .replace(/(\d)/, '($1') - .replace(/(\d{2})(\d)/, '$1) $2' ) - .replace(/(\d)(\d{4})/, '$1 $2') - .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); - console.log("Resultado:", result); - - 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); - } - //BuscarCPFnoBancodeDados(value) - } + const handleChange = (e) => { const {value, name} = e.target; - - console.log(value, name) - if(name === 'email'){ - setPaciente({...paciente, contato:{ - ...paciente.contato, + setAgendamento({...agendamento, contato:{ + ...agendamento.contato, email:value }}) - } else if(name === 'telefone'){ - setPaciente({...paciente, contato:{ - ...paciente.contato, - telefone1:FormatTelefones(value) - }}) + }else if(name === 'cpf'){ + + let cpfFormatted = FormatCPF(value) + const fetchPatient = async () => { + let patientData = await GetPatientByCPF(cpfFormatted, authHeader); + if (patientData) { + setAgendamento((prev) => ({ + ...prev, + nome: patientData.full_name, + patient_id: patientData.id + })); + }} + setAgendamento(prev => ({ ...prev, cpf: cpfFormatted })) + fetchPatient() + }else if(name==='convenio'){ + setAgendamento({...agendamento,insurance_provider:value}) + }else if(name ==='profissional'){ + + + const fetchDoctor = async () => { + let DoctorData = await GetDoctorByName(value, authHeader) + if(DoctorData){ + setAgendamento((prev) => ({ + ...prev, + doctor_id:DoctorData.id + })) + }} + fetchDoctor() } else{ - setPaciente({...paciente,[name]:value}) + setAgendamento({...agendamento,[name]:value}) } } const handleSubmit = (e) => { e.preventDefault(); alert("Agendamento salvo!"); + onSave(agendamento) }; return ( @@ -180,57 +97,33 @@ const FormNovaConsulta = ({ onCancel, patientID }) => {
- +
- e.target.value = FormatCPF(e.target.value)} /> +
-
- - -
+
-
-
- - -
- -
- - -
- -
- - -
-
+
- + + +
-
- - -
- -
- - -
+

Informações adicionais

@@ -243,7 +136,7 @@ const FormNovaConsulta = ({ onCancel, patientID }) => { onChange={(e) => setSelectedFile(e.target.files[0])} /> {selectedFile && ( - )} @@ -291,7 +184,7 @@ const FormNovaConsulta = ({ onCancel, patientID }) => {
- +
diff --git a/src/components/AgendarConsulta/TabelaAgendamentoDia.jsx b/src/components/AgendarConsulta/TabelaAgendamentoDia.jsx index da73a5af..a248f234 100644 --- a/src/components/AgendarConsulta/TabelaAgendamentoDia.jsx +++ b/src/components/AgendarConsulta/TabelaAgendamentoDia.jsx @@ -1,14 +1,34 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import CardConsulta from './CardConsulta'; import "./style/styleTabelas/tabeladia.css"; - -const TabelaAgendamentoDia = ({ handleClickAgendamento, agendamentos }) => { +const TabelaAgendamentoDia = ({ handleClickAgendamento, agendamentos, setShowDeleteModal }) => { + const [indiceAcesso, setIndiceAcesso] = useState(0) + const [Dia, setDia] = useState() const agendamentosDoDia = agendamentos?.semana1?.segunda || []; const nomeMedico = agendamentosDoDia.find(item => item.medico)?.medico || 'Profissional'; + let ListaDiasComAgendamentos = Object.keys(agendamentos) + + + + console.log(Dia, "hshdhshhsdhs") + + useEffect(() => { + setDia(ListaDiasComAgendamentos[indiceAcesso]) + }, [indiceAcesso]) + + + return (
+
+
+ +

{Dia}

+ +
+
@@ -18,12 +38,12 @@ const TabelaAgendamentoDia = ({ handleClickAgendamento, agendamentos }) => { - {agendamentosDoDia.map((agendamento, index) => ( + {agendamentos[Dia]?.map((agendamento, index) => ( diff --git a/src/components/AgendarConsulta/TabelaAgendamentoMes.jsx b/src/components/AgendarConsulta/TabelaAgendamentoMes.jsx index 7e404084..26dcb313 100644 --- a/src/components/AgendarConsulta/TabelaAgendamentoMes.jsx +++ b/src/components/AgendarConsulta/TabelaAgendamentoMes.jsx @@ -3,7 +3,8 @@ import React from 'react'; import dayjs from "dayjs"; import CardConsulta from './CardConsulta'; import "./style/styleTabelas/tabelames.css"; - +import { useEffect, useState } from 'react'; +import { useMemo } from 'react'; const TabelaAgendamentoMes = ({ ListarDiasdoMes, agendamentos }) => { @@ -12,19 +13,179 @@ const TabelaAgendamentoMes = ({ ListarDiasdoMes, agendamentos }) => { const mes = dataHoje.month() + 1; let ListaDiasDatas = ListarDiasdoMes(AnoAtual, mes); + const [AgendamentosSemanaisOrganizados, setAgendamentosSemanaisOrganizados] = useState({}) + const [indice, setIndice] = useState("10") - let segundas = ListaDiasDatas[0]; - let tercas = ListaDiasDatas[1]; - let quartas = ListaDiasDatas[2]; - let quintas = ListaDiasDatas[3]; - let sextas = ListaDiasDatas[4]; + const [AgendamentosMensaisOrganizados, setAgendamentosMensaisOrganizados] = useState({ + "01": { "nomeDoMes": "janeiro" }, + "02": { "nomeDoMes": "fevereiro" }, + "03": { "nomeDoMes": "março" }, + "04": { "nomeDoMes": "abril" }, + "05": { "nomeDoMes": "maio" }, + "06": { "nomeDoMes": "junho" }, + "07": { "nomeDoMes": "julho" }, + "08": { "nomeDoMes": "agosto" }, + "09": { "nomeDoMes": "setembro" }, + "10": { "nomeDoMes": "outubro" }, + "11": { "nomeDoMes": "novembro" }, + "12": { "nomeDoMes": "dezembro" } +}) + + + + + const OrganizarAgendamentosSemanais = useMemo(() => { + if (!agendamentos || Object.keys(agendamentos).length === 0) return {}; + + const DiasComAtendimentos = Object.keys(agendamentos) + const semanas = {} + + + for (let i = 0; i < DiasComAtendimentos.length; i++) { + const DiaComAtendimento = DiasComAtendimentos[i] + const [_, MesDoAgendamento, DiaDoAgendamento] = DiaComAtendimento.split("-") + + const data = dayjs(`${AnoAtual}-${MesDoAgendamento}-${DiaDoAgendamento}`) + const diaSemana = data.format('dddd') + const semanaKey = `semana${data.week()}` + + if (!semanas[semanaKey]) { + semanas[semanaKey] = { + segunda: [], terça: [], quarta: [], quinta: [], sexta: [] + } + } + + switch (diaSemana) { + case 'Monday': + semanas[semanaKey].segunda.push(...agendamentos[DiaComAtendimento]) + break + case 'Tuesday': + semanas[semanaKey].terça.push(...agendamentos[DiaComAtendimento]) + break + case 'Wednesday': + semanas[semanaKey].quarta.push(...agendamentos[DiaComAtendimento]) + break + case 'Thursday': + semanas[semanaKey].quinta.push(...agendamentos[DiaComAtendimento]) + break + case 'Friday': + semanas[semanaKey].sexta.push(...agendamentos[DiaComAtendimento]) + break + default: + break + } + } + + return semanas + }, [agendamentos, AnoAtual]) + + useEffect(() => { + setAgendamentosSemanaisOrganizados(OrganizarAgendamentosSemanais); + + + // NOTA: Ao carregar, o Indice é 0, que é a primeira semana. + }, [OrganizarAgendamentosSemanais]) + + useEffect(() => { + console.log(OrganizarAgendamentosMensais) + + + }, []) + + useEffect(() => { + console.log(AgendamentosMensaisOrganizados, 'aqui os agendamentos mensais') + }, [AgendamentosMensaisOrganizados]) + + const OrganizarAgendamentosMensais = useMemo(() => { + if (!AgendamentosSemanaisOrganizados || Object.keys(AgendamentosSemanaisOrganizados).length === 0) + return; + + // Cria uma cópia local do estado atual + const novoEstado = { ...AgendamentosMensaisOrganizados }; + + const indices = Object.keys(AgendamentosSemanaisOrganizados); + + for (let i = 0; i < indices.length; i++) { + const DictSemanais = AgendamentosSemanaisOrganizados[indices[i]]; + const indicesDictSemanais = Object.keys(DictSemanais); + + for (let d = 0; d < indicesDictSemanais.length; d++) { + const lista = DictSemanais[indicesDictSemanais[d]]; + + if (lista.length > 0) { + const [_, mesDaConsulta] = lista[0].scheduled_at.split("-"); + + // Cria o mês se ainda não existir + if (!novoEstado[mesDaConsulta]) { + novoEstado[mesDaConsulta] = { + nomeDoMes: AgendamentosMensaisOrganizados[mesDaConsulta]?.nomeDoMes || "", + }; + } + + // Garante que a semana existe + novoEstado[mesDaConsulta][indices[i]] = { + ...novoEstado[mesDaConsulta][indices[i]], + ...DictSemanais, + }; + } + } + } + + // Faz o set de uma vez só + setAgendamentosMensaisOrganizados(novoEstado); +}, [AgendamentosSemanaisOrganizados]); + + const AvançarMes = () => { + let Indice = parseInt(indice) + Indice += 1 + + console.log(Indice) + if(Indice < 10){ + Indice = "0" + Indice.toString() + console.log(Indice) + } + if(Indice === 13){ + return + }else{ + setIndice(Indice) + } + } + + const VoltarMes = () => { + let Indice = parseInt(indice) + + Indice -= 1 + + console.log(Indice) + if(Indice < 10){ + Indice = "0" + Indice.toString() + console.log(Indice) + } + if(Indice === "00"){ + return + }else{ + + setIndice(Indice) + } + + + } + return (
+
+
+ +

{AgendamentosMensaisOrganizados[indice].nomeDoMes}

+ + +
+

{agendamento.horario}

handleClickAgendamento(agendamento)}> - +
- + @@ -32,105 +193,33 @@ const TabelaAgendamentoMes = ({ ListarDiasdoMes, agendamentos }) => { - {agendamentos && Object.entries(agendamentos).map(([semana, dias], index) => ( - - {/* Coluna de Segunda-feira */} - + {Object.keys(AgendamentosMensaisOrganizados[indice]).map((semanaKey) => { + const semana = AgendamentosMensaisOrganizados[indice][semanaKey] + console.log(AgendamentosMensaisOrganizados[indice][semanaKey], 'ajdsahchbaohdfoduh') - {/* Coluna de Terça-feira */} - - {/* Coluna de Quarta-feira */} - + return( + + + { + semana && typeof semana === "object" && Object.keys(semana).map((dia) => ( + + ): null } + + )) + } + - {/* Coluna de Sexta-feira */} - - - ))} - + )})} +
SegSeg Ter Qua Qui
-
-

{segundas[index]}

-
- {(dias.segunda || []).slice(0, 3).map((consulta, idx) => ( - - ))} -
- {(dias.segunda || []).length > 3 ? -

+ {(dias.segunda || []).length - 3}

- : null} -
-
-
-

{tercas[index]}

-
- {(dias.terca || []).slice(0, 3).map((consulta, idx) => ( - - ))} -
- {(dias.terca || []).length > 3 ? -

+ {(dias.terca || []).length - 3}

- : null} -
-
-
-

{quartas[index]}

-
- {(dias.quarta || []).slice(0, 3).map((consulta, idx) => ( - - ))} -
- {(dias.quarta || []).length > 3 ? -

+ {(dias.quarta || []).length - 3}

- : null} -
-
+ + + + {semana[dia].length > 3 ? ( +
+

{` +${semana[dia].length - 2}`}

+
- {/* Coluna de Quinta-feira */} -
-
-

{quintas[index]}

-
- {(dias.quinta || []).slice(0, 3).map((consulta, idx) => ( - - ))} -
- {(dias.quinta || []).length > 3 ? -

+ {(dias.quinta || []).length - 3}

- : null} -
-
-
-

{sextas[index]}

-
- {(dias.sexta || []).slice(0, 3).map((consulta, idx) => ( - - ))} -
- {(dias.sexta || []).length > 3 ? -

+ {(dias.sexta || []).length - 3}

- : null} -
-
) diff --git a/src/components/AgendarConsulta/TabelaAgendamentoSemana.jsx b/src/components/AgendarConsulta/TabelaAgendamentoSemana.jsx index 3f3c2b61..95a32380 100644 --- a/src/components/AgendarConsulta/TabelaAgendamentoSemana.jsx +++ b/src/components/AgendarConsulta/TabelaAgendamentoSemana.jsx @@ -1,31 +1,150 @@ import React from 'react'; import CardConsulta from './CardConsulta'; import "./style/styleTabelas/tabelasemana.css"; +import dayjs from 'dayjs'; +import { useEffect, useState, useMemo } from 'react'; +import weekOfYear from 'dayjs/plugin/weekOfYear' +dayjs.extend(weekOfYear) +const TabelaAgendamentoSemana = ({ agendamentos, ListarDiasdoMes }) => { -const TabelaAgendamentoSemana = ({ agendamentos }) => { + // Armazena o objeto COMPLETO das semanas organizadas + const [semanasOrganizadas, setSemanasOrganizadas] = useState({}); + // Controla qual semana está sendo exibida (o índice da chave no objeto) + const [Indice, setIndice] = useState(0); + const dataHoje = dayjs(); + const AnoAtual = dataHoje.year(); + const mes = dataHoje.month() + 1; + + let DiasdoMes = ListarDiasdoMes(AnoAtual, mes) + + // Array de chaves (ex: ['semana40', 'semana41', ...]) + const chavesDasSemanas = Object.keys(semanasOrganizadas); + + // Armazena o total de semanas que foram organizadas (para definir os limites de navegação) + const totalSemanas = chavesDasSemanas.length; + + // --- LÓGICA DE ORGANIZAÇÃO (useMemo mantido para otimização) --- + + const OrganizarAgendamentosSemanais = useMemo(() => { + if (!agendamentos || Object.keys(agendamentos).length === 0) return {}; + + const DiasComAtendimentos = Object.keys(agendamentos) + const semanas = {} + + for (let i = 0; i < DiasComAtendimentos.length; i++) { + const DiaComAtendimento = DiasComAtendimentos[i] + const [_, MesDoAgendamento, DiaDoAgendamento] = DiaComAtendimento.split("-") + + const data = dayjs(`${AnoAtual}-${MesDoAgendamento}-${DiaDoAgendamento}`) + const diaSemana = data.format('dddd') + const semanaKey = `semana${data.week()}` + + if (!semanas[semanaKey]) { + semanas[semanaKey] = { + segunda: [], terça: [], quarta: [], quinta: [], sexta: [] + } + } + + switch (diaSemana) { + case 'Monday': + semanas[semanaKey].segunda.push(...agendamentos[DiaComAtendimento]) + break + case 'Tuesday': + semanas[semanaKey].terça.push(...agendamentos[DiaComAtendimento]) + break + case 'Wednesday': + semanas[semanaKey].quarta.push(...agendamentos[DiaComAtendimento]) + break + case 'Thursday': + semanas[semanaKey].quinta.push(...agendamentos[DiaComAtendimento]) + break + case 'Friday': + semanas[semanaKey].sexta.push(...agendamentos[DiaComAtendimento]) + break + default: + break + } + } + + return semanas + }, [agendamentos, AnoAtual]) // Adicionei AnoAtual como dependência por segurança + + // --- EFEITO PARA POPULAR O ESTADO --- + + useEffect(() => { + setSemanasOrganizadas(OrganizarAgendamentosSemanais); + // NOTA: Ao carregar, o Indice é 0, que é a primeira semana. + }, [OrganizarAgendamentosSemanais]) + + // --- NOVAS FUNÇÕES DE NAVEGAÇÃO --- + + const avancarSemana = () => { + // Avança se o índice atual não for o último (totalSemanas - 1) + if (Indice < totalSemanas - 1) { + setIndice(Indice + 1); + } + }; + + const voltarSemana = () => { + // Volta se o índice atual não for o primeiro (0) + if (Indice > 0) { + setIndice(Indice - 1); + } + }; - const agendamentoSemana = agendamentos?.semana1 || {}; - - const agendamentosDeSegunda = agendamentoSemana.segunda || []; - const agendamentosDeTerca = agendamentoSemana.terca || []; - const agendamentosDeQuarta = agendamentoSemana.quarta || []; - const agendamentosDeQuinta = agendamentoSemana.quinta || []; - const agendamentosDeSexta = agendamentoSemana.sexta || []; + // --- PREPARAÇÃO DOS DADOS PARA RENDERIZAÇÃO --- - + // Pega a chave da semana que deve ser exibida (usa o estado Indice) + const chaveDaSemanaAtual = chavesDasSemanas[Indice]; + + // Extrai os agendamentos da semana atual (ou um objeto vazio se não existir) + const semanaParaRenderizar = semanasOrganizadas[chaveDaSemanaAtual] || { + segunda: [], terça: [], quarta: [], quinta: [], sexta: [] + }; + + // Determina o número máximo de linhas/consultas const numLinhas = Math.max( - agendamentosDeSegunda.length, - agendamentosDeTerca.length, - agendamentosDeQuarta.length, - agendamentosDeQuinta.length, - agendamentosDeSexta.length + semanaParaRenderizar.segunda.length, + semanaParaRenderizar.terça.length, + semanaParaRenderizar.quarta.length, + semanaParaRenderizar.quinta.length, + semanaParaRenderizar.sexta.length ); + // Array de índices para iterar sobre as LINHAS da tabela + const indicesDeLinha = Array.from({ length: numLinhas }, (_, i) => i); + + // Título da semana (para mostrar ao usuário) + const tituloSemana = chaveDaSemanaAtual + ? `Semana ${chaveDaSemanaAtual.replace('semana', '')} / ${AnoAtual}` + : 'Nenhuma semana encontrada'; + + // --- RENDERIZAÇÃO --- return (
+ {/* Container de Navegação */} +
+ + +

{tituloSemana}

+ +
+ + {/* Tabela de Agendamentos */} @@ -38,28 +157,44 @@ const TabelaAgendamentoSemana = ({ agendamentos }) => { - {Array.from({ length: numLinhas }).map((_, index) => { - - const consultaSeg = agendamentosDeSegunda[index]; - const consultaTer = agendamentosDeTerca[index]; - const consultaQua = agendamentosDeQuarta[index]; - const consultaQui = agendamentosDeQuinta[index]; - const consultaSex = agendamentosDeSexta[index]; + {indicesDeLinha.map((indiceLinha) => ( + + {/* Célula para Horário (Pode ser ajustado para mostrar o horário real) */} + - - const horarioDaLinha = consultaSeg?.horario || consultaTer?.horario || consultaQua?.horario || consultaQui?.horario || consultaSex?.horario; - - return ( - - - - - - - - - ); - })} + {/* Mapeamento de COLUNAS (dias) */} + + + + + + + ))}
{horarioDaLinha}{consultaSeg && }{consultaTer && }{consultaQua && }{consultaQui && }{consultaSex && }
+ {semanaParaRenderizar.segunda[indiceLinha] + ? + : null + } + + {semanaParaRenderizar.terça[indiceLinha] + ? + : null + } + + {semanaParaRenderizar.quarta[indiceLinha] + ? + : null + } + + {semanaParaRenderizar.quinta[indiceLinha] + ? + : null + } + + {semanaParaRenderizar.sexta[indiceLinha] + ? + : null + } +
diff --git a/src/components/AgendarConsulta/style/styleTabelas/tabeladia.css b/src/components/AgendarConsulta/style/styleTabelas/tabeladia.css index 62284339..0e94023d 100644 --- a/src/components/AgendarConsulta/style/styleTabelas/tabeladia.css +++ b/src/components/AgendarConsulta/style/styleTabelas/tabeladia.css @@ -114,4 +114,9 @@ html[data-bs-theme="dark"] .mostrar-horario th { border: 1px solid #333; color: #e0e0e0; background-color: #232323; -} \ No newline at end of file +} +/* +.container-botons{ + margin-left: 10rem; + background-color: pink; +}*/ \ No newline at end of file diff --git a/src/components/AgendarConsulta/style/styleTabelas/tabelames.css b/src/components/AgendarConsulta/style/styleTabelas/tabelames.css index 5fbe05c0..21972607 100644 --- a/src/components/AgendarConsulta/style/styleTabelas/tabelames.css +++ b/src/components/AgendarConsulta/style/styleTabelas/tabelames.css @@ -219,4 +219,14 @@ html[data-bs-theme="dark"] .usuario-default { html[data-bs-theme="dark"] .cards-que-faltam { color: #90caf9; +} + +.cabecalho-tabela{ + color: white; + background-color: #005a9e; +} + +.container-botons{ + margin-left: 5rem; + } \ No newline at end of file diff --git a/src/components/utils/Functions-Endpoints/Doctor.js b/src/components/utils/Functions-Endpoints/Doctor.js index 2d6046f9..d3c0e28e 100644 --- a/src/components/utils/Functions-Endpoints/Doctor.js +++ b/src/components/utils/Functions-Endpoints/Doctor.js @@ -4,8 +4,6 @@ import API_KEY from "../apiKeys"; const GetDoctorByID = async (ID,authHeader) => { - console.log(authHeader, 'mostrando autorização dentro da função') - var myHeaders = new Headers(); myHeaders.append('apikey', API_KEY) myHeaders.append('Authorization', authHeader) @@ -23,4 +21,36 @@ return DictMedico } -export {GetDoctorByID} \ No newline at end of file +const GetAllDoctors = async (authHeader) => { + var myHeaders = new Headers(); + myHeaders.append("apikey", API_KEY); + myHeaders.append("Authorization", authHeader); + + var requestOptions = { + method: 'GET', + headers: myHeaders, + redirect: 'follow' + }; + + const result = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors", requestOptions) + const DictMedicos = await result.json() + return DictMedicos + } + + +const GetDoctorByName = async (nome, authHeader) => { + const Medicos = await GetAllDoctors(authHeader) + + for (let i = 0; i < Medicos.length; i++) { + + if (Medicos[i].full_name === nome) { + console.log('Medico encontrado:', Medicos[i]); + return Medicos[i]; + } + else{console.log("nada encontrado")} + } + + +} + +export {GetDoctorByID, GetDoctorByName} \ No newline at end of file diff --git a/src/components/utils/Functions-Endpoints/Patient.js b/src/components/utils/Functions-Endpoints/Patient.js index ad848545..14cbfd6c 100644 --- a/src/components/utils/Functions-Endpoints/Patient.js +++ b/src/components/utils/Functions-Endpoints/Patient.js @@ -4,8 +4,6 @@ import API_KEY from "../apiKeys"; const GetPatientByID = async (ID,authHeader) => { - console.log(authHeader, 'mostrando autorização dentro da função') - var myHeaders = new Headers(); myHeaders.append('apikey', API_KEY) myHeaders.append('Authorization', authHeader) diff --git a/src/pages/Agendamento.jsx b/src/pages/Agendamento.jsx index d693cfee..5266b66a 100644 --- a/src/pages/Agendamento.jsx +++ b/src/pages/Agendamento.jsx @@ -1,23 +1,78 @@ -import React, { useState, useMemo } from 'react'; - +import React, { useState, useMemo, useEffect } from 'react'; +import API_KEY from '../components/utils/apiKeys.js'; +import AgendamentoCadastroManager from './AgendamentoCadastroManager.jsx'; import TabelaAgendamentoDia from '../components/AgendarConsulta/TabelaAgendamentoDia'; import TabelaAgendamentoSemana from '../components/AgendarConsulta/TabelaAgendamentoSemana'; import TabelaAgendamentoMes from '../components/AgendarConsulta/TabelaAgendamentoMes'; import FormNovaConsulta from '../components/AgendarConsulta/FormNovaConsulta'; - +import { useAuth } from '../components/utils/AuthProvider.js'; // ✨ NOVO: Caminho de importação corrigido com base na sua estrutura de pastas import AgendamentosMes from '../components/AgendarConsulta/DadosConsultasMock.js'; + import dayjs from 'dayjs'; import "./style/Agendamento.css"; import './style/FilaEspera.css'; const Agendamento = () => { - const [FiladeEspera, setFiladeEspera] = useState(false); + const [FiladeEspera, setFiladeEspera] = useState(false); const [tabela, setTabela] = useState('diario'); const [PageNovaConsulta, setPageConsulta] = useState(false); const [searchTerm, setSearchTerm] = useState(''); + const [agendamentos, setAgendamentos] = useState() + const {getAuthorizationHeader} = useAuth() + const [DictAgendamentosOrganizados, setAgendamentosOrganizados ] = useState({}) + + const [showDeleteModal, setShowDeleteModal] = useState(false) + const [AgendamentoFiltrado, setAgendamentoFiltrado] = useState() + + + let authHeader = getAuthorizationHeader() + + const FiltrarAgendamentos = (listaTodosAgendamentos) => { + let DictAgendamentosOrganizados = {}; + + for (let i = 0; i < listaTodosAgendamentos.length; i++) { + const agendamento = listaTodosAgendamentos[i]; + const DiaAgendamento = agendamento.scheduled_at.split("T")[0]; + + console.log(DictAgendamentosOrganizados) + + if (DiaAgendamento in DictAgendamentosOrganizados) { + // já existe a data → adiciona na lista + DictAgendamentosOrganizados[DiaAgendamento].push(agendamento); + } else { + // não existe → cria nova key com uma lista + DictAgendamentosOrganizados[DiaAgendamento] = [agendamento]; + } + } + + // faz o set de uma vez só ✅ + setAgendamentosOrganizados(DictAgendamentosOrganizados); + + } + + // Requisição inicial para mostrar os agendamentos do banco de dados + useEffect(() => { + + var myHeaders = new Headers(); + myHeaders.append("Authorization", authHeader); + myHeaders.append("apikey", API_KEY) + + var requestOptions = { + method: 'GET', + headers: myHeaders, + redirect: 'follow' + }; + + fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?select&doctor_id&patient_id&status&scheduled_at&order&limit&offset", requestOptions) + .then(response => response.json()) + .then(result => {FiltrarAgendamentos(result); console.log(result, "aqui")}) + .catch(error => console.log('error', error)); + }, []) + + // Dados da fila de espera (sem alteração) const filaEsperaData = [ @@ -76,7 +131,7 @@ const Agendamento = () => { default: break } } - let ListaDiasDatas = [segundas, tercas, quartas, quintas, sextas] + let ListaDiasDatas = {segundas:segundas,tercas:tercas,quartas: quartas,quintas: quintas,sextas: sextas} return ListaDiasDatas } @@ -169,9 +224,9 @@ const Agendamento = () => {
- {tabela === "diario" && } - {tabela === 'semanal' && } - {tabela === 'mensal' && } + {tabela === "diario" && } + {tabela === 'semanal' && } + {tabela === 'mensal' && } ) @@ -216,8 +271,65 @@ const Agendamento = () => { ) : ( - + )} + + {showDeleteModal && ( +
+ e.target.classList.contains("modal") && setShowDeleteModal(false) + } + > +
+
+ +
+
+ Confirmação de Exclusão +
+ +
+ +
+

+ Tem certeza que deseja excluir este paciente? +

+
+ +
+ + + + + +
+
+
+
)} + + ) } diff --git a/src/pages/AgendamentoCadastroManager.jsx b/src/pages/AgendamentoCadastroManager.jsx new file mode 100644 index 00000000..7c976402 --- /dev/null +++ b/src/pages/AgendamentoCadastroManager.jsx @@ -0,0 +1,58 @@ +import React from 'react' +import FormNovaConsulta from '../components/AgendarConsulta/FormNovaConsulta' +import API_KEY from '../components/utils/apiKeys' +import { useAuth } from '../components/utils/AuthProvider' +import { useState } from 'react' +import dayjs from 'dayjs' + +const AgendamentoCadastroManager = () => { + + const {getAuthorizationHeader} = useAuth() + const [agendamento, setAgendamento] = useState({}) + + + let authHeader = getAuthorizationHeader() + + const handleSave = (Dict) => { + let DataAtual = dayjs() + var myHeaders = new Headers(); + myHeaders.append("apikey", API_KEY); + myHeaders.append("Authorization", authHeader); + myHeaders.append("Content-Type", "application/json"); + + var raw = JSON.stringify({ + "patient_id": Dict.patient_id, + "doctor_id": Dict.doctor_id, + "scheduled_at": DataAtual, + "duration_minutes": 30, + "appointment_type": "presencial", + "chief_complaint": "Dor de cabeça há 3 ", + "patient_notes": "Prefiro horário pela manhã", + "insurance_provider": "Unimed", + "created_by": "87f2662c-9da7-45c0-9e05-521d9d92d105" + }); + + var requestOptions = { + method: 'POST', + headers: myHeaders, + body: raw, + redirect: 'follow' + }; + + fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments", requestOptions) + .then(response => response.text()) + .then(result => console.log(result)) + .catch(error => console.log('error', error)); + + } + + return ( +
+ + + +
+ ) +} + +export default AgendamentoCadastroManager \ No newline at end of file diff --git a/src/pages/AgendamentoEditPage.jsx b/src/pages/AgendamentoEditPage.jsx new file mode 100644 index 00000000..46f37111 --- /dev/null +++ b/src/pages/AgendamentoEditPage.jsx @@ -0,0 +1,70 @@ +import React from 'react' +import FormNovaConsulta from '../components/AgendarConsulta/FormNovaConsulta' +import { useState } from 'react' +import { useParams } from 'react-router-dom' +import API_KEY from '../components/utils/apiKeys' +import { useAuth } from '../components/utils/AuthProvider' +import dayjs from 'dayjs' + + +const AgendamentoEditPage = () => { + + let DataAtual = dayjs() + const {getAuthorizationHeader} = useAuth() + const params = useParams() + const [PatientToPatch, setPatientToPatch] = useState({}) + + let id = params.id + + console.log(id) + + let authHeader = getAuthorizationHeader() + + const handleSave = (DictParaPatch) => { + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + myHeaders.append('apikey', API_KEY) + myHeaders.append("authorization", authHeader) + + console.log(DictParaPatch) + + var raw = JSON.stringify({"patient_id": DictParaPatch.patient_id, + "doctor_id": DictParaPatch.doctor_id, + "scheduled_at": DataAtual, + "duration_minutes": 30, + "appointment_type": "presencial", + "chief_complaint": "Dor de cabeça há 3 ", + "patient_notes": "Prefiro horário pela manhã", + "insurance_provider": "Unimed", + "created_by": "87f2662c-9da7-45c0-9e05-521d9d92d105" + + + }); + + console.log(DictParaPatch) + console.log(id) + + var requestOptions = { + method: 'PATCH', + headers: myHeaders, + body: raw, + redirect: 'follow' + }; + + fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?id=eq.${id}`, requestOptions) + .then(response => response.text()) + .then(result => console.log(result)) + .catch(error => console.log('error', error)); + } + + + return ( +
+ + + +
+ ) +} + +export default AgendamentoEditPage diff --git a/src/pages/DoctorTable.jsx b/src/pages/DoctorTable.jsx index 019f7f74..47d9aacb 100644 --- a/src/pages/DoctorTable.jsx +++ b/src/pages/DoctorTable.jsx @@ -71,7 +71,7 @@ function TableDoctor() { fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors", requestOptions) .then(response => response.json()) - .then(result => setMedicos(result)) + .then(result => {setMedicos(result); console.log(result)}) .catch(error => console.log('error', error)); }, []); diff --git a/src/pages/PatientCadastroManager.jsx b/src/pages/PatientCadastroManager.jsx index 701e6b5b..4672f813 100644 --- a/src/pages/PatientCadastroManager.jsx +++ b/src/pages/PatientCadastroManager.jsx @@ -171,7 +171,6 @@ function PatientCadastroManager( {setCurrentPage} ) { }); setShowModal(true); - setTimeout(() => { setShowModal(false); navigate('/secretaria/pacientes'); diff --git a/src/pages/TablePaciente.jsx b/src/pages/TablePaciente.jsx index a82e63d1..4386b1dc 100644 --- a/src/pages/TablePaciente.jsx +++ b/src/pages/TablePaciente.jsx @@ -102,7 +102,7 @@ function TablePaciente({ setCurrentPage, setPatientID }) { const authHeader = getAuthorizationHeader() - console.log(authHeader, 'aqui autorização') + console.log(authHeader) var myHeaders = new Headers(); myHeaders.append("apikey", API_KEY); @@ -115,7 +115,7 @@ function TablePaciente({ setCurrentPage, setPatientID }) { fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients", requestOptions) .then(response => response.json()) - .then(result => setPacientes(result)) + .then(result => {setPacientes(result); console.log(result)}) .catch(error => console.log('error', error)); }, [isAuthenticated, getAuthorizationHeader]); diff --git a/src/pages/style/Agendamento.css b/src/pages/style/Agendamento.css index 8df2e113..8d1e7eb4 100644 --- a/src/pages/style/Agendamento.css +++ b/src/pages/style/Agendamento.css @@ -118,7 +118,7 @@ border-radius: 10px; } -#status-card-consulta-confirmado, .legenda-item-confirmado { +#status-card-consulta-confirmado, .legenda-item-confirmed { background-color: #eef8fb; border:3px solid #d8dfe7; padding: 5px; @@ -288,4 +288,73 @@ html[data-bs-theme="dark"] { color: #fff; background-color: #005a9e; } -} \ No newline at end of file +} + +/* Estilo para o botão de Editar */ +.btn-edit-custom { + background-color: #FFF3CD; + color: #856404; +} + +/* Estilo para o botão de Excluir (Deletar) */ +.btn-delete-custom { + background-color: #F8D7DA; + color: #721C24; + padding: 10px; +} + +.cardconsulta{ + display:flex; + align-items: center; + flex-direction: row; +} + +.container-botons{ + display: flex; + flex-direction: row; +} + +#tabela-seletor-container { + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + + background-color: #fff; + border-radius: 8px; + padding: 6px 12px; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08); + + font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto; + width: fit-content; + margin: 0 auto; +} + +#tabela-seletor-container p { + margin: 0; + font-size: 23px; + font-weight: 500; + color: #4085f6; + text-align: center; + white-space: nowrap; +} + +#tabela-seletor-container button { + background: transparent; + border: none; + color: #555; + font-size: 20px; + cursor: pointer; + padding: 4px 6px; + border-radius: 6px; + transition: all 0.2s ease-in-out; +} + +#tabela-seletor-container button:hover { + background-color: rgba(0, 0, 0, 0.05); + color: #000; +} + +#tabela-seletor-container i { + pointer-events: none; +} diff --git a/src/perfis/perfil_secretaria/PerfilSecretaria.jsx b/src/perfis/perfil_secretaria/PerfilSecretaria.jsx index baa72a69..b59d2d22 100644 --- a/src/perfis/perfil_secretaria/PerfilSecretaria.jsx +++ b/src/perfis/perfil_secretaria/PerfilSecretaria.jsx @@ -15,6 +15,7 @@ import Details from "../../pages/Details"; import EditPage from "../../pages/EditPage"; import DoctorDetails from "../../pages/DoctorDetails"; import DoctorEditPage from "../../pages/DoctorEditPage"; +import AgendamentoEditPage from "../../pages/AgendamentoEditPage"; function PerfilSecretaria({ onLogout }) { return ( @@ -33,7 +34,8 @@ function PerfilSecretaria({ onLogout }) { } /> } /> } /> - } /> + } /> + } /> Página não encontrada} />