Merge branch 'AgendamentoConsultas'

This commit is contained in:
jp-lima 2025-10-15 20:14:06 -03:00
commit bba034c518
17 changed files with 887 additions and 334 deletions

View File

@ -1,24 +1,87 @@
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()
const ids = useMemo(() => {
return {
doctor_id: DadosConsulta?.doctor_id,
patient_id: DadosConsulta?.patient_id,
status: DadosConsulta?.status
};
}, [DadosConsulta]);
// Status (agendado, confirmado, realizado, cancelado) 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 ( return (
<div className={`container-cardconsulta-${TabelaAgendamento}`}> <div className={`container-cardconsulta-${TabelaAgendamento}`}>
{DadosConsulta.status !== 'vazio'? {DadosConsulta.id?
<div className='cardconsulta' id={`status-card-consulta-${DadosConsulta.status}`}> <div className='cardconsulta' id={`status-card-consulta-${DadosConsulta.status}`}>
<div>
<section className='cardconsulta-infosecundaria'> <section className='cardconsulta-infosecundaria'>
<p>{DadosConsulta.horario}|GEAP| {DadosConsulta.medico}</p> <p>{DadosConsulta.horario} {Medico?.full_name}</p>
</section> </section>
<section className='cardconsulta-infoprimaria'> <section className='cardconsulta-infoprimaria'>
<p>{DadosConsulta.paciente} - {DadosConsulta.motivo} - 23 anos</p> <p>{Paciente?.full_name} - {DadosConsulta.exam}</p>
</section> </section>
</div> </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 null

View File

@ -1,57 +1,21 @@
import InputMask from "react-input-mask"; import InputMask from "react-input-mask";
import "./style/formagendamentos.css"; import "./style/formagendamentos.css";
import { useState, useEffect } from "react"; 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 FormNovaConsulta = ({ onCancel, patientID }) => { const {getAuthorizationHeader} = useAuth()
const [selectedFile, setSelectedFile] = useState(null); const [selectedFile, setSelectedFile] = useState(null);
const [anexos, setAnexos] = useState([]); const [anexos, setAnexos] = useState([]);
const [loadingAnexos, setLoadingAnexos] = useState(false); const [loadingAnexos, setLoadingAnexos] = useState(false);
const [paciente, setPaciente] = useState({})
const [acessibilidade, setAcessibilidade] = useState({cadeirante:false,idoso:false,gravida:false,bebe:false, autista:false }) const [acessibilidade, setAcessibilidade] = useState({cadeirante:false,idoso:false,gravida:false,bebe:false, autista:false })
useEffect(() => { let authHeader = getAuthorizationHeader()
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);
}
};
const handleclickAcessibilidade = (id) => { const handleclickAcessibilidade = (id) => {
@ -65,11 +29,7 @@ const FormNovaConsulta = ({ onCancel, patientID }) => {
const FormatCPF = (valor) => { const FormatCPF = (valor) => {
console.log(valor)
const digits = String(valor).replace(/\D/g, '').slice(0, 11); const digits = String(valor).replace(/\D/g, '').slice(0, 11);
BuscarPacienteExistentePeloCPF(valor)
return digits return digits
.replace(/(\d{3})(\d)/, '$1.$2') .replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d)/, '$1.$2') .replace(/(\d{3})(\d)/, '$1.$2')
@ -77,97 +37,54 @@ const FormNovaConsulta = ({ onCancel, patientID }) => {
} }
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 handleChange = (e) => {
const {value, name} = e.target; const {value, name} = e.target;
console.log(value, name)
if(name === 'email'){ if(name === 'email'){
setPaciente({...paciente, contato:{ setAgendamento({...agendamento, contato:{
...paciente.contato, ...agendamento.contato,
email:value email:value
}}) }})
} else if(name === 'telefone'){ }else if(name === 'cpf'){
setPaciente({...paciente, contato:{
...paciente.contato, let cpfFormatted = FormatCPF(value)
telefone1:FormatTelefones(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{ else{
setPaciente({...paciente,[name]:value}) setAgendamento({...agendamento,[name]:value})
} }
} }
const handleSubmit = (e) => { const handleSubmit = (e) => {
e.preventDefault(); e.preventDefault();
alert("Agendamento salvo!"); alert("Agendamento salvo!");
onSave(agendamento)
}; };
return ( return (
@ -180,57 +97,33 @@ const FormNovaConsulta = ({ onCancel, patientID }) => {
<div className="campos-informacoes-paciente" id="informacoes-paciente-linha-um"> <div className="campos-informacoes-paciente" id="informacoes-paciente-linha-um">
<div className="campo-de-input"> <div className="campo-de-input">
<label>Nome *</label> <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>
<div className="campo-de-input"> <div className="campo-de-input">
<label>CPF do paciente</label> <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>
<div className="campo-de-input">
<label>RG</label>
<input type="text" name="rg" placeholder="Insira o nº do RG" maxLength={9} />
</div>
</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="campos-informacoes-paciente" id="informacoes-paciente-linha-tres">
<div className="campo-de-input"> <div className="campo-de-input">
<label>Convênio</label> <label>Convênio</label>
<select name="convenio"> <select name="convenio" onChange={handleChange}>
<option value="particular">Particular</option>
<option value="publico">Público</option> <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> </select>
</div> </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> </div>
<h3 className="section-subtitle">Informações adicionais</h3> <h3 className="section-subtitle">Informações adicionais</h3>
@ -243,7 +136,7 @@ const FormNovaConsulta = ({ onCancel, patientID }) => {
onChange={(e) => setSelectedFile(e.target.files[0])} onChange={(e) => setSelectedFile(e.target.files[0])}
/> />
{selectedFile && ( {selectedFile && (
<button type="button" className="btn btn-primary ms-2" onClick={handleUpload}> <button type="button" className="btn btn-primary ms-2" >
Enviar Enviar
</button> </button>
)} )}
@ -291,7 +184,7 @@ const FormNovaConsulta = ({ onCancel, patientID }) => {
<div className="campo-de-input"> <div className="campo-de-input">
<label>Nome do profissional *</label> <label>Nome do profissional *</label>
<input type="text" name="profissional" required /> <input type="text" name="profissional" onChange={handleChange} value={agendamento.nome_medico}required />
</div> </div>

View File

@ -1,14 +1,34 @@
import React from 'react'; import React, { useState, useEffect } from 'react';
import CardConsulta from './CardConsulta'; import CardConsulta from './CardConsulta';
import "./style/styleTabelas/tabeladia.css"; import "./style/styleTabelas/tabeladia.css";
const TabelaAgendamentoDia = ({ handleClickAgendamento, agendamentos, setShowDeleteModal }) => {
const TabelaAgendamentoDia = ({ handleClickAgendamento, agendamentos }) => { const [indiceAcesso, setIndiceAcesso] = useState(0)
const [Dia, setDia] = useState()
const agendamentosDoDia = agendamentos?.semana1?.segunda || []; const agendamentosDoDia = agendamentos?.semana1?.segunda || [];
const nomeMedico = agendamentosDoDia.find(item => item.medico)?.medico || 'Profissional'; const nomeMedico = agendamentosDoDia.find(item => item.medico)?.medico || 'Profissional';
let ListaDiasComAgendamentos = Object.keys(agendamentos)
console.log(Dia, "hshdhshhsdhs")
useEffect(() => {
setDia(ListaDiasComAgendamentos[indiceAcesso])
}, [indiceAcesso])
return ( return (
<div> <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'> <table className='tabeladiaria'>
<thead> <thead>
<tr> <tr>
@ -18,12 +38,12 @@ const TabelaAgendamentoDia = ({ handleClickAgendamento, agendamentos }) => {
</thead> </thead>
<tbody> <tbody>
{agendamentosDoDia.map((agendamento, index) => ( {agendamentos[Dia]?.map((agendamento, index) => (
<tr key={index}> <tr key={index}>
<td><p>{agendamento.horario}</p></td> <td><p>{agendamento.horario}</p></td>
<td className='mostrar-horario'> <td className='mostrar-horario'>
<div onClick={() => handleClickAgendamento(agendamento)}> <div onClick={() => handleClickAgendamento(agendamento)}>
<CardConsulta DadosConsulta={agendamento} TabelaAgendamento={'dia'} /> <CardConsulta DadosConsulta={agendamento} TabelaAgendamento={'dia'} setShowDeleteModal={setShowDeleteModal} />
</div> </div>
</td> </td>
</tr> </tr>

View File

@ -3,7 +3,8 @@ import React from 'react';
import dayjs from "dayjs"; import dayjs from "dayjs";
import CardConsulta from './CardConsulta'; import CardConsulta from './CardConsulta';
import "./style/styleTabelas/tabelames.css"; import "./style/styleTabelas/tabelames.css";
import { useEffect, useState } from 'react';
import { useMemo } from 'react';
const TabelaAgendamentoMes = ({ ListarDiasdoMes, agendamentos }) => { const TabelaAgendamentoMes = ({ ListarDiasdoMes, agendamentos }) => {
@ -12,19 +13,179 @@ const TabelaAgendamentoMes = ({ ListarDiasdoMes, agendamentos }) => {
const mes = dataHoje.month() + 1; const mes = dataHoje.month() + 1;
let ListaDiasDatas = ListarDiasdoMes(AnoAtual, mes); let ListaDiasDatas = ListarDiasdoMes(AnoAtual, mes);
const [AgendamentosSemanaisOrganizados, setAgendamentosSemanaisOrganizados] = useState({})
const [indice, setIndice] = useState("10")
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)
}
}
let segundas = ListaDiasDatas[0];
let tercas = ListaDiasDatas[1];
let quartas = ListaDiasDatas[2];
let quintas = ListaDiasDatas[3];
let sextas = ListaDiasDatas[4];
return ( return (
<div> <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'> <table className='tabelamensal'>
<thead> <thead>
<tr> <tr>
<th>Seg</th> <td className='cabecalho-tabela'>Seg</td>
<th>Ter</th> <th>Ter</th>
<th>Qua</th> <th>Qua</th>
<th>Qui</th> <th>Qui</th>
@ -32,104 +193,32 @@ const TabelaAgendamentoMes = ({ ListarDiasdoMes, agendamentos }) => {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{agendamentos && Object.entries(agendamentos).map(([semana, dias], index) => ( {Object.keys(AgendamentosMensaisOrganizados[indice]).map((semanaKey) => {
<tr key={index}> const semana = AgendamentosMensaisOrganizados[indice][semanaKey]
{/* Coluna de Segunda-feira */} console.log(AgendamentosMensaisOrganizados[indice][semanaKey], 'ajdsahchbaohdfoduh')
<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>
{/* 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 */} return(
<td> <tr key={semanaKey}>
<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>
{/* Coluna de Quinta-feira */} {
<td> 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> <div>
<p>{quintas[index]}</p> <p>{` +${semana[dia].length - 2}`}</p>
<div>
{(dias.quinta || []).slice(0, 3).map((consulta, idx) => (
<CardConsulta
key={idx}
DadosConsulta={consulta}
className={`usuario-${consulta.cor || "default"}`}
/>
))}
</div> </div>
{(dias.quinta || []).length > 3 ?
<div><p className='cards-que-faltam'>+ {(dias.quinta || []).length - 3}</p></div>
: null}
</div>
</td>
{/* Coluna de Sexta-feira */} ): null }
<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> </td>
))
}
</tr> </tr>
))}
)})}
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@ -1,31 +1,150 @@
import React from 'react'; import React from 'react';
import CardConsulta from './CardConsulta'; import CardConsulta from './CardConsulta';
import "./style/styleTabelas/tabelasemana.css"; 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 }) => {
// 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 TabelaAgendamentoSemana = ({ agendamentos }) => { // --- PREPARAÇÃO DOS DADOS PARA RENDERIZAÇÃO ---
// Pega a chave da semana que deve ser exibida (usa o estado Indice)
const chaveDaSemanaAtual = chavesDasSemanas[Indice];
const agendamentoSemana = agendamentos?.semana1 || {}; // Extrai os agendamentos da semana atual (ou um objeto vazio se não existir)
const semanaParaRenderizar = semanasOrganizadas[chaveDaSemanaAtual] || {
segunda: [], terça: [], quarta: [], quinta: [], sexta: []
const agendamentosDeSegunda = agendamentoSemana.segunda || []; };
const agendamentosDeTerca = agendamentoSemana.terca || [];
const agendamentosDeQuarta = agendamentoSemana.quarta || [];
const agendamentosDeQuinta = agendamentoSemana.quinta || [];
const agendamentosDeSexta = agendamentoSemana.sexta || [];
// Determina o número máximo de linhas/consultas
const numLinhas = Math.max( const numLinhas = Math.max(
agendamentosDeSegunda.length, semanaParaRenderizar.segunda.length,
agendamentosDeTerca.length, semanaParaRenderizar.terça.length,
agendamentosDeQuarta.length, semanaParaRenderizar.quarta.length,
agendamentosDeQuinta.length, semanaParaRenderizar.quinta.length,
agendamentosDeSexta.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 ( return (
<div> <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'> <table className='tabelasemanal'>
<thead> <thead>
<tr> <tr>
@ -38,28 +157,44 @@ const TabelaAgendamentoSemana = ({ agendamentos }) => {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{Array.from({ length: numLinhas }).map((_, index) => { {indicesDeLinha.map((indiceLinha) => (
<tr key={indiceLinha}>
{/* Célula para Horário (Pode ser ajustado para mostrar o horário real) */}
<td></td>
const consultaSeg = agendamentosDeSegunda[index]; {/* Mapeamento de COLUNAS (dias) */}
const consultaTer = agendamentosDeTerca[index]; <td>
const consultaQua = agendamentosDeQuarta[index]; {semanaParaRenderizar.segunda[indiceLinha]
const consultaQui = agendamentosDeQuinta[index]; ? <CardConsulta DadosConsulta={semanaParaRenderizar.segunda[indiceLinha]} />
const consultaSex = agendamentosDeSexta[index]; : null
}
</td>
const horarioDaLinha = consultaSeg?.horario || consultaTer?.horario || consultaQua?.horario || consultaQui?.horario || consultaSex?.horario; <td>
{semanaParaRenderizar.terça[indiceLinha]
return ( ? <CardConsulta DadosConsulta={semanaParaRenderizar.terça[indiceLinha]} />
<tr key={index}> : null
<td>{horarioDaLinha}</td> }
<td>{consultaSeg && <CardConsulta DadosConsulta={consultaSeg} />}</td> </td>
<td>{consultaTer && <CardConsulta DadosConsulta={consultaTer} />}</td> <td>
<td>{consultaQua && <CardConsulta DadosConsulta={consultaQua} />}</td> {semanaParaRenderizar.quarta[indiceLinha]
<td>{consultaQui && <CardConsulta DadosConsulta={consultaQui} />}</td> ? <CardConsulta DadosConsulta={semanaParaRenderizar.quarta[indiceLinha]} />
<td>{consultaSex && <CardConsulta DadosConsulta={consultaSex} />}</td> : 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> </tr>
); ))}
})}
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@ -115,3 +115,8 @@ html[data-bs-theme="dark"] .mostrar-horario th {
color: #e0e0e0; color: #e0e0e0;
background-color: #232323; background-color: #232323;
} }
/*
.container-botons{
margin-left: 10rem;
background-color: pink;
}*/

View File

@ -220,3 +220,13 @@ html[data-bs-theme="dark"] .usuario-default {
html[data-bs-theme="dark"] .cards-que-faltam { html[data-bs-theme="dark"] .cards-que-faltam {
color: #90caf9; color: #90caf9;
} }
.cabecalho-tabela{
color: white;
background-color: #005a9e;
}
.container-botons{
margin-left: 5rem;
}

View File

@ -4,8 +4,6 @@ import API_KEY from "../apiKeys";
const GetDoctorByID = async (ID,authHeader) => { const GetDoctorByID = async (ID,authHeader) => {
console.log(authHeader, 'mostrando autorização dentro da função')
var myHeaders = new Headers(); var myHeaders = new Headers();
myHeaders.append('apikey', API_KEY) myHeaders.append('apikey', API_KEY)
myHeaders.append('Authorization', authHeader) 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}

View File

@ -4,8 +4,6 @@ import API_KEY from "../apiKeys";
const GetPatientByID = async (ID,authHeader) => { const GetPatientByID = async (ID,authHeader) => {
console.log(authHeader, 'mostrando autorização dentro da função')
var myHeaders = new Headers(); var myHeaders = new Headers();
myHeaders.append('apikey', API_KEY) myHeaders.append('apikey', API_KEY)
myHeaders.append('Authorization', authHeader) myHeaders.append('Authorization', authHeader)

View File

@ -1,13 +1,15 @@
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 TabelaAgendamentoDia from '../components/AgendarConsulta/TabelaAgendamentoDia';
import TabelaAgendamentoSemana from '../components/AgendarConsulta/TabelaAgendamentoSemana'; import TabelaAgendamentoSemana from '../components/AgendarConsulta/TabelaAgendamentoSemana';
import TabelaAgendamentoMes from '../components/AgendarConsulta/TabelaAgendamentoMes'; import TabelaAgendamentoMes from '../components/AgendarConsulta/TabelaAgendamentoMes';
import FormNovaConsulta from '../components/AgendarConsulta/FormNovaConsulta'; 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 // NOVO: Caminho de importação corrigido com base na sua estrutura de pastas
import AgendamentosMes from '../components/AgendarConsulta/DadosConsultasMock.js'; import AgendamentosMes from '../components/AgendarConsulta/DadosConsultasMock.js';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import "./style/Agendamento.css"; import "./style/Agendamento.css";
import './style/FilaEspera.css'; import './style/FilaEspera.css';
@ -18,6 +20,59 @@ const Agendamento = () => {
const [tabela, setTabela] = useState('diario'); const [tabela, setTabela] = useState('diario');
const [PageNovaConsulta, setPageConsulta] = useState(false); const [PageNovaConsulta, setPageConsulta] = useState(false);
const [searchTerm, setSearchTerm] = useState(''); 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) // Dados da fila de espera (sem alteração)
const filaEsperaData = [ const filaEsperaData = [
@ -76,7 +131,7 @@ const Agendamento = () => {
default: break default: break
} }
} }
let ListaDiasDatas = [segundas, tercas, quartas, quintas, sextas] let ListaDiasDatas = {segundas:segundas,tercas:tercas,quartas: quartas,quintas: quintas,sextas: sextas}
return ListaDiasDatas return ListaDiasDatas
} }
@ -169,9 +224,9 @@ const Agendamento = () => {
</div> </div>
</section> </section>
{tabela === "diario" && <TabelaAgendamentoDia handleClickAgendamento={handleClickAgendamento} agendamentos={filteredAgendamentos} />} {tabela === "diario" && <TabelaAgendamentoDia handleClickAgendamento={handleClickAgendamento} agendamentos={DictAgendamentosOrganizados} setShowDeleteModal={setShowDeleteModal} />}
{tabela === 'semanal' && <TabelaAgendamentoSemana agendamentos={filteredAgendamentos} />} {tabela === 'semanal' && <TabelaAgendamentoSemana agendamentos={DictAgendamentosOrganizados} ListarDiasdoMes={ListarDiasdoMes}/>}
{tabela === 'mensal' && <TabelaAgendamentoMes ListarDiasdoMes={ListarDiasdoMes} aplicarCores={true} agendamentos={filteredAgendamentos} />} {tabela === 'mensal' && <TabelaAgendamentoMes ListarDiasdoMes={ListarDiasdoMes} aplicarCores={true} agendamentos={DictAgendamentosOrganizados} />}
</div> </div>
</div> </div>
) )
@ -216,8 +271,65 @@ const Agendamento = () => {
</section> </section>
</div> </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> </div>
) )
} }

View 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

View 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

View File

@ -71,7 +71,7 @@ function TableDoctor() {
fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors", requestOptions) fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors", requestOptions)
.then(response => response.json()) .then(response => response.json())
.then(result => setMedicos(result)) .then(result => {setMedicos(result); console.log(result)})
.catch(error => console.log('error', error)); .catch(error => console.log('error', error));
}, []); }, []);

View File

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

View File

@ -102,7 +102,7 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
const authHeader = getAuthorizationHeader() const authHeader = getAuthorizationHeader()
console.log(authHeader, 'aqui autorização') console.log(authHeader)
var myHeaders = new Headers(); var myHeaders = new Headers();
myHeaders.append("apikey", API_KEY); myHeaders.append("apikey", API_KEY);
@ -115,7 +115,7 @@ function TablePaciente({ setCurrentPage, setPatientID }) {
fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients", requestOptions) fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients", requestOptions)
.then(response => response.json()) .then(response => response.json())
.then(result => setPacientes(result)) .then(result => {setPacientes(result); console.log(result)})
.catch(error => console.log('error', error)); .catch(error => console.log('error', error));
}, [isAuthenticated, getAuthorizationHeader]); }, [isAuthenticated, getAuthorizationHeader]);

View File

@ -118,7 +118,7 @@
border-radius: 10px; border-radius: 10px;
} }
#status-card-consulta-confirmado, .legenda-item-confirmado { #status-card-consulta-confirmado, .legenda-item-confirmed {
background-color: #eef8fb; background-color: #eef8fb;
border:3px solid #d8dfe7; border:3px solid #d8dfe7;
padding: 5px; padding: 5px;
@ -289,3 +289,72 @@ html[data-bs-theme="dark"] {
background-color: #005a9e; 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;
}

View File

@ -15,6 +15,7 @@ import Details from "../../pages/Details";
import EditPage from "../../pages/EditPage"; import EditPage from "../../pages/EditPage";
import DoctorDetails from "../../pages/DoctorDetails"; import DoctorDetails from "../../pages/DoctorDetails";
import DoctorEditPage from "../../pages/DoctorEditPage"; import DoctorEditPage from "../../pages/DoctorEditPage";
import AgendamentoEditPage from "../../pages/AgendamentoEditPage";
function PerfilSecretaria({ onLogout }) { function PerfilSecretaria({ onLogout }) {
return ( return (
@ -33,6 +34,7 @@ function PerfilSecretaria({ onLogout }) {
<Route path="medicos/:id" element={<DoctorDetails />} /> <Route path="medicos/:id" element={<DoctorDetails />} />
<Route path="medicos/:id/edit" element={<DoctorEditPage />} /> <Route path="medicos/:id/edit" element={<DoctorEditPage />} />
<Route path="agendamento" element={<Agendamento />} /> <Route path="agendamento" element={<Agendamento />} />
<Route path="agendamento/:id/edit" element={<AgendamentoEditPage/>} />
<Route path="laudo" element={<LaudoManager />} /> <Route path="laudo" element={<LaudoManager />} />
<Route path="*" element={<h2>Página não encontrada</h2>} /> <Route path="*" element={<h2>Página não encontrada</h2>} />
</Routes> </Routes>