Função do agendamento GET para semana

This commit is contained in:
jp-lima 2025-10-13 15:49:38 -03:00
parent b949971a28
commit 39a78db8c5
9 changed files with 253 additions and 79 deletions

View File

@ -1,10 +1,24 @@
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';
const CardConsulta = ( {DadosConsulta, TabelaAgendamento} ) => {
const {getAuthorizationHeader} = useAuth()
const authHeader = getAuthorizationHeader()
const [Paciente, setPaciente] = useState()
const [Medico, setMedico] = useState()
const BuscarMedicoEPaciente = async () => {
const Doctor = await GetDoctorByID(DadosConsulta.doctor_id, authHeader)
const Patient = await GetPatientByID(DadosConsulta.patient_id, authHeader)
setMedico(Doctor[0])
setPaciente(Patient[0])
console.log(Doctor, Patient)
}
// Status (agendado, confirmado, realizado, cancelado)
useEffect(() => {
BuscarMedicoEPaciente()
}, [])
return (
<div className={`container-cardconsulta-${TabelaAgendamento}`}>
@ -12,11 +26,11 @@ const CardConsulta = ( {DadosConsulta, TabelaAgendamento} ) => {
{DadosConsulta.status !== 'vazio'?
<div className='cardconsulta' id={`status-card-consulta-${DadosConsulta.status}`}>
<section className='cardconsulta-infosecundaria'>
<p>{DadosConsulta.horario}|GEAP| {DadosConsulta.medico}</p>
<p>{DadosConsulta.horario}|GEAP| {Medico?.full_name}</p>
</section>
<section className='cardconsulta-infoprimaria'>
<p>{DadosConsulta.paciente} - {DadosConsulta.motivo} - 23 anos</p>
<p>{Paciente?.full_name} - {DadosConsulta.exam}</p>
</section>
</div>
:

View File

@ -1,14 +1,32 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import CardConsulta from './CardConsulta';
import "./style/styleTabelas/tabeladia.css";
const TabelaAgendamentoDia = ({ handleClickAgendamento, agendamentos }) => {
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 (
<div>
<div>
<button onClick={() => {if(indiceAcesso === 0)return; else(setIndiceAcesso(indiceAcesso - 1))}}>voltar</button>
<p>{Dia}</p>
<button onClick={() => {if(ListaDiasComAgendamentos.length - 1 === indiceAcesso)return; else(setIndiceAcesso(indiceAcesso + 1))}}>Avançar</button>
</div>
<table className='tabeladiaria'>
<thead>
<tr>
@ -18,7 +36,7 @@ const TabelaAgendamentoDia = ({ handleClickAgendamento, agendamentos }) => {
</thead>
<tbody>
{agendamentosDoDia.map((agendamento, index) => (
{agendamentos[Dia]?.map((agendamento, index) => (
<tr key={index}>
<td><p>{agendamento.horario}</p></td>
<td className='mostrar-horario'>

View File

@ -1,31 +1,151 @@
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 (
<div>
{/* Container de Navegação */}
<div className='navegacao-semanal' style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '15px' }}>
<button
onClick={voltarSemana}
disabled={Indice === 0} // Desabilita se for a primeira semana
>
&lt; Voltar
</button>
<h2>{tituloSemana}</h2>
<button
onClick={avancarSemana}
disabled={Indice === totalSemanas - 1 || totalSemanas === 0} // Desabilita se for a última semana ou se não houver semanas
>
Avançar &gt;
</button>
</div>
{/* Tabela de Agendamentos */}
<table className='tabelasemanal'>
<thead>
<tr>
@ -38,28 +158,44 @@ const TabelaAgendamentoSemana = ({ agendamentos }) => {
</tr>
</thead>
<tbody>
{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) => (
<tr key={indiceLinha}>
{/* Célula para Horário (Pode ser ajustado para mostrar o horário real) */}
<td></td>
const horarioDaLinha = consultaSeg?.horario || consultaTer?.horario || consultaQua?.horario || consultaQui?.horario || consultaSex?.horario;
return (
<tr key={index}>
<td>{horarioDaLinha}</td>
<td>{consultaSeg && <CardConsulta DadosConsulta={consultaSeg} />}</td>
<td>{consultaTer && <CardConsulta DadosConsulta={consultaTer} />}</td>
<td>{consultaQua && <CardConsulta DadosConsulta={consultaQua} />}</td>
<td>{consultaQui && <CardConsulta DadosConsulta={consultaQui} />}</td>
<td>{consultaSex && <CardConsulta DadosConsulta={consultaSex} />}</td>
</tr>
);
})}
{/* Mapeamento de COLUNAS (dias) */}
<td>
{semanaParaRenderizar.segunda[indiceLinha]
? <CardConsulta DadodsConsulta={semanaParaRenderizar.segunda[indiceLinha]} />
: null
}
</td>
<td>
{semanaParaRenderizar.terça[indiceLinha]
? <CardConsulta DadosConsulta={semanaParaRenderizar.terça[indiceLinha]} />
: null
}
</td>
<td>
{semanaParaRenderizar.quarta[indiceLinha]
? <CardConsulta DadosConsulta={semanaParaRenderizar.quarta[indiceLinha]} />
: null
}
</td>
<td>
{semanaParaRenderizar.quinta[indiceLinha]
? <CardConsulta DadosConsulta={semanaParaRenderizar.quinta[indiceLinha]} />
: null
}
</td>
<td>
{semanaParaRenderizar.sexta[indiceLinha]
? <CardConsulta DadosConsulta={semanaParaRenderizar.sexta[indiceLinha]} />
: null
}
</td>
</tr>
))}
</tbody>
</table>
</div>

View File

@ -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)

View File

@ -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)

View File

@ -19,9 +19,9 @@ const Agendamento = () => {
// Dados mocados para simular consultas com a API de Hugo
const Agendamentos = [
{
id: "9d5c7233-0437-4283-84cd-668714b1c6af",
id: "",
order_number: "APT-2025-0001",
patient_id: "47902ada-7d04-480a-a759-bae8a211973a",
patient_id: "a8039e6d-7271-4187-a719-e27d9c6d15b3",
appointment_type: "presencial",
cancellation_reason: null,
cancelled_at: null,
@ -30,7 +30,7 @@ const Agendamento = () => {
completed_at: null,
created_at: "2025-10-10T15:56:59.112231+00:00",
created_by: "87f2662c-9da7-45c0-9e05-521d9d92d105",
doctor_id: "16e93000-7239-4865-85f6-7f89af3ce5cd",
doctor_id: "c2715ddb-e8fb-4319-8015-4fd5df93a39b",
duration_minutes: 30,
insurance_provider: "Unimed",
notes: null,
@ -42,74 +42,85 @@ const Agendamento = () => {
},
// mesma data
{
id: "c8d87a3a-f221-4e88-a71e-947c03f3a9c2",
id: "",
order_number: "APT-2025-0002",
patient_id: "4b102ada-7d04-480a-a759-bae8a211973b",
patient_id: "becd4c18-042e-44ad-9bcb-cfef08f18046",
appointment_type: "presencial",
chief_complaint: "Retorno de consulta",
created_at: "2025-10-10T09:30:00.000+00:00",
scheduled_at: "2025-10-10T09:30:00.000+00:00",
doctor_id: "16e93000-7239-4865-85f6-7f89af3ce5cd",
doctor_id: "c2715ddb-e8fb-4319-8015-4fd5df93a39b",
duration_minutes: 45,
insurance_provider: "Amil",
status: "requested"
},
// dia anterior 1
{
id: "a3b77a12-1f11-45f8-912b-99372cd6a711",
id: "",
order_number: "APT-2025-0003",
patient_id: "57902ada-7d04-480a-a759-bae8a211973a",
patient_id: "e17e2bc6-6a90-4dc6-ae2d-b503e2835d36",
appointment_type: "teleconsulta",
chief_complaint: "Tosse persistente",
created_at: "2025-10-09T10:15:00.000+00:00",
scheduled_at: "2025-10-09T10:15:00.000+00:00",
doctor_id: "16e93000-7239-4865-85f6-7f89af3ce5cd",
doctor_id: "c2715ddb-e8fb-4319-8015-4fd5df93a39b",
duration_minutes: 20,
insurance_provider: "Bradesco Saúde",
status: "confirmed"
},
// dia anterior 2
{
id: "f77a42e1-b1a3-41af-8b4f-b92e8372bb20",
id: "",
order_number: "APT-2025-0004",
patient_id: "5a902ada-7d04-480a-a759-bae8a211973a",
patient_id: "d20e418f-6e45-495a-98be-16a9a163fab3",
appointment_type: "presencial",
chief_complaint: "Check-up anual",
created_at: "2025-10-09T14:00:00.000+00:00",
scheduled_at: "2025-10-09T14:00:00.000+00:00",
doctor_id: "16e93000-7239-4865-85f6-7f89af3ce5cd",
doctor_id: "c2715ddb-e8fb-4319-8015-4fd5df93a39b",
duration_minutes: 60,
insurance_provider: "Unimed",
status: "requested"
},
// dia seguinte
{
id: "b832a7e3-7319-4c22-b17b-922a6d4a9287",
id: "",
order_number: "APT-2025-0005",
patient_id: "6c902ada-7d04-480a-a759-bae8a211973a",
patient_id: "8f27e87d-851a-484a-8450-6e3a5f29476c",
appointment_type: "presencial",
chief_complaint: "Dor lombar",
created_at: "2025-10-11T11:45:00.000+00:00",
scheduled_at: "2025-10-11T11:45:00.000+00:00",
doctor_id: "16e93000-7239-4865-85f6-7f89af3ce5cd",
scheduled_at: "2025-10-08T11:45:00.000+00:00",
doctor_id: "9471fb52-4de6-4052-b173-1f0695173ba3",
duration_minutes: 30,
insurance_provider: "SulAmérica",
status: "requested"
},
// outro qualquer (para variedade)
{
id: "d112f76a-24a1-41de-8d03-9e8a20a73b54",
id: "",
order_number: "APT-2025-0006",
patient_id: "78902ada-7d04-480a-a759-bae8a211973a",
patient_id: "47902ada-7d04-480a-a759-bae8a211973a",
appointment_type: "teleconsulta",
chief_complaint: "Acompanhamento pós-cirurgia",
created_at: "2025-10-10T18:00:00.000+00:00",
scheduled_at: "2025-10-10T18:00:00.000+00:00",
doctor_id: "16e93000-7239-4865-85f6-7f89af3ce5cd",
doctor_id: "9471fb52-4de6-4052-b173-1f0695173ba3",
duration_minutes: 25,
insurance_provider: "Unimed",
status: "requested"
}
}, { id: "",
order_number: "APT-2025-0006",
patient_id: "47902ada-7d04-480a-a759-bae8a211973a",
appointment_type: "teleconsulta",
chief_complaint: "Acompanhamento pós-cirurgia",
created_at: "2025-10-10T18:00:00.000+00:00",
scheduled_at: "2025-10-24T18:00:00.000+00:00",
doctor_id: "9471fb52-4de6-4052-b173-1f0695173ba3",
duration_minutes: 25,
insurance_provider: "Unimed",
status: "requested"}
];
@ -155,7 +166,6 @@ const Agendamento = () => {
// faz o set de uma vez só
setAgendamentosOrganizados(DictAgendamentosOrganizados);
}
const handleSave = (Dict) => {
@ -190,9 +200,9 @@ fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments", requestOp
.catch(error => console.log('error', error));
}
// 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)
@ -205,11 +215,12 @@ fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments", requestOp
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(Agendamentos); console.log(Agendamentos)})
.then(result => {FiltrarAgendamentos(Agendamentos); console.log(Agendamentos, "aqui")})
.catch(error => console.log('error', error));
}, [])
// Dados da fila de espera (sem alteração)
const filaEsperaData = [
{ nome: 'Ricardo Pereira', email: 'ricardo.pereira@gmail.com', cpf: '444.777.666-55', telefone: '(79) 99123-4567', entrada: '25/09/2025 às 08:00' },
@ -267,7 +278,7 @@ fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments", requestOp
default: break
}
}
let ListaDiasDatas = [segundas, tercas, quartas, quintas, sextas]
let ListaDiasDatas = {segundas:segundas,tercas:tercas,quartas: quartas,quintas: quintas,sextas: sextas}
return ListaDiasDatas
}
@ -360,9 +371,9 @@ fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments", requestOp
</div>
</section>
{tabela === "diario" && <TabelaAgendamentoDia handleClickAgendamento={handleClickAgendamento} agendamentos={filteredAgendamentos} />}
{tabela === 'semanal' && <TabelaAgendamentoSemana agendamentos={filteredAgendamentos} />}
{tabela === 'mensal' && <TabelaAgendamentoMes ListarDiasdoMes={ListarDiasdoMes} aplicarCores={true} agendamentos={filteredAgendamentos} />}
{tabela === "diario" && <TabelaAgendamentoDia handleClickAgendamento={handleClickAgendamento} agendamentos={DictAgendamentosOrganizados} />}
{tabela === 'semanal' && <TabelaAgendamentoSemana agendamentos={DictAgendamentosOrganizados} ListarDiasdoMes={ListarDiasdoMes}/>}
{tabela === 'mensal' && <TabelaAgendamentoMes ListarDiasdoMes={ListarDiasdoMes} aplicarCores={true} agendamentos={DictAgendamentosOrganizados} />}
</div>
</div>
)

View File

@ -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));
}, []);

View File

@ -171,7 +171,6 @@ function PatientCadastroManager( {setCurrentPage} ) {
});
setShowModal(true);
setTimeout(() => {
setShowModal(false);
navigate('/secretaria/pacientes');

View File

@ -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]);