Ajuste das exceções
This commit is contained in:
parent
f7cb04a68f
commit
461bf3b413
@ -3,11 +3,6 @@
|
|||||||
"name": "Seus Agendamentos",
|
"name": "Seus Agendamentos",
|
||||||
"icon": "calendar",
|
"icon": "calendar",
|
||||||
"url": "/medico/agendamento"
|
"url": "/medico/agendamento"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Exceções de Disponibilidade",
|
|
||||||
"icon": "calendar-x-fill",
|
|
||||||
"url": "/medico/excecoes-disponibilidade"
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@ -377,8 +377,16 @@ const DeleteModal = () => (
|
|||||||
>
|
>
|
||||||
<i className="bi bi-plus-circle"></i> Adicionar Consulta
|
<i className="bi bi-plus-circle"></i> Adicionar Consulta
|
||||||
</button>
|
</button>
|
||||||
<button className="manage-button btn" onClick={() => navigate("/secretaria/excecoes-disponibilidade")}><i className="bi bi-gear-fill me-1"></i> Gerenciar Exceções</button>
|
<button
|
||||||
<button className='manage-button btn' onClick={() => navigate('/secretaria/disponibilidade')}><i className="bi bi-gear-fill me-1"></i> Mudar Disponibilidade</button>
|
className="btn btn-primary"
|
||||||
|
onClick={() => navigate("/medico/excecoes-disponibilidade")}>
|
||||||
|
<i className="bi bi-gear-fill me-1"></i> Gerenciar Exceções de Disponibilidade
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='btn btn-primary'
|
||||||
|
onClick={() => navigate('/secretaria/disponibilidade')}>
|
||||||
|
<i className="bi bi-gear-fill me-1"></i> Mudar Disponibilidade
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{!PageNovaConsulta ? (
|
{!PageNovaConsulta ? (
|
||||||
<div className='atendimento-eprocura'>
|
<div className='atendimento-eprocura'>
|
||||||
|
|||||||
@ -2,6 +2,10 @@ 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/FormExcecaoDisponibilidade';
|
||||||
|
|
||||||
|
import '../../_assets/css/components/agendamento/FormAgendamento.css';
|
||||||
|
import '../../_assets/css/pages/agendamento/Agendamento.css';
|
||||||
|
import '../../_assets/css/pages/agendamento/FilaEspera.css';
|
||||||
|
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import weekday from 'dayjs/plugin/weekday';
|
import weekday from 'dayjs/plugin/weekday';
|
||||||
import 'dayjs/locale/pt-br';
|
import 'dayjs/locale/pt-br';
|
||||||
@ -19,9 +23,12 @@ const getDateRange = (date, view) => {
|
|||||||
toDate = base.endOf('day').format('YYYY-MM-DD');
|
toDate = base.endOf('day').format('YYYY-MM-DD');
|
||||||
titleRange = base.format('DD/MM/YYYY');
|
titleRange = base.format('DD/MM/YYYY');
|
||||||
} else if (view === 'semanal') {
|
} else if (view === 'semanal') {
|
||||||
fromDate = base.startOf('week').format('YYYY-MM-DD');
|
let weekStart = base.startOf('week');
|
||||||
toDate = base.endOf('week').format('YYYY-MM-DD');
|
if (weekStart.day() !== 1) weekStart = base.weekday(1);
|
||||||
titleRange = `${base.startOf('week').format('DD/MM')} - ${base.endOf('week').format('DD/MM')}`;
|
const weekEnd = weekStart.add(6, 'day');
|
||||||
|
fromDate = weekStart.format('YYYY-MM-DD');
|
||||||
|
toDate = weekEnd.format('YYYY-MM-DD');
|
||||||
|
titleRange = `Semana de ${weekStart.format('DD/MM')} a ${weekEnd.format('DD/MM')}`;
|
||||||
} else { // mensal
|
} else { // mensal
|
||||||
fromDate = base.startOf('month').format('YYYY-MM-DD');
|
fromDate = base.startOf('month').format('YYYY-MM-DD');
|
||||||
toDate = base.endOf('month').format('YYYY-MM-DD');
|
toDate = base.endOf('month').format('YYYY-MM-DD');
|
||||||
@ -40,7 +47,7 @@ const ExcecoesDisponibilidadeDoctor = () => {
|
|||||||
const [erro, setErro] = useState('');
|
const [erro, setErro] = useState('');
|
||||||
const [buscaTexto, setBuscaTexto] = useState('');
|
const [buscaTexto, setBuscaTexto] = useState('');
|
||||||
|
|
||||||
const doctorID = user?.doctor_id || user?.id; // ajuste conforme estrutura real
|
const doctorID = user?.doctor_id || user?.id || '';
|
||||||
|
|
||||||
const { fromDate, toDate, titleRange } = useMemo(
|
const { fromDate, toDate, titleRange } = useMemo(
|
||||||
() => getDateRange(dataFiltro, visualizacao),
|
() => getDateRange(dataFiltro, visualizacao),
|
||||||
@ -52,7 +59,6 @@ const ExcecoesDisponibilidadeDoctor = () => {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
setErro('');
|
setErro('');
|
||||||
try {
|
try {
|
||||||
// trata getAuthorizationHeader() que pode retornar objeto ou string
|
|
||||||
const maybeAuth = getAuthorizationHeader();
|
const maybeAuth = getAuthorizationHeader();
|
||||||
const headers = {};
|
const headers = {};
|
||||||
if (typeof maybeAuth === 'string') {
|
if (typeof maybeAuth === 'string') {
|
||||||
@ -130,66 +136,95 @@ const ExcecoesDisponibilidadeDoctor = () => {
|
|||||||
setDataFiltro(nova.format('YYYY-MM-DD'));
|
setDataFiltro(nova.format('YYYY-MM-DD'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCancelForm = (recarregar = false) => {
|
||||||
|
setMostrarForm(false);
|
||||||
|
if (recarregar) fetchExcecoes();
|
||||||
|
};
|
||||||
|
|
||||||
if (mostrarForm) {
|
if (mostrarForm) {
|
||||||
return (
|
return (
|
||||||
|
<div>
|
||||||
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '15px' }}>
|
||||||
|
<h1>Gerenciar Exceções de Disponibilidade</h1>
|
||||||
|
</div>
|
||||||
<div className="container mt-3">
|
<div className="container mt-3">
|
||||||
<h4>Nova Exceção</h4>
|
|
||||||
<FormExcecaoDisponibilidade
|
<FormExcecaoDisponibilidade
|
||||||
doctorID={doctorID}
|
doctorID={doctorID}
|
||||||
onCancel={(reload) => {
|
onCancel={(reload) => handleCancelForm(reload)}
|
||||||
setMostrarForm(false);
|
|
||||||
if (reload) fetchExcecoes();
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container mt-3">
|
<div>
|
||||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '15px' }}>
|
||||||
<h4>Exceções de Disponibilidade</h4>
|
<h1>Gerenciar Exceções de Disponibilidade</h1>
|
||||||
<button className="btn btn-primary" onClick={() => setMostrarForm(true)}>
|
<button
|
||||||
Criar Exceção
|
className="btn-primary"
|
||||||
|
onClick={() => setMostrarForm(true)}
|
||||||
|
style={{ padding: '10px 20px', fontSize: '14px', whiteSpace: 'nowrap' }}
|
||||||
|
>
|
||||||
|
+ Criar Nova Exceção
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="d-flex gap-2 flex-wrap mb-3">
|
<div className='atendimento-eprocura'>
|
||||||
<div className="btn-group">
|
<div className='busca-atendimento'>
|
||||||
|
<div>
|
||||||
|
<i className="fa-solid fa-user-doctor"></i>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="ID do Médico"
|
||||||
|
value={doctorID}
|
||||||
|
readOnly
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<i className="fa-solid fa-calendar"></i>
|
||||||
|
<input
|
||||||
|
type="date"
|
||||||
|
value={dataFiltro}
|
||||||
|
onChange={(e) => setDataFiltro(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='container-btns-agenda-fila_esepera' style={{ marginTop: 8 }}>
|
||||||
<button
|
<button
|
||||||
className={`btn btn-sm ${visualizacao === 'diario' ? 'btn-secondary' : 'btn-outline-secondary'}`}
|
className={`btn-agenda ${visualizacao === "diario" ? "opc-agenda-ativo" : ""}`}
|
||||||
onClick={() => setVisualizacao('diario')}
|
onClick={() => setVisualizacao('diario')}
|
||||||
>
|
>
|
||||||
Diário
|
Dia
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={`btn btn-sm ${visualizacao === 'semanal' ? 'btn-secondary' : 'btn-outline-secondary'}`}
|
className={`btn-fila-espera ${visualizacao === "semanal" ? "opc-filaespera-ativo" : ""}`}
|
||||||
onClick={() => setVisualizacao('semanal')}
|
onClick={() => setVisualizacao('semanal')}
|
||||||
>
|
>
|
||||||
Semanal
|
Semana
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={`btn btn-sm ${visualizacao === 'mensal' ? 'btn-secondary' : 'btn-outline-secondary'}`}
|
className={`btn-fila-espera ${visualizacao === "mensal" ? "opc-filaespera-ativo" : ""}`}
|
||||||
onClick={() => setVisualizacao('mensal')}
|
onClick={() => setVisualizacao('mensal')}
|
||||||
>
|
>
|
||||||
Mensal
|
Mês
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="d-flex align-items-center gap-2">
|
<section className='calendario-ou-filaespera' style={{ marginTop: 12 }}>
|
||||||
|
<div className="fila-container">
|
||||||
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
|
<h2 className="fila-titulo">Exceções em {titleRange} ({excecoes.length})</h2>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||||
<button className="btn btn-outline-dark btn-sm" onClick={() => mudarData(-1)}><</button>
|
<button className="btn btn-outline-dark btn-sm" onClick={() => mudarData(-1)}><</button>
|
||||||
<strong>{titleRange}</strong>
|
<strong>{titleRange}</strong>
|
||||||
<button className="btn btn-outline-dark btn-sm" onClick={() => mudarData(1)}>></button>
|
<button className="btn btn-outline-dark btn-sm" onClick={() => mudarData(1)}>></button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<input
|
<div style={{ marginTop: 8, marginBottom: 8, display: 'flex', gap: 8, alignItems: 'center' }}>
|
||||||
type="date"
|
|
||||||
className="form-control form-control-sm"
|
|
||||||
value={dataFiltro}
|
|
||||||
onChange={e => setDataFiltro(e.target.value)}
|
|
||||||
style={{ maxWidth: 160 }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Buscar (motivo / tipo)"
|
placeholder="Buscar (motivo / tipo)"
|
||||||
@ -201,48 +236,62 @@ const ExcecoesDisponibilidadeDoctor = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{erro && <div className="alert alert-danger py-1">{erro}</div>}
|
{erro && <div className="alert alert-danger py-1">{erro}</div>}
|
||||||
{loading && <div>Carregando...</div>}
|
{loading ? (
|
||||||
|
<p>Carregando exceções...</p>
|
||||||
{!loading && excecoesFiltradas.length === 0 && (
|
) : excecoesFiltradas.length === 0 ? (
|
||||||
<div className="alert alert-info py-1">Nenhuma exceção neste intervalo.</div>
|
<p>Nenhuma exceção encontrada para os filtros aplicados.</p>
|
||||||
)}
|
) : (
|
||||||
|
<table className="fila-tabela">
|
||||||
{!loading && excecoesFiltradas.length > 0 && (
|
|
||||||
<div className="table-responsive">
|
|
||||||
<table className="table table-sm table-striped">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>Médico (Nome)</th>
|
||||||
<th>Data</th>
|
<th>Data</th>
|
||||||
<th>Início</th>
|
<th>Início</th>
|
||||||
<th>Término</th>
|
<th>Término</th>
|
||||||
<th>Tipo</th>
|
<th>Tipo</th>
|
||||||
<th>Motivo</th>
|
<th>Motivo</th>
|
||||||
<th></th>
|
<th>Ações</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{excecoesFiltradas.map(ex => (
|
{excecoesFiltradas.map((ex) => (
|
||||||
<tr key={ex.id}>
|
<tr key={ex.id}>
|
||||||
|
<td><p>{ex.doctor_name || ex.doctor_id || doctorID}</p></td>
|
||||||
<td>{ex.date ? dayjs(ex.date).format('DD/MM/YYYY') : '-'}</td>
|
<td>{ex.date ? dayjs(ex.date).format('DD/MM/YYYY') : '-'}</td>
|
||||||
<td>{ex.start_time || ex.inicio || '-'}</td>
|
<td>{ex.start_time ? (dayjs(ex.start_time, 'HH:mm:ss').isValid() ? dayjs(ex.start_time, 'HH:mm:ss').format('HH:mm') : ex.start_time) : (ex.inicio || '-')}</td>
|
||||||
<td>{ex.end_time || ex.termino || '-'}</td>
|
<td>{ex.end_time ? (dayjs(ex.end_time, 'HH:mm:ss').isValid() ? dayjs(ex.end_time, 'HH:mm:ss').format('HH:mm') : ex.end_time) : (ex.termino || '-')}</td>
|
||||||
<td>{ex.kind || ex.tipoAtendimento || '-'}</td>
|
<td>{ex.kind || ex.tipoAtendimento || '-'}</td>
|
||||||
<td>{ex.reason || ex.motivo || '-'}</td>
|
<td><p>{ex.reason || ex.motivo || '-'}</p></td>
|
||||||
<td>
|
<td>
|
||||||
|
<div className="d-flex gap-2">
|
||||||
<button
|
<button
|
||||||
className="btn btn-outline-danger btn-sm"
|
className="btn btn-sm btn-edit"
|
||||||
|
onClick={() => {
|
||||||
|
// ao editar, mostra o formulário. FormExcecaoDisponibilidade precisa lidar com edição via props
|
||||||
|
setMostrarForm(true);
|
||||||
|
// Form pode receber os dados via estado global/URL ou ser ajustado para receber o registro atual
|
||||||
|
} }
|
||||||
|
>
|
||||||
|
<i className="bi bi-pencil me-1"></i> Editar
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="btn btn-sm btn-delete"
|
||||||
onClick={() => handleDelete(ex.id)}
|
onClick={() => handleDelete(ex.id)}
|
||||||
>
|
>
|
||||||
Remover
|
<i className="bi bi-trash me-1"></i> Excluir
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -200,6 +200,16 @@ const ExcecoesDisponibilidade = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// navegação de datas (adicionada, mesma lógica da versão do médico)
|
||||||
|
const mudarData = (delta) => {
|
||||||
|
const base = dayjs(filtroData);
|
||||||
|
let nova;
|
||||||
|
if (visualizacao === 'diario') nova = base.add(delta, 'day');
|
||||||
|
else if (visualizacao === 'semanal') nova = base.add(delta, 'week');
|
||||||
|
else nova = base.add(delta, 'month');
|
||||||
|
setFiltroData(nova.format('YYYY-MM-DD'));
|
||||||
|
}
|
||||||
|
|
||||||
const handleCancelForm = (recarregar = false) => {
|
const handleCancelForm = (recarregar = false) => {
|
||||||
setPageNovaExcecao(false);
|
setPageNovaExcecao(false);
|
||||||
if (recarregar) {
|
if (recarregar) {
|
||||||
@ -273,7 +283,15 @@ const ExcecoesDisponibilidade = () => {
|
|||||||
{/* Tabela de Exceções (Título usa o titleRange calculado) */}
|
{/* Tabela de Exceções (Título usa o titleRange calculado) */}
|
||||||
<section className='calendario-ou-filaespera'>
|
<section className='calendario-ou-filaespera'>
|
||||||
<div className="fila-container">
|
<div className="fila-container">
|
||||||
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
<h2 className="fila-titulo">Exceções em {titleRange} ({excecoes.length})</h2>
|
<h2 className="fila-titulo">Exceções em {titleRange} ({excecoes.length})</h2>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||||
|
<button className="btn btn-outline-dark btn-sm" onClick={() => mudarData(-1)}><</button>
|
||||||
|
<strong>{titleRange}</strong>
|
||||||
|
<button className="btn btn-outline-dark btn-sm" onClick={() => mudarData(1)}>></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<p>Carregando exceções...</p>
|
<p>Carregando exceções...</p>
|
||||||
) : excecoes.length === 0 ? (
|
) : excecoes.length === 0 ? (
|
||||||
|
|||||||
@ -408,13 +408,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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user