Adições finais
This commit is contained in:
parent
0b47a96589
commit
45ac442e4f
@ -12,7 +12,7 @@ import PerfilSecretaria from "./perfis/perfil_secretaria/PerfilSecretaria.jsx"
|
|||||||
import PerfilFinanceiro from "./perfis/perfil_financeiro/PerfilFinanceiro.jsx";
|
import PerfilFinanceiro from "./perfis/perfil_financeiro/PerfilFinanceiro.jsx";
|
||||||
import Perfiladm from "./perfis/Perfil_adm/PerfilAdmin.jsx";
|
import Perfiladm from "./perfis/Perfil_adm/PerfilAdmin.jsx";
|
||||||
import PerfilMedico from "./perfis/Perfil_medico/PerfilMedico.jsx";
|
import PerfilMedico from "./perfis/Perfil_medico/PerfilMedico.jsx";
|
||||||
import PerfilPaciente from "./perfis/Perfil_paciente/PerfilPaciente.jsx"
|
import PerfilPaciente from "./perfis/Perfil_paciente/Perfilpaciente.jsx"
|
||||||
|
|
||||||
// COMBINADO: Importações de ambas as versões
|
// COMBINADO: Importações de ambas as versões
|
||||||
import ProfilePage from "./pages/geral/PerfilUsuario.jsx";
|
import ProfilePage from "./pages/geral/PerfilUsuario.jsx";
|
||||||
|
|||||||
@ -335,7 +335,7 @@ const FormCriarExcecao = ({ onCancel, doctorID }) => {
|
|||||||
<label>Tipo de exceção *</label>
|
<label>Tipo de exceção *</label>
|
||||||
<select name="tipoAtendimento" onChange={handleAtendimentoChange} value={dadosAtendimento.tipoAtendimento} required>
|
<select name="tipoAtendimento" onChange={handleAtendimentoChange} value={dadosAtendimento.tipoAtendimento} required>
|
||||||
<option value="" disabled>Selecione o tipo de exceção</option>
|
<option value="" disabled>Selecione o tipo de exceção</option>
|
||||||
<option value="disponibilidade_extra" >Liberação</option>
|
<option value="disponibilidade_extra" >Disponibilidade Extra</option>
|
||||||
<option value="bloqueio" >Bloqueio</option>
|
<option value="bloqueio" >Bloqueio</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
335
src/components/medico/FormExcecaoMedico.jsx
Normal file
335
src/components/medico/FormExcecaoMedico.jsx
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { useAuth } from "../../_assets/utils/AuthProvider";
|
||||||
|
import API_KEY from "../../_assets/utils/apiKeys";
|
||||||
|
import { GetDoctorByName } from '../../_assets/utils/Functions-Endpoints/Doctor';
|
||||||
|
|
||||||
|
import "../../_assets/css/components/agendamento/FormAgendamento.css";
|
||||||
|
|
||||||
|
const ENDPOINT_CRIAR_EXCECAO = "https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctor_exceptions";
|
||||||
|
|
||||||
|
const FormCriarExcecao = ({ onCancel, doctorID }) => {
|
||||||
|
const { getAuthorizationHeader, user, getUserInfo } = useAuth();
|
||||||
|
|
||||||
|
// mantemos apenas os campos realmente necessários no formulário;
|
||||||
|
// profissional (id) e created_by serão preenchidos automaticamente a partir do usuário logado
|
||||||
|
const [dadosAtendimento, setDadosAtendimento] = useState({
|
||||||
|
profissional: doctorID || '',
|
||||||
|
tipoAtendimento: '',
|
||||||
|
dataAtendimento: '',
|
||||||
|
inicio: '',
|
||||||
|
termino: '',
|
||||||
|
motivo: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleAtendimentoChange = (e) => {
|
||||||
|
const { value, name } = e.target;
|
||||||
|
setDadosAtendimento(prev => ({
|
||||||
|
...prev,
|
||||||
|
[name]: value
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
// preencher automaticamente o id do profissional (doctor_id) vindo do user/prop
|
||||||
|
useEffect(() => {
|
||||||
|
const resolvedDoctorId = doctorID || user?.doctor_id || user?.id || '';
|
||||||
|
setDadosAtendimento(prev => ({
|
||||||
|
...prev,
|
||||||
|
profissional: prev.profissional || resolvedDoctorId
|
||||||
|
}));
|
||||||
|
}, [doctorID, user]);
|
||||||
|
|
||||||
|
const ALLOWED_KINDS = ['disponibilidade_extra', 'bloqueio'];
|
||||||
|
|
||||||
|
// helper: normalize and validate Authorization header -> "Bearer <jwt>"
|
||||||
|
const resolveAuthHeader = () => {
|
||||||
|
try {
|
||||||
|
const maybe = getAuthorizationHeader ? getAuthorizationHeader() : null;
|
||||||
|
console.log('[DEBUG] getAuthorizationHeader() ->', maybe);
|
||||||
|
let raw = null;
|
||||||
|
|
||||||
|
if (!maybe) {
|
||||||
|
// fallback localStorage
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem('user') || localStorage.getItem('auth') || null;
|
||||||
|
if (stored) {
|
||||||
|
const parsed = JSON.parse(stored);
|
||||||
|
raw = parsed?.access_token || parsed?.token || parsed?.auth?.access_token || null;
|
||||||
|
}
|
||||||
|
} catch (e) { console.warn('[DEBUG] parse localStorage failed', e); }
|
||||||
|
} else if (typeof maybe === 'string') {
|
||||||
|
raw = maybe;
|
||||||
|
} else if (typeof maybe === 'object') {
|
||||||
|
raw = maybe.Authorization || maybe.authorization || maybe.access_token || maybe.token || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!raw) return null;
|
||||||
|
|
||||||
|
// remove any leading "bearer " (case-insensitive) and possible duplicated prefixes
|
||||||
|
raw = String(raw).trim().replace(/^(?:bearer\s*)+/i, '');
|
||||||
|
|
||||||
|
console.log('[DEBUG] resolved raw token ->', raw);
|
||||||
|
|
||||||
|
// basic JWT structure check
|
||||||
|
if (typeof raw !== 'string' || raw.split('.').length !== 3) {
|
||||||
|
console.error('[DEBUG] token not a JWT:', raw);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `Bearer ${raw}`;
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('resolveAuthHeader error', err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUidFromAuthHeader = (authHeader) => {
|
||||||
|
try {
|
||||||
|
if (!authHeader) return null;
|
||||||
|
const token = String(authHeader).replace(/Bearer\s+/i, '').trim();
|
||||||
|
if (!token || token.split('.').length !== 3) return null;
|
||||||
|
|
||||||
|
// decode base64url payload
|
||||||
|
const payloadBase64 = token.split('.')[1].replace(/-/g, '+').replace(/_/g, '/');
|
||||||
|
const padded = payloadBase64 + '='.repeat((4 - (payloadBase64.length % 4)) % 4);
|
||||||
|
const json = atob(padded);
|
||||||
|
const payload = JSON.parse(json);
|
||||||
|
return payload.sub || payload.user_id || payload.uid || payload.id || null;
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Não foi possível decodificar JWT para obter uid:', err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmitExcecao = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log('[DEBUG] submit dadosAtendimento ->', dadosAtendimento);
|
||||||
|
|
||||||
|
const authHeader = resolveAuthHeader();
|
||||||
|
console.log('[DEBUG] authHeader to send ->', authHeader);
|
||||||
|
if (!authHeader) {
|
||||||
|
alert('Sessão inválida ou token ausente / inválido. Faça logout e login novamente.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let { profissional, dataAtendimento, tipoAtendimento, inicio, termino, motivo } = dadosAtendimento;
|
||||||
|
|
||||||
|
// tenta resolver profissional automaticamente se ainda não definido
|
||||||
|
profissional = profissional || doctorID || user?.doctor_id || user?.id || null;
|
||||||
|
|
||||||
|
// extrai uid do token (se policy do Supabase exigir auth.uid())
|
||||||
|
const authUid = getUidFromAuthHeader(authHeader) || user?.id || null;
|
||||||
|
|
||||||
|
// se a policy exige que doctor_id seja igual ao auth.uid(), force o valor aqui
|
||||||
|
if (authUid && !profissional) {
|
||||||
|
profissional = authUid;
|
||||||
|
setDadosAtendimento(prev => ({ ...prev, profissional }));
|
||||||
|
}
|
||||||
|
|
||||||
|
// created_by também deve refletir o uid do usuário autenticado (se policy exigir)
|
||||||
|
let createdBy = authUid || user?.id || null;
|
||||||
|
|
||||||
|
if (!profissional || !dataAtendimento || !tipoAtendimento || !motivo) {
|
||||||
|
alert("Por favor, verifique: médico, data, tipo e motivo são obrigatórios.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mappedKind = tipoAtendimento;
|
||||||
|
if (!ALLOWED_KINDS.includes(mappedKind)) {
|
||||||
|
alert(`Tipo inválido: "${tipoAtendimento}". Tipos aceitos: ${ALLOWED_KINDS.join(', ')}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startTime = inicio ? inicio + ":00" : null;
|
||||||
|
const endTime = termino ? termino + ":00" : null;
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
doctor_id: profissional,
|
||||||
|
date: dataAtendimento,
|
||||||
|
kind: mappedKind,
|
||||||
|
start_time: startTime,
|
||||||
|
end_time: endTime,
|
||||||
|
reason: motivo,
|
||||||
|
created_by: createdBy
|
||||||
|
};
|
||||||
|
|
||||||
|
// monta headers do POST usando authHeader já normalizado
|
||||||
|
const myHeaders = new Headers();
|
||||||
|
myHeaders.append('Content-Type', 'application/json');
|
||||||
|
myHeaders.append('Authorization', authHeader);
|
||||||
|
if (API_KEY) myHeaders.append('apikey', API_KEY);
|
||||||
|
|
||||||
|
// envia
|
||||||
|
try {
|
||||||
|
const response = await fetch(ENDPOINT_CRIAR_EXCECAO, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: myHeaders,
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
redirect: 'follow'
|
||||||
|
});
|
||||||
|
|
||||||
|
const text = await response.text();
|
||||||
|
let result;
|
||||||
|
try { result = JSON.parse(text); } catch { result = { message: text }; }
|
||||||
|
|
||||||
|
if (response.ok || response.status === 201) {
|
||||||
|
alert(`Exceção criada com sucesso.`);
|
||||||
|
onCancel(true);
|
||||||
|
} else {
|
||||||
|
console.error("Erro ao criar exceção:", result);
|
||||||
|
alert(`Erro ao criar exceção. Status: ${response.status}. ${result.message || ''}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro na requisição para criar exceção:", error);
|
||||||
|
alert("Erro de comunicação com o servidor.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// exibimos informações do médico logado de forma somente leitura (preenchidas automaticamente)
|
||||||
|
const [displayDoctorName, setDisplayDoctorName] = useState(user?.full_name || user?.name || '');
|
||||||
|
const displayDoctorId = doctorID || user?.doctor_id || user?.id || '';
|
||||||
|
|
||||||
|
// preenche dados do médico usando a função de informações do usuário (UserInfos / getUserInfo)
|
||||||
|
useEffect(() => {
|
||||||
|
let cancelled = false;
|
||||||
|
const resolvedDoctorId = doctorID || user?.doctor_id || user?.id || null;
|
||||||
|
const userName = user?.full_name || user?.name || user?.username || '';
|
||||||
|
|
||||||
|
const tryFillFromUserInfo = async () => {
|
||||||
|
try {
|
||||||
|
// primeiro, tenta usar getUserInfo() se disponível
|
||||||
|
let info = null;
|
||||||
|
if (typeof getUserInfo === 'function') {
|
||||||
|
try {
|
||||||
|
// se getUserInfo precisa de header, passe-o; caso contrário, a função interna deve usar auth
|
||||||
|
const authHeader = resolveAuthHeader();
|
||||||
|
// se getUserInfo aceita header, você pode adaptar; aqui tentamos chamar sem args
|
||||||
|
info = await getUserInfo();
|
||||||
|
} catch (e) {
|
||||||
|
// fallback: sem info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// se não veio info, use user
|
||||||
|
const profile = info || user || {};
|
||||||
|
|
||||||
|
const profileId = profile.doctor_id || profile.id || resolvedDoctorId;
|
||||||
|
const profileName = profile.full_name || profile.name || userName;
|
||||||
|
|
||||||
|
if (!cancelled && profileName) setDisplayDoctorName(profileName);
|
||||||
|
if (!cancelled && profileId) {
|
||||||
|
setDadosAtendimento(prev => ({ ...prev, profissional: prev.profissional || profileId }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback: tentar buscar por nome via endpoint de médicos (usa auth header normalizado)
|
||||||
|
if (userName) {
|
||||||
|
const authHeader = resolveAuthHeader();
|
||||||
|
if (!authHeader) {
|
||||||
|
console.warn('No auth header available for GetDoctorByName lookup');
|
||||||
|
} else {
|
||||||
|
const doctor = await GetDoctorByName(userName, authHeader);
|
||||||
|
if (!cancelled && doctor) {
|
||||||
|
setDisplayDoctorName(doctor.full_name || doctor.name || userName);
|
||||||
|
setDadosAtendimento(prev => ({ ...prev, profissional: doctor.id || doctor.doctor_id || prev.profissional }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// último fallback
|
||||||
|
if (!cancelled) {
|
||||||
|
setDisplayDoctorName(userName || '');
|
||||||
|
if (resolvedDoctorId) setDadosAtendimento(prev => ({ ...prev, profissional: prev.profissional || resolvedDoctorId }));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (cancelled) return;
|
||||||
|
console.warn('Erro ao preencher dados do médico via UserInfos/getUserInfo:', err);
|
||||||
|
setDisplayDoctorName(userName || '');
|
||||||
|
if (resolvedDoctorId) setDadosAtendimento(prev => ({ ...prev, profissional: prev.profissional || resolvedDoctorId }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
tryFillFromUserInfo();
|
||||||
|
return () => { cancelled = true; };
|
||||||
|
}, [doctorID, user, getUserInfo, getAuthorizationHeader]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="form-container">
|
||||||
|
<form className="form-agendamento" onSubmit={handleSubmitExcecao}>
|
||||||
|
<h2 className="section-title">Informações da Nova Exceção</h2>
|
||||||
|
|
||||||
|
{/* Médico agora não é editável/visível — dados preenchidos automaticamente */}
|
||||||
|
<div className="campo-informacoes-atendimento">
|
||||||
|
<div className="campo-de-input">
|
||||||
|
<label>Tipo de exceção *</label>
|
||||||
|
<select name="tipoAtendimento" onChange={handleAtendimentoChange} value={dadosAtendimento.tipoAtendimento} required>
|
||||||
|
<option value="" disabled>Selecione o tipo de exceção</option>
|
||||||
|
<option value="disponibilidade_extra">Disponibilidade Extra</option>
|
||||||
|
<option value="bloqueio">Bloqueio</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section id="informacoes-atendimento-segunda-linha">
|
||||||
|
<section id="informacoes-atendimento-segunda-linha-esquerda">
|
||||||
|
<div className="campo-informacoes-atendimento">
|
||||||
|
<div className="campo-de-input">
|
||||||
|
<label>Data *</label>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
name="dataAtendimento"
|
||||||
|
required
|
||||||
|
value={dadosAtendimento.dataAtendimento}
|
||||||
|
onChange={handleAtendimentoChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="campo-informacoes-atendimento">
|
||||||
|
<div className="campo-de-input">
|
||||||
|
<label>Início (Opcional)</label>
|
||||||
|
<input
|
||||||
|
type="time"
|
||||||
|
name="inicio"
|
||||||
|
value={dadosAtendimento.inicio}
|
||||||
|
onChange={handleAtendimentoChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="campo-de-input">
|
||||||
|
<label>Término (Opcional)</label>
|
||||||
|
<input
|
||||||
|
type="time"
|
||||||
|
name="termino"
|
||||||
|
value={dadosAtendimento.termino}
|
||||||
|
onChange={handleAtendimentoChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="informacoes-atendimento-segunda-linha-direita">
|
||||||
|
<div className="campo-de-input">
|
||||||
|
<label>Motivo da exceção *</label>
|
||||||
|
<textarea
|
||||||
|
name="motivo"
|
||||||
|
rows="4"
|
||||||
|
cols="1"
|
||||||
|
required
|
||||||
|
value={dadosAtendimento.motivo}
|
||||||
|
onChange={handleAtendimentoChange}
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div className="form-actions">
|
||||||
|
<button type="submit" className="btn-primary">Criar Exceção</button>
|
||||||
|
<button type="button" className="btn-cancel" onClick={() => onCancel(false)}>Cancelar</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormCriarExcecao;
|
||||||
@ -522,13 +522,13 @@ const filtrarPorPaciente = (appointments) => {
|
|||||||
<i className="bi bi-plus-circle"></i> Adicionar Consulta
|
<i className="bi bi-plus-circle"></i> Adicionar Consulta
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="manage-button btn"
|
className="btn btn-primary"
|
||||||
onClick={() => navigate("/secretaria/excecoes-disponibilidade")}
|
onClick={() => navigate("/medico/excecoes-disponibilidade")}
|
||||||
>
|
>
|
||||||
<i className="bi bi-gear-fill me-1"></i> Gerenciar Exceções
|
<i className="bi bi-gear-fill me-1"></i> Gerenciar Exceções
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="manage-button btn"
|
className="btn btn-primary"
|
||||||
onClick={() => navigate("/secretaria/disponibilidade")}
|
onClick={() => navigate("/secretaria/disponibilidade")}
|
||||||
>
|
>
|
||||||
<i className="bi bi-gear-fill me-1"></i> Mudar Disponibilidade
|
<i className="bi bi-gear-fill me-1"></i> Mudar Disponibilidade
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect, useMemo, useCallback } from 'react';
|
import { useState, useEffect, useMemo, useCallback } from 'react';
|
||||||
import { useAuth } from '../../_assets/utils/AuthProvider'
|
import { useAuth } from '../../_assets/utils/AuthProvider'
|
||||||
import FormExcecaoDisponibilidade from '../../components/medico/FormExcecaoDisponibilidade';
|
import FormExcecaoDisponibilidade from '../../components/medico/FormExcecaoMedico';
|
||||||
|
|
||||||
import '../../_assets/css/components/agendamento/FormAgendamento.css';
|
import '../../_assets/css/components/agendamento/FormAgendamento.css';
|
||||||
import '../../_assets/css/pages/agendamento/Agendamento.css';
|
import '../../_assets/css/pages/agendamento/Agendamento.css';
|
||||||
|
|||||||
@ -299,7 +299,6 @@ const DoctorRelatorioManager = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="page-heading"><h3>Lista de Relatórios</h3></div>
|
<div className="page-heading"><h3>Lista de Relatórios</h3></div>
|
||||||
<div className="page-content">
|
|
||||||
<section className="row">
|
<section className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="card">
|
<div className="card">
|
||||||
@ -449,7 +448,6 @@ const DoctorRelatorioManager = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import html2pdf from 'html2pdf.js';
|
import html2pdf from 'html2pdf.js';
|
||||||
import './styleMedico/NovoRelatorioAudio.css';
|
import '../../_assets/css/pages/medico/RelatorioAudio.css';
|
||||||
|
|
||||||
const NovoRelatorioAudio = () => {
|
const NovoRelatorioAudio = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|||||||
@ -469,7 +469,7 @@ const Agendamento = ({ setDictInfo }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="page-content table-paciente-container">
|
<div className="table-paciente-container">
|
||||||
<section className="row">
|
<section className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="card table-paciente-card">
|
<div className="card table-paciente-card">
|
||||||
|
|||||||
@ -466,13 +466,13 @@ const Agendamento = ({ setDictInfo }) => {
|
|||||||
<i className="bi bi-plus-circle"></i> Adicionar Consulta
|
<i className="bi bi-plus-circle"></i> Adicionar Consulta
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="manage-button btn"
|
className="btn btn-primary"
|
||||||
onClick={() => navigate("/secretaria/excecoes-disponibilidade")}
|
onClick={() => navigate("/secretaria/excecoes-disponibilidade")}
|
||||||
>
|
>
|
||||||
<i className="bi bi-gear-fill me-1"></i> Gerenciar Exceções
|
<i className="bi bi-gear-fill me-1"></i> Gerenciar Exceções
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className="manage-button btn"
|
className="btn btn-primary"
|
||||||
onClick={() => navigate("/secretaria/disponibilidade")}
|
onClick={() => navigate("/secretaria/disponibilidade")}
|
||||||
>
|
>
|
||||||
<i className="bi bi-gear-fill me-1"></i> Mudar Disponibilidade
|
<i className="bi bi-gear-fill me-1"></i> Mudar Disponibilidade
|
||||||
@ -792,7 +792,7 @@ const Agendamento = ({ setDictInfo }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="page-content table-paciente-container">
|
<div className="table-paciente-container">
|
||||||
<section className="row">
|
<section className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="card table-paciente-card">
|
<div className="card table-paciente-card">
|
||||||
|
|||||||
@ -239,7 +239,6 @@ const LaudoManager = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="page-heading"><h3>Lista de Relatórios</h3></div>
|
<div className="page-heading"><h3>Lista de Relatórios</h3></div>
|
||||||
<div className="page-content">
|
|
||||||
<section className="row">
|
<section className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="card">
|
<div className="card">
|
||||||
@ -404,7 +403,6 @@ const LaudoManager = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{showModal && relatorioModal && (
|
{showModal && relatorioModal && (
|
||||||
|
|||||||
@ -211,7 +211,7 @@ function TableDoctor({setDictInfo}) {
|
|||||||
<div className="page-heading">
|
<div className="page-heading">
|
||||||
<h3>Lista de Médicos</h3>
|
<h3>Lista de Médicos</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="page-content table-doctor-container">
|
<div className="table-doctor-container">
|
||||||
<section className="row">
|
<section className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="card table-doctor-card">
|
<div className="card table-doctor-card">
|
||||||
|
|||||||
@ -318,7 +318,7 @@ function TablePaciente({ setPatientID, setDictInfo }) {
|
|||||||
<div className="page-heading">
|
<div className="page-heading">
|
||||||
<h3>Lista de Pacientes</h3>
|
<h3>Lista de Pacientes</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="page-content table-paciente-container">
|
<div className="table-paciente-container">
|
||||||
<section className="row">
|
<section className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="card table-paciente-card">
|
<div className="card table-paciente-card">
|
||||||
|
|||||||
@ -42,6 +42,7 @@ function PerfilMedico() {
|
|||||||
<Route path="/relatorios" element={<DoctorRelatorioManager />} />
|
<Route path="/relatorios" element={<DoctorRelatorioManager />} />
|
||||||
<Route path="/agendamento" element={<DoctorAgendamentoManager setDictInfo={setDictInfo}/>} />
|
<Route path="/agendamento" element={<DoctorAgendamentoManager setDictInfo={setDictInfo}/>} />
|
||||||
<Route path="/agendamento/edit" element={<DoctorAgendamentoEditPage DictInfo={dictInfo} setDictInfo={setDictInfo}/>} />
|
<Route path="/agendamento/edit" element={<DoctorAgendamentoEditPage DictInfo={dictInfo} setDictInfo={setDictInfo}/>} />
|
||||||
|
<Route path="/excecoes-disponibilidade" element={<ExcecoesDisponibilidadeDoctor />} />
|
||||||
<Route path="/chat" element={<Chat />} />
|
<Route path="/chat" element={<Chat />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user