diff --git a/src/components/paciente/FormCadastroPaciente.jsx b/src/components/paciente/FormCadastroPaciente.jsx index 95a3483..41c0c57 100644 --- a/src/components/paciente/FormCadastroPaciente.jsx +++ b/src/components/paciente/FormCadastroPaciente.jsx @@ -1,10 +1,9 @@ //PatientForm.jsx -//Nesta página falta: ajustar caminho do CSS import { useState, useEffect, useRef } from 'react'; import { Link } from 'react-router-dom'; import { FormatTelefones, FormatPeso, FormatCPF } from '../../_assets/utils/Formatar/Format'; -//import './PatientForm.css'; +import '../../_assets/css/components/paciente/FormCadastroPaciente.css'; function PatientForm({ onSave, onCancel, formData, setFormData, isLoading }) { const [avatarUrl, setAvatarUrl] = useState(null); diff --git a/src/pages/secretaria/CadastroMedico.jsx b/src/pages/secretaria/CadastroMedico.jsx index 2168cae..51280e0 100644 --- a/src/pages/secretaria/CadastroMedico.jsx +++ b/src/pages/secretaria/CadastroMedico.jsx @@ -208,7 +208,6 @@ function DoctorCadastroManager() {

Cadastro de Médicos

-
-
); } diff --git a/src/pages/secretaria/CadastroPaciente.jsx b/src/pages/secretaria/CadastroPaciente.jsx index b335e6b..7896bdd 100644 --- a/src/pages/secretaria/CadastroPaciente.jsx +++ b/src/pages/secretaria/CadastroPaciente.jsx @@ -1,5 +1,4 @@ //PatientCadastroManager.jsx -//Nesta página falta: mudar nomes import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; @@ -226,7 +225,6 @@ function PatientCadastroManager() { )} -
-
); } diff --git a/src/pages/secretaria/EditarMedico.jsx b/src/pages/secretaria/EditarMedico.jsx index 1a43cbe..7b2a1a7 100644 --- a/src/pages/secretaria/EditarMedico.jsx +++ b/src/pages/secretaria/EditarMedico.jsx @@ -1,5 +1,4 @@ //DoctorEditPage.jsx -//Nesta página falta: mudar nomes import { useState, useEffect, useMemo } from "react"; import { useParams, useNavigate, useLocation } from "react-router-dom"; diff --git a/src/pages/secretaria/ExcecoesDisponibilidade.jsx b/src/pages/secretaria/ExcecoesDisponibilidade.jsx index 221d738..4f197eb 100644 --- a/src/pages/secretaria/ExcecoesDisponibilidade.jsx +++ b/src/pages/secretaria/ExcecoesDisponibilidade.jsx @@ -17,7 +17,8 @@ import dayjs from 'dayjs'; dayjs.extend(weekday); dayjs.locale('pt-br'); -const ENDPOINT_BASE = "https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctor_exceptions"; +const ENDPOINT_BASE = "https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctor_exceptions"; +const API_ROOT = "https://yuanqfswhberkoevtmfr.supabase.co/rest/v1"; const getDateRange = (date, view) => { const startDayjs = dayjs(date); @@ -28,27 +29,23 @@ const getDateRange = (date, view) => { toDate = startDayjs.format('YYYY-MM-DD'); titleRange = startDayjs.format('DD/MM/YYYY'); } else if (view === 'semanal') { - - let weekStart = startDayjs.startOf('week'); - if (weekStart.day() !== 1) { - weekStart = startDayjs.weekday(1); + let weekStart = startDayjs.startOf('week'); + if (weekStart.day() !== 1) { + weekStart = startDayjs.weekday(1); } - 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 if (view === 'mensal') { const monthStart = startDayjs.startOf('month'); const monthEnd = startDayjs.endOf('month'); - fromDate = monthStart.format('YYYY-MM-DD'); toDate = monthEnd.format('YYYY-MM-DD'); titleRange = startDayjs.format('MMMM/YYYY').toUpperCase(); } - + return { fromDate, toDate, titleRange }; }; @@ -56,21 +53,25 @@ const ExcecoesDisponibilidade = () => { const { getAuthorizationHeader } = useAuth(); const navigate = useNavigate(); + const [pageNovaExcecao, setPageNovaExcecao] = useState(false); const [excecoes, setExcecoes] = useState([]); const [loading, setLoading] = useState(false); + const [showDeleteModal, setShowDeleteModal] = useState(false); const [selectedExceptionId, setSelectedExceptionId] = useState(null); + const [showSuccessModal, setShowSuccessModal] = useState(false); const [successMessage, setSuccessMessage] = useState(''); - + const [filtroMedicoId, setFiltroMedicoId] = useState(''); const [filtroData, setFiltroData] = useState(dayjs().format('YYYY-MM-DD')); + const [listaDeMedicos, setListaDeMedicos] = useState([]); const [searchTermDoctor, setSearchTermDoctor] = useState(''); const [filteredDoctors, setFilteredDoctors] = useState([]); const [selectedDoctor, setSelectedDoctor] = useState(null); - + const [visualizacao, setVisualizacao] = useState('diario'); const resolveAuthHeader = () => { @@ -80,56 +81,89 @@ const ExcecoesDisponibilidade = () => { } catch { return ''; } - } + }; const fetchExcecoes = useCallback(async (fromDate, toDate, doctorId) => { - setLoading(true); - + let url = `${ENDPOINT_BASE}?select=*`; - - if (doctorId) { - url += `&doctor_id=eq.${doctorId}`; - } - + + if (doctorId) url += `&doctor_id=eq.${doctorId}`; url += `&date=gte.${fromDate}&date=lte.${toDate}`; - + const myHeaders = new Headers(); const authHeader = resolveAuthHeader(); + if (authHeader) myHeaders.append("Authorization", authHeader); myHeaders.append("Content-Type", "application/json"); if (API_KEY) myHeaders.append("apikey", API_KEY); try { - const requestOptions = { - method: 'GET', - headers: myHeaders, - redirect: 'follow' - }; - - const response = await fetch(url, requestOptions); - const result = await response.json(); - - if (response.ok && Array.isArray(result)) { - setExcecoes(result); - } else { - setExcecoes([]); - console.error("Erro ao listar exceções (Status:", response.status, "):", result); - alert(`Erro ao carregar lista de exceções. Status: ${response.status}. Detalhes: ${result.message || JSON.stringify(result)}`); - } - } catch (error) { - console.error('Erro na requisição de listagem de exceções:', error); - setExcecoes([]); - alert("Erro de comunicação com o servidor ao listar exceções."); - } finally { - setLoading(false); - } - }, [getAuthorizationHeader]); + const response = await fetch(url, { method: 'GET', headers: myHeaders }); + const result = await response.json(); - const { fromDate, toDate, titleRange } = useMemo(() => - getDateRange(filtroData, visualizacao), - [filtroData, visualizacao] - ); + if (response.ok && Array.isArray(result)) { + + // Buscar nomes de médicos + let doctors = []; + try { + doctors = await GetAllDoctors(authHeader); + } catch (err) { + console.warn('Erro ao obter lista de médicos:', err); + doctors = []; + } + + const doctorMap = {}; + doctors.forEach(d => { + doctorMap[d.id] = d.full_name || d.name || d.display_name; + }); + + // Buscar criadores + const createdByIds = [...new Set(result.map(r => r.created_by).filter(Boolean))]; + const creatorMap = {}; + + if (createdByIds.length > 0) { + const idList = createdByIds.map(id => `"${id}"`).join(','); + const profilesUrl = `${API_ROOT}/profiles?select=*&id=in.(${idList})`; + + try { + const resProfiles = await fetch(profilesUrl, { method: 'GET', headers: myHeaders }); + if (resProfiles.ok) { + const profiles = await resProfiles.json(); + profiles.forEach(p => { + creatorMap[p.id] = p.full_name || p.name || p.username; + }); + } + } catch (err) { + console.warn('Erro ao buscar profiles:', err); + } + } + + // Enriquecer exceções + const enriched = result.map(r => ({ + ...r, + doctor_name: doctorMap[r.doctor_id] || r.doctor_id, + created_by_name: creatorMap[r.created_by] || r.created_by + })); + + setExcecoes(enriched); + + } else { + alert("Erro ao carregar exceções"); + setExcecoes([]); + } + + } catch (err) { + console.error(err); + alert("Erro ao comunicar com o servidor"); + setExcecoes([]); + } + + setLoading(false); + + }, [getAuthorizationHeader]); + + const { fromDate, toDate, titleRange } = useMemo(() => getDateRange(filtroData, visualizacao), [filtroData, visualizacao]); useEffect(() => { fetchExcecoes(fromDate, toDate, filtroMedicoId); @@ -143,43 +177,29 @@ const ExcecoesDisponibilidade = () => { if (API_KEY) myHeaders.append("apikey", API_KEY); try { - const response = await fetch('https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors?select=id,full_name', { - method: 'GET', - headers: myHeaders - }); + const response = await fetch(`${API_ROOT}/doctors?select=id,full_name`, { method: 'GET', headers: myHeaders }); if (response.ok) { const doctors = await response.json(); setListaDeMedicos(doctors); } - } catch (error) { - console.error('Erro ao buscar médicos:', error); + } catch (err) { + console.error('Erro ao buscar médicos:', err); } }; + fetchDoctors(); }, []); const handleSearchDoctors = (term) => { setSearchTermDoctor(term); - if (term.trim() === '') { - setFilteredDoctors([]); - return; - } - const filtered = listaDeMedicos.filter(doc => - doc.full_name.toLowerCase().includes(term.toLowerCase()) - ); + if (!term.trim()) return setFilteredDoctors([]); + const filtered = listaDeMedicos.filter(doc => doc.full_name.toLowerCase().includes(term.toLowerCase())); setFilteredDoctors(filtered); }; - const limparFiltros = () => { - setSearchTermDoctor(''); - setFilteredDoctors([]); - setSelectedDoctor(null); - setFiltroMedicoId(''); - setFiltroData(dayjs().format('YYYY-MM-DD')); - setVisualizacao('diario'); - }; + const deleteExcecao = async () => { + if (!selectedExceptionId) return; - const deleteExcecao = async (id) => { const myHeaders = new Headers(); const authHeader = resolveAuthHeader(); if (authHeader) myHeaders.append("Authorization", authHeader); @@ -187,33 +207,23 @@ const ExcecoesDisponibilidade = () => { myHeaders.append("Content-Type", "application/json"); try { - const res = await fetch(`${ENDPOINT_BASE}?id=eq.${id}`, { - method: 'DELETE', - headers: myHeaders, - redirect: 'follow' - }); + const res = await fetch(`${ENDPOINT_BASE}?id=eq.${selectedExceptionId}`, { method: 'DELETE', headers: myHeaders }); if (res.ok) { - setExcecoes(prev => prev.filter(x => x.id !== id)); + setExcecoes(prev => prev.filter(x => x.id !== selectedExceptionId)); setShowDeleteModal(false); setSuccessMessage('Exceção excluída com sucesso!'); setShowSuccessModal(true); - } else { - const text = await res.text(); - console.error('Erro ao deletar exceção', res.status, text); - alert(`Erro ao excluir exceção. Status: ${res.status}. ${text}`); } } catch (err) { - console.error('Erro na requisição de exclusão:', err); - alert('Erro ao excluir exceção.'); + console.error(err); + alert('Erro ao excluir exceção'); } - } + }; - const handleCancelForm = (recarregar = false) => { + const handleCancelForm = (reload = false) => { setPageNovaExcecao(false); - if (recarregar) { - fetchExcecoes(fromDate, toDate, filtroMedicoId); - } - } + if (reload) fetchExcecoes(fromDate, toDate, filtroMedicoId); + }; if (pageNovaExcecao) { return ; @@ -221,259 +231,123 @@ const ExcecoesDisponibilidade = () => { return (
- -
+

Gerenciar Exceções de Disponibilidade

- +
-
-
- - Filtros -
- + {/* Filtros */} +
+
Filtros
+
- handleSearchDoctors(e.target.value)} - /> - Filtre as exceções por médico - {searchTermDoctor && filteredDoctors.length > 0 && ( + handleSearchDoctors(e.target.value)} /> + + {filteredDoctors.length > 0 && (
- {filteredDoctors.map((doc) => ( - ))}
)}
- +
- - setFiltroData(e.target.value)} - /> - Selecione a data base para visualização + + setFiltroData(e.target.value)} />
-
-
- {selectedDoctor && ( - - - {selectedDoctor.full_name} - - )} -
- {excecoes.length} DE {excecoes.length} EXCEÇÕES ENCONTRADAS -
-
- - +
+ + +
-
+ {/* Tabela */} +
+

Exceções em {titleRange} ({excecoes.length})

+ {loading ? ( +

Carregando...

+ ) : excecoes.length === 0 ? ( +

Nenhuma exceção encontrada.

+ ) : ( + + + + + + + + + + + + + + {excecoes.map(exc => ( + + + + + + + + + + ))} + +
MédicoDataInícioTérminoMotivoCriado porAções
{exc.doctor_name}{dayjs(exc.date).format('DD/MM/YYYY')}{exc.start_time ? dayjs(exc.start_time, 'HH:mm:ss').format('HH:mm') : '—'}{exc.end_time ? dayjs(exc.end_time, 'HH:mm:ss').format('HH:mm') : '—'}{exc.reason}{exc.created_by_name} + -
- - - -
- - -
-
-

Exceções em {titleRange} ({excecoes.length})

- {loading ? ( -

Carregando exceções...

- ) : excecoes.length === 0 ? ( -

Nenhuma exceção encontrada para os filtros aplicados.

- ) : ( - - - - - - - - - - - - - - {excecoes.map((exc) => ( - - - - - - - - - - ))} - -
Médico (ID)DataInícioTérminoMotivoCriado porAções

{exc.doctor_id}

{dayjs(exc.date).format('DD/MM/YYYY')}{exc.start_time ? dayjs(exc.start_time, 'HH:mm:ss').format('HH:mm') : '—'}{exc.end_time ? dayjs(exc.end_time, 'HH:mm:ss').format('HH:mm') : '—'}

{exc.reason}

{exc.created_by || '—'} -
- - - -
-
- )} -
-
- + +
+ )} +
+ {/* Modal de exclusão */} {showDeleteModal && ( -
-
-
-
-
- Confirmação de Exclusão -
-
- -
-

- Tem certeza que deseja excluir esta exceção? -

-
- -
- - - -
+
+
+

Confirmar exclusão

+

Deseja realmente excluir esta exceção?

+
+ +
)} - {showSuccessModal && ( -
-
-
-
-
- Sucesso -
-
- -
-

- {successMessage} -

-
- -
- -
-
+
+
+

Sucesso

+

{successMessage}

+
)} +
); -} +}; export default ExcecoesDisponibilidade; \ No newline at end of file