Merge branch 'AgendamentoConsultas'
This commit is contained in:
commit
bba034c518
@ -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 (
|
||||
<div className={`container-cardconsulta-${TabelaAgendamento}`}>
|
||||
|
||||
{DadosConsulta.status !== 'vazio'?
|
||||
{DadosConsulta.id?
|
||||
|
||||
<div className='cardconsulta' id={`status-card-consulta-${DadosConsulta.status}`}>
|
||||
<section className='cardconsulta-infosecundaria'>
|
||||
<p>{DadosConsulta.horario}|GEAP| {DadosConsulta.medico}</p>
|
||||
</section>
|
||||
|
||||
<section className='cardconsulta-infoprimaria'>
|
||||
<p>{DadosConsulta.paciente} - {DadosConsulta.motivo} - 23 anos</p>
|
||||
</section>
|
||||
<div>
|
||||
<section className='cardconsulta-infosecundaria'>
|
||||
<p>{DadosConsulta.horario} {Medico?.full_name}</p>
|
||||
</section>
|
||||
|
||||
<section className='cardconsulta-infoprimaria'>
|
||||
<p>{Paciente?.full_name} - {DadosConsulta.exam}</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div className='container-botons'>
|
||||
<button className="btn btn-sm btn-edit-custom"
|
||||
|
||||
onClick={() => {navigate(`${DadosConsulta.id}/edit`)}}
|
||||
>
|
||||
<i className="bi bi-pencil me-1"></i> Editar
|
||||
</button>
|
||||
|
||||
|
||||
|
||||
<button
|
||||
className="btn btn-sm btn-delete-custom"
|
||||
onClick={() => {
|
||||
console.log(DadosConsulta.id)
|
||||
//setSelectedPatientId(DadosConsulta.id);
|
||||
setShowDeleteModal(true);
|
||||
}}
|
||||
>
|
||||
<i className="bi bi-trash me-1"></i> Excluir
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
:
|
||||
null
|
||||
|
||||
@ -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 <token>");
|
||||
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 <token>");
|
||||
|
||||
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 }) => {
|
||||
<div className="campos-informacoes-paciente" id="informacoes-paciente-linha-um">
|
||||
<div className="campo-de-input">
|
||||
<label>Nome *</label>
|
||||
<input type="text" name="nome" value={paciente.nome} placeholder="Insira o nome do paciente" required onChange={handleChange} />
|
||||
<input type="text" name="nome" value={agendamento.nome} placeholder="Insira o nome do paciente" required onChange={handleChange} />
|
||||
</div>
|
||||
|
||||
<div className="campo-de-input">
|
||||
<label>CPF do paciente</label>
|
||||
|
||||
<input type="text" name="cpf" placeholder="000.000.000-00" onChange={(e) => e.target.value = FormatCPF(e.target.value)} />
|
||||
<input type="text" name="cpf" placeholder="000.000.000-00" onChange={handleChange} value={agendamento.cpf}/>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="campo-de-input">
|
||||
<label>RG</label>
|
||||
<input type="text" name="rg" placeholder="Insira o nº do RG" maxLength={9} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div className="campos-informacoes-paciente" id="informacoes-paciente-linha-dois">
|
||||
<div className="campo-de-input">
|
||||
<label>Data de nascimento *</label>
|
||||
<input type="date" name="data_nascimento" value={paciente.data_nascimento} required onChange={handleChange}/>
|
||||
</div>
|
||||
|
||||
<div className="campo-de-input">
|
||||
<label>Telefone</label>
|
||||
<input type="tel" name="telefone" placeholder="(99) 99999-9999" value={paciente.contato?.telefone1} onChange={handleChange} />
|
||||
</div>
|
||||
|
||||
<div className="campo-de-input">
|
||||
<label>E-mail</label>
|
||||
<input type="email" name="email" placeholder="Email" value={paciente.contato?.email} onChange={handleChange} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="campos-informacoes-paciente" id="informacoes-paciente-linha-tres">
|
||||
|
||||
<div className="campo-de-input">
|
||||
<label>Convênio</label>
|
||||
<select name="convenio">
|
||||
<option value="particular">Particular</option>
|
||||
<select name="convenio" onChange={handleChange}>
|
||||
<option value="publico">Público</option>
|
||||
<option value="unimed">Unimed</option>
|
||||
<option value="bradesco_saude">Bradesco Saúde</option>
|
||||
<option value="hapvida">Hapvida</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="campo-de-input">
|
||||
<label>Matrícula</label>
|
||||
<input type="text" name="matricula" placeholder="000000000" />
|
||||
</div>
|
||||
|
||||
<div className="campo-de-input">
|
||||
<label>Validade</label>
|
||||
<input type="date" name="validade" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h3 className="section-subtitle">Informações adicionais</h3>
|
||||
@ -243,7 +136,7 @@ const FormNovaConsulta = ({ onCancel, patientID }) => {
|
||||
onChange={(e) => setSelectedFile(e.target.files[0])}
|
||||
/>
|
||||
{selectedFile && (
|
||||
<button type="button" className="btn btn-primary ms-2" onClick={handleUpload}>
|
||||
<button type="button" className="btn btn-primary ms-2" >
|
||||
Enviar
|
||||
</button>
|
||||
)}
|
||||
@ -291,7 +184,7 @@ const FormNovaConsulta = ({ onCancel, patientID }) => {
|
||||
|
||||
<div className="campo-de-input">
|
||||
<label>Nome do profissional *</label>
|
||||
<input type="text" name="profissional" required />
|
||||
<input type="text" name="profissional" onChange={handleChange} value={agendamento.nome_medico}required />
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@ -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 (
|
||||
<div>
|
||||
<div>
|
||||
<div id='tabela-seletor-container'>
|
||||
<button onClick={() => {if(indiceAcesso === 0)return; else(setIndiceAcesso(indiceAcesso - 1))}}> <i className="bi bi-chevron-compact-left"></i></button>
|
||||
<p>{Dia}</p>
|
||||
<button onClick={() => {if(ListaDiasComAgendamentos.length - 1 === indiceAcesso)return; else(setIndiceAcesso(indiceAcesso + 1))}}> <i className="bi bi-chevron-compact-right"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<table className='tabeladiaria'>
|
||||
<thead>
|
||||
<tr>
|
||||
@ -18,12 +38,12 @@ 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'>
|
||||
<div onClick={() => handleClickAgendamento(agendamento)}>
|
||||
<CardConsulta DadosConsulta={agendamento} TabelaAgendamento={'dia'} />
|
||||
<CardConsulta DadosConsulta={agendamento} TabelaAgendamento={'dia'} setShowDeleteModal={setShowDeleteModal} />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@ -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 (
|
||||
<div>
|
||||
<div >
|
||||
<div id='tabela-seletor-container'>
|
||||
<button onClick={() => VoltarMes()}><i className="bi bi-chevron-compact-left"></i></button>
|
||||
<p>{AgendamentosMensaisOrganizados[indice].nomeDoMes}</p>
|
||||
|
||||
<button onClick={() => AvançarMes()}> <i className="bi bi-chevron-compact-right"></i> </button>
|
||||
</div>
|
||||
</div>
|
||||
<table className='tabelamensal'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Seg</th>
|
||||
<td className='cabecalho-tabela'>Seg</td>
|
||||
<th>Ter</th>
|
||||
<th>Qua</th>
|
||||
<th>Qui</th>
|
||||
@ -32,105 +193,33 @@ const TabelaAgendamentoMes = ({ ListarDiasdoMes, agendamentos }) => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{agendamentos && Object.entries(agendamentos).map(([semana, dias], index) => (
|
||||
<tr key={index}>
|
||||
{/* Coluna de Segunda-feira */}
|
||||
<td>
|
||||
<div>
|
||||
<p>{segundas[index]}</p>
|
||||
<div>
|
||||
{(dias.segunda || []).slice(0, 3).map((consulta, idx) => (
|
||||
<CardConsulta
|
||||
key={idx}
|
||||
DadosConsulta={consulta}
|
||||
className={`usuario-${consulta.cor || "default"}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{(dias.segunda || []).length > 3 ?
|
||||
<div><p className='cards-que-faltam'>+ {(dias.segunda || []).length - 3}</p></div>
|
||||
: null}
|
||||
</div>
|
||||
</td>
|
||||
{Object.keys(AgendamentosMensaisOrganizados[indice]).map((semanaKey) => {
|
||||
const semana = AgendamentosMensaisOrganizados[indice][semanaKey]
|
||||
console.log(AgendamentosMensaisOrganizados[indice][semanaKey], 'ajdsahchbaohdfoduh')
|
||||
|
||||
{/* Coluna de Terça-feira */}
|
||||
<td>
|
||||
<div>
|
||||
<p>{tercas[index]}</p>
|
||||
<div>
|
||||
{(dias.terca || []).slice(0, 3).map((consulta, idx) => (
|
||||
<CardConsulta
|
||||
key={idx}
|
||||
DadosConsulta={consulta}
|
||||
className={`usuario-${consulta.cor || "default"}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{(dias.terca || []).length > 3 ?
|
||||
<div><p className='cards-que-faltam'>+ {(dias.terca || []).length - 3}</p></div>
|
||||
: null}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
{/* Coluna de Quarta-feira */}
|
||||
<td>
|
||||
<div>
|
||||
<p>{quartas[index]}</p>
|
||||
<div>
|
||||
{(dias.quarta || []).slice(0, 3).map((consulta, idx) => (
|
||||
<CardConsulta
|
||||
key={idx}
|
||||
DadosConsulta={consulta}
|
||||
className={`usuario-${consulta.cor || "default"}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{(dias.quarta || []).length > 3 ?
|
||||
<div><p className='cards-que-faltam'>+ {(dias.quarta || []).length - 3}</p></div>
|
||||
: null}
|
||||
</div>
|
||||
</td>
|
||||
return(
|
||||
<tr key={semanaKey}>
|
||||
|
||||
{
|
||||
semana && typeof semana === "object" && Object.keys(semana).map((dia) => (
|
||||
<td key={dia} >
|
||||
<CardConsulta DadosConsulta={((semana[dia]|| [])[0]) || {status:'vazio'}}/>
|
||||
<CardConsulta DadosConsulta={((semana[dia]|| [])[1]) || {status:'vazio'}}/>
|
||||
<CardConsulta DadosConsulta={((semana[dia]|| [])[2]) || {status:'vazio'}}/>
|
||||
{semana[dia].length > 3 ? (
|
||||
<div>
|
||||
<p>{` +${semana[dia].length - 2}`}</p>
|
||||
</div>
|
||||
|
||||
{/* Coluna de Quinta-feira */}
|
||||
<td>
|
||||
<div>
|
||||
<p>{quintas[index]}</p>
|
||||
<div>
|
||||
{(dias.quinta || []).slice(0, 3).map((consulta, idx) => (
|
||||
<CardConsulta
|
||||
key={idx}
|
||||
DadosConsulta={consulta}
|
||||
className={`usuario-${consulta.cor || "default"}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{(dias.quinta || []).length > 3 ?
|
||||
<div><p className='cards-que-faltam'>+ {(dias.quinta || []).length - 3}</p></div>
|
||||
: null}
|
||||
</div>
|
||||
</td>
|
||||
): null }
|
||||
</td>
|
||||
))
|
||||
}
|
||||
</tr>
|
||||
|
||||
{/* Coluna de Sexta-feira */}
|
||||
<td>
|
||||
<div>
|
||||
<p>{sextas[index]}</p>
|
||||
<div>
|
||||
{(dias.sexta || []).slice(0, 3).map((consulta, idx) => (
|
||||
<CardConsulta
|
||||
key={idx}
|
||||
DadosConsulta={consulta}
|
||||
className={`usuario-${consulta.cor || "default"}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{(dias.sexta || []).length > 3 ?
|
||||
<div><p className='cards-que-faltam'>+ {(dias.sexta || []).length - 3}</p></div>
|
||||
: null}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
)})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -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 (
|
||||
<div>
|
||||
{/* Container de Navegação */}
|
||||
<div id='tabela-seletor-container'>
|
||||
|
||||
<button
|
||||
onClick={voltarSemana}
|
||||
disabled={Indice === 0} // Desabilita se for a primeira semana
|
||||
>
|
||||
<i className='bi bi-chevron-compact-left'></i>
|
||||
</button>
|
||||
<p>{tituloSemana}</p>
|
||||
<button
|
||||
onClick={avancarSemana}
|
||||
disabled={Indice === totalSemanas - 1 || totalSemanas === 0} // Desabilita se for a última semana ou se não houver semanas
|
||||
|
||||
>
|
||||
<i className='bi bi-chevron-compact-right'></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Tabela de Agendamentos */}
|
||||
<table className='tabelasemanal'>
|
||||
<thead>
|
||||
<tr>
|
||||
@ -38,28 +157,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 DadosConsulta={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>
|
||||
|
||||
@ -114,4 +114,9 @@ html[data-bs-theme="dark"] .mostrar-horario th {
|
||||
border: 1px solid #333;
|
||||
color: #e0e0e0;
|
||||
background-color: #232323;
|
||||
}
|
||||
}
|
||||
/*
|
||||
.container-botons{
|
||||
margin-left: 10rem;
|
||||
background-color: pink;
|
||||
}*/
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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}
|
||||
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}
|
||||
@ -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)
|
||||
|
||||
@ -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 = () => {
|
||||
</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} setShowDeleteModal={setShowDeleteModal} />}
|
||||
{tabela === 'semanal' && <TabelaAgendamentoSemana agendamentos={DictAgendamentosOrganizados} ListarDiasdoMes={ListarDiasdoMes}/>}
|
||||
{tabela === 'mensal' && <TabelaAgendamentoMes ListarDiasdoMes={ListarDiasdoMes} aplicarCores={true} agendamentos={DictAgendamentosOrganizados} />}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@ -216,8 +271,65 @@ const Agendamento = () => {
|
||||
</section>
|
||||
</div>
|
||||
) : (
|
||||
<FormNovaConsulta onCancel={handleClickCancel} />
|
||||
<AgendamentoCadastroManager />
|
||||
)}
|
||||
|
||||
{showDeleteModal && (
|
||||
<div
|
||||
className="modal fade show"
|
||||
style={{
|
||||
display: "block",
|
||||
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
||||
}}
|
||||
tabIndex="-1"
|
||||
onClick={(e) =>
|
||||
e.target.classList.contains("modal") && setShowDeleteModal(false)
|
||||
}
|
||||
>
|
||||
<div className="modal-dialog modal-dialog-centered">
|
||||
<div className="modal-content">
|
||||
|
||||
<div className="modal-header bg-danger bg-opacity-25">
|
||||
<h5 className="modal-title text-danger">
|
||||
Confirmação de Exclusão
|
||||
</h5>
|
||||
<button
|
||||
type="button"
|
||||
className="btn-close"
|
||||
onClick={() => setShowDeleteModal(false)}
|
||||
></button>
|
||||
</div>
|
||||
|
||||
<div className="modal-body">
|
||||
<p className="mb-0 fs-5">
|
||||
Tem certeza que deseja excluir este paciente?
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="modal-footer">
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-primary"
|
||||
onClick={() => setShowDeleteModal(false)}
|
||||
>
|
||||
Cancelar
|
||||
</button>
|
||||
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-danger"
|
||||
//onClick={() => deletePatient(selectedPatientId)}
|
||||
>
|
||||
<i className="bi bi-trash me-1"></i> Excluir
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>)}
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
58
src/pages/AgendamentoCadastroManager.jsx
Normal file
58
src/pages/AgendamentoCadastroManager.jsx
Normal file
@ -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 (
|
||||
<div>
|
||||
|
||||
<FormNovaConsulta onSave={handleSave} agendamento={agendamento} setAgendamento={setAgendamento}/>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AgendamentoCadastroManager
|
||||
70
src/pages/AgendamentoEditPage.jsx
Normal file
70
src/pages/AgendamentoEditPage.jsx
Normal file
@ -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 (
|
||||
<div>
|
||||
<FormNovaConsulta onSave={handleSave} agendamento={PatientToPatch} setAgendamento={setPatientToPatch}/>
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AgendamentoEditPage
|
||||
@ -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));
|
||||
}, []);
|
||||
|
||||
|
||||
@ -171,7 +171,6 @@ function PatientCadastroManager( {setCurrentPage} ) {
|
||||
});
|
||||
setShowModal(true);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
setShowModal(false);
|
||||
navigate('/secretaria/pacientes');
|
||||
|
||||
@ -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]);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -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 }) {
|
||||
<Route path="medicos/:id" element={<DoctorDetails />} />
|
||||
<Route path="medicos/:id/edit" element={<DoctorEditPage />} />
|
||||
<Route path="agendamento" element={<Agendamento />} />
|
||||
<Route path="laudo" element={<LaudoManager />} />
|
||||
<Route path="agendamento/:id/edit" element={<AgendamentoEditPage/>} />
|
||||
<Route path="laudo" element={<LaudoManager />} />
|
||||
<Route path="*" element={<h2>Página não encontrada</h2>} />
|
||||
</Routes>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user