From e007c167e72add5f84927b197049d3f87a934a80 Mon Sep 17 00:00:00 2001 From: Caio Miguel Lima Nunes Date: Wed, 5 Nov 2025 21:27:13 -0300 Subject: [PATCH] Adicionado-novas-tabelas --- src/pages/Agendamento.jsx | 846 ++++++++++++++++++++------------ src/pages/style/Agendamento.css | 18 + 2 files changed, 553 insertions(+), 311 deletions(-) diff --git a/src/pages/Agendamento.jsx b/src/pages/Agendamento.jsx index 2e819a7..5325a5c 100644 --- a/src/pages/Agendamento.jsx +++ b/src/pages/Agendamento.jsx @@ -23,112 +23,116 @@ import { Search } from 'lucide-react'; -const Agendamento = ({setDictInfo}) => { +const Agendamento = ({ setDictInfo }) => { const navigate = useNavigate(); - + const [listaTodosAgendamentos, setListaTodosAgendamentos] = useState([]) - - const [selectedID, setSelectedId] = useState('0') + + const [selectedID, setSelectedId] = useState('0') const [filaEsperaData, setFilaEsperaData] = useState([]) const [FiladeEspera, setFiladeEspera] = useState(false); const [tabela, setTabela] = useState('diario'); const [PageNovaConsulta, setPageConsulta] = useState(false); const [searchTerm, setSearchTerm] = useState(''); - const [agendamentos, setAgendamentos] = useState() - const {getAuthorizationHeader} = useAuth() - const [DictAgendamentosOrganizados, setAgendamentosOrganizados ] = useState({}) + const [agendamentos, setAgendamentos] = useState() + const { getAuthorizationHeader } = useAuth() + const [DictAgendamentosOrganizados, setAgendamentosOrganizados] = useState({}) const [showDeleteModal, setShowDeleteModal] = useState(false) const [AgendamentoFiltrado, setAgendamentoFiltrado] = useState() - + const [ListaDeMedicos, setListaDeMedicos] = useState([]) const [FiltredTodosMedicos, setFiltredTodosMedicos] = useState([]) const [searchTermDoctor, setSearchTermDoctor] = useState(''); - const [MedicoFiltrado, setMedicoFiltrado] = useState({id:"vazio"}) + const [MedicoFiltrado, setMedicoFiltrado] = useState({ id: "vazio" }) - const [cacheAgendamentos, setCacheAgendamentos] = useState([]) + const [cacheAgendamentos, setCacheAgendamentos] = useState([]) - const [showConfirmModal, setShowConfirmModal] = useState(false) + const [showConfirmModal, setShowConfirmModal] = useState(false) - const [motivoCancelamento, setMotivoCancelamento] = useState("") + const [motivoCancelamento, setMotivoCancelamento] = useState("") - const [corModal, setCorModal] = useState("") + const [corModal, setCorModal] = useState("") - const [listaConsultasID, setListaConsultaID] = useState([]) - const [coresConsultas,setCoresConsultas] = useState([]) + const [listaConsultasID, setListaConsultaID] = useState([]) + const [coresConsultas, setCoresConsultas] = useState([]) + + // Estados para a tabela da fila de espera + const [searchTermFila, setSearchTermFila] = useState(''); + const [filtroMedicoFila, setFiltroMedicoFila] = useState('Todos'); + const [paginaAtualFila, setPaginaAtualFila] = useState(1); + const [itensPorPaginaFila, setItensPorPaginaFila] = useState(10); + + let authHeader = getAuthorizationHeader() + + const cacheMedicos = {}; + const cachePacientes = {}; - let authHeader = getAuthorizationHeader() - -const cacheMedicos = {}; -const cachePacientes = {}; + useMemo(() => { + if (!listaTodosAgendamentos.length) return { agendamentosOrganizados: {}, filaEsperaData: [] }; + console.log("recarregando") + const DictAgendamentosOrganizados = {}; + const ListaFilaDeEspera = []; + const fetchDados = async () => { + for (const agendamento of listaTodosAgendamentos) { + if (agendamento.status === "requested") { + // Cache de médico e paciente + if (!cacheMedicos[agendamento.doctor_id]) { + cacheMedicos[agendamento.doctor_id] = await GetDoctorByID(agendamento.doctor_id, authHeader); + } + if (!cachePacientes[agendamento.patient_id]) { + cachePacientes[agendamento.patient_id] = await GetPatientByID(agendamento.patient_id, authHeader); + } - -useMemo(() => { - if (!listaTodosAgendamentos.length) return { agendamentosOrganizados: {}, filaEsperaData: [] }; -console.log("recarregando") - const DictAgendamentosOrganizados = {}; - const ListaFilaDeEspera = []; + const medico = cacheMedicos[agendamento.doctor_id]; + const paciente = cachePacientes[agendamento.patient_id]; - const fetchDados = async () => { - for (const agendamento of listaTodosAgendamentos) { - if (agendamento.status === "requested") { - // Cache de médico e paciente - if (!cacheMedicos[agendamento.doctor_id]) { - cacheMedicos[agendamento.doctor_id] = await GetDoctorByID(agendamento.doctor_id, authHeader); - } - if (!cachePacientes[agendamento.patient_id]) { - cachePacientes[agendamento.patient_id] = await GetPatientByID(agendamento.patient_id, authHeader); - } - - const medico = cacheMedicos[agendamento.doctor_id]; - const paciente = cachePacientes[agendamento.patient_id]; - - ListaFilaDeEspera.push({ - agendamento, - Infos: { - nome_medico: medico[0]?.full_name, - doctor_id: medico[0]?.id, - patient_id: paciente[0]?.id, - paciente_nome: paciente[0]?.full_name, - paciente_cpf: paciente[0]?.cpf, - }, - }); - } else { - const DiaAgendamento = agendamento.scheduled_at.split("T")[0]; - - if (DiaAgendamento in DictAgendamentosOrganizados) { - DictAgendamentosOrganizados[DiaAgendamento].push(agendamento); + ListaFilaDeEspera.push({ + agendamento, + Infos: { + nome_medico: medico[0]?.full_name, + doctor_id: medico[0]?.id, + patient_id: paciente[0]?.id, + paciente_nome: paciente[0]?.full_name, + paciente_cpf: paciente[0]?.cpf, + }, + }); } else { - DictAgendamentosOrganizados[DiaAgendamento] = [agendamento]; + const DiaAgendamento = agendamento.scheduled_at.split("T")[0]; + + if (DiaAgendamento in DictAgendamentosOrganizados) { + DictAgendamentosOrganizados[DiaAgendamento].push(agendamento); + } else { + DictAgendamentosOrganizados[DiaAgendamento] = [agendamento]; + } } } - } - // Ordenar por data - for (const DiaAgendamento in DictAgendamentosOrganizados) { - DictAgendamentosOrganizados[DiaAgendamento].sort((a, b) => a.scheduled_at.localeCompare(b.scheduled_at)); - } + // Ordenar por data + for (const DiaAgendamento in DictAgendamentosOrganizados) { + DictAgendamentosOrganizados[DiaAgendamento].sort((a, b) => a.scheduled_at.localeCompare(b.scheduled_at)); + } - const chavesOrdenadas = Object.keys(DictAgendamentosOrganizados).sort(); + const chavesOrdenadas = Object.keys(DictAgendamentosOrganizados).sort(); - const DictAgendamentosFinal = {}; - for (const data of chavesOrdenadas) { - DictAgendamentosFinal[data] = DictAgendamentosOrganizados[data]; - } + const DictAgendamentosFinal = {}; + for (const data of chavesOrdenadas) { + DictAgendamentosFinal[data] = DictAgendamentosOrganizados[data]; + } - setAgendamentosOrganizados(DictAgendamentosFinal); - setFilaEsperaData(ListaFilaDeEspera); - }; + setAgendamentosOrganizados(DictAgendamentosFinal); + setFilaEsperaData(ListaFilaDeEspera); + }; - fetchDados(); + fetchDados(); - return { agendamentosOrganizados: DictAgendamentosOrganizados, filaEsperaData: ListaFilaDeEspera }; -}, [listaTodosAgendamentos]); // 👉 só recalcula quando a lista muda + return { agendamentosOrganizados: DictAgendamentosOrganizados, filaEsperaData: ListaFilaDeEspera }; + }, [listaTodosAgendamentos]); // 👉 só recalcula quando a lista muda useEffect(() => { @@ -144,15 +148,16 @@ console.log("recarregando") 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 => {setListaTodosAgendamentos(result);console.log(result)}) + .then(result => { setListaTodosAgendamentos(result); console.log(result) }) .catch(error => console.log('error', error)); const PegarTodosOsMedicos = async () => { let lista = [] const TodosOsMedicos = await GetAllDoctors(authHeader) - for(let d = 0; TodosOsMedicos.length > d; d++){ - lista.push({nomeMedico: TodosOsMedicos[d].full_name, idMedico: TodosOsMedicos[d].id })} + for (let d = 0; TodosOsMedicos.length > d; d++) { + lista.push({ nomeMedico: TodosOsMedicos[d].full_name, idMedico: TodosOsMedicos[d].id }) + } setListaDeMedicos(lista) } PegarTodosOsMedicos() @@ -160,55 +165,57 @@ console.log("recarregando") }, []) -const deleteConsulta = (selectedPatientId) => { - var myHeaders = new Headers(); - myHeaders.append("Content-Type", "application/json"); - myHeaders.append('apikey', API_KEY) - myHeaders.append("authorization", authHeader) - - - var raw = JSON.stringify({ "status":"cancelled", - "cancellation_reason": motivoCancelamento - }); - - - var requestOptions = { - method: 'PATCH', - headers: myHeaders, - body: raw, - redirect: 'follow' - }; - - fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?id=eq.${selectedPatientId}`, requestOptions) - .then(response => {if(response.status !== 200)(console.log(response))}) - .then(result => console.log(result)) - .catch(error => console.log('error', error)); -} + const deleteConsulta = (selectedPatientId) => { + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + myHeaders.append('apikey', API_KEY) + myHeaders.append("authorization", authHeader) -const confirmConsulta = (selectedPatientId) => { - var myHeaders = new Headers(); - myHeaders.append("Content-Type", "application/json"); - myHeaders.append('apikey', API_KEY) - myHeaders.append("authorization", authHeader) - - - var raw = JSON.stringify({ "status":"confirmed" - }); - - - var requestOptions = { - method: 'PATCH', - headers: myHeaders, - body: raw, - redirect: 'follow' - }; - - fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?id=eq.${selectedPatientId}`, requestOptions) - .then(response => {if(response.status !== 200)(console.log(response))}) - .then(result => console.log(result)) - .catch(error => console.log('error', error)); -} + var raw = JSON.stringify({ + "status": "cancelled", + "cancellation_reason": motivoCancelamento + }); + + + var requestOptions = { + method: 'PATCH', + headers: myHeaders, + body: raw, + redirect: 'follow' + }; + + fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?id=eq.${selectedPatientId}`, requestOptions) + .then(response => { if (response.status !== 200) (console.log(response)) }) + .then(result => console.log(result)) + .catch(error => console.log('error', error)); + } + + const confirmConsulta = (selectedPatientId) => { + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + myHeaders.append('apikey', API_KEY) + myHeaders.append("authorization", authHeader) + + + var raw = JSON.stringify({ + "status": "confirmed" + }); + + + var requestOptions = { + method: 'PATCH', + headers: myHeaders, + body: raw, + redirect: 'follow' + }; + + fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?id=eq.${selectedPatientId}`, requestOptions) + .then(response => { if (response.status !== 200) (console.log(response)) }) + .then(result => console.log(result)) + .catch(error => console.log('error', error)); + + } @@ -247,7 +254,7 @@ const confirmConsulta = (selectedPatientId) => { default: break } } - let ListaDiasDatas = {segundas:segundas,tercas:tercas,quartas: quartas,quintas: quintas,sextas: sextas} + let ListaDiasDatas = { segundas: segundas, tercas: tercas, quartas: quartas, quintas: quintas, sextas: sextas } return ListaDiasDatas } @@ -255,137 +262,137 @@ const confirmConsulta = (selectedPatientId) => { const handleClickAgendamento = (agendamento) => { if (agendamento.status !== 'vazio') return else setPageConsulta(true) -}; + }; - useEffect(() => { - console.log("mudou FiltredTodosMedicos:", FiltredTodosMedicos); - if (MedicoFiltrado.id != "vazio" ) { - const unicoMedico = MedicoFiltrado; + useEffect(() => { + console.log("mudou FiltredTodosMedicos:", FiltredTodosMedicos); + if (MedicoFiltrado.id != "vazio") { + const unicoMedico = MedicoFiltrado; console.log(unicoMedico) - const idMedicoFiltrado = unicoMedico.idMedico; + const idMedicoFiltrado = unicoMedico.idMedico; console.log(`Médico único encontrado: ${unicoMedico.nomeMedico}. ID: ${idMedicoFiltrado}`); - + const agendamentosDoMedico = filtrarAgendamentosPorMedico( - DictAgendamentosOrganizados, - idMedicoFiltrado - ); + DictAgendamentosOrganizados, + idMedicoFiltrado + ); console.log(`Total de agendamentos filtrados para este médico: ${agendamentosDoMedico.length}`); console.log("Lista completa de Agendamentos do Médico:", agendamentosDoMedico); //FiltrarAgendamentos(agendamentosDoMedico) setListaTodosAgendamentos(agendamentosDoMedico) - - } - }, [FiltredTodosMedicos, MedicoFiltrado]); -const filtrarAgendamentosPorMedico = (dictAgendamentos, idMedicoFiltrado) => { + } + }, [FiltredTodosMedicos, MedicoFiltrado]); + + const filtrarAgendamentosPorMedico = (dictAgendamentos, idMedicoFiltrado) => { setCacheAgendamentos(DictAgendamentosOrganizados); - + const todasAsListasDeAgendamentos = Object.values(dictAgendamentos); const todosOsAgendamentos = todasAsListasDeAgendamentos.flat(); - const agendamentosFiltrados = todosOsAgendamentos.filter(agendamento => - agendamento.doctor_id === idMedicoFiltrado + const agendamentosFiltrados = todosOsAgendamentos.filter(agendamento => + agendamento.doctor_id === idMedicoFiltrado ); return agendamentosFiltrados; -}; + }; -const handleSearchMedicos = (term) => { + const handleSearchMedicos = (term) => { setSearchTermDoctor(term); if (term.trim() === '') { - if(MedicoFiltrado.id !== "vazio"){ + if (MedicoFiltrado.id !== "vazio") { console.log("Medico escolhido, mas vai ser apagado") console.log(cacheAgendamentos, "cache ") - - } - - + + } + + setFiltredTodosMedicos([]); - setMedicoFiltrado({id:"vazio"}) - + setMedicoFiltrado({ id: "vazio" }) + //2 FiltrarAgendamentos() - return; + return; } - if (FiltredTodosMedicos.length === 1){ - setMedicoFiltrado({...FiltredTodosMedicos[0]}) + if (FiltredTodosMedicos.length === 1) { + setMedicoFiltrado({ ...FiltredTodosMedicos[0] }) } - - const filtered = ListaDeMedicos.filter(medico => - medico.nomeMedico.toLowerCase().includes(term.toLowerCase()) + + const filtered = ListaDeMedicos.filter(medico => + medico.nomeMedico.toLowerCase().includes(term.toLowerCase()) ); setFiltredTodosMedicos(filtered); -}; - + }; + return (

Agendar nova consulta

- - + +
- - - - - + + + + +
{!PageNovaConsulta ? (
-
- - {/* Bloco de busca por médico */} -
-
-
+
+ + {/* Bloco de busca por médico */} +
+
+
- - handleSearchMedicos(e.target.value)} - /> + + handleSearchMedicos(e.target.value)} + />
-
- - {/* DROPDOWN (RENDERIZAÇÃO CONDICIONAL) */} +
+ + {/* DROPDOWN (RENDERIZAÇÃO CONDICIONAL) */} {searchTermDoctor && FiltredTodosMedicos.length > 0 && (
- {FiltredTodosMedicos.map((medico) => ( -
{ - setSearchTermDoctor(medico.nomeMedico); - setFiltredTodosMedicos([]); - setMedicoFiltrado(medico) - - }} - > -

{medico.nomeMedico}

-
- ))} + {FiltredTodosMedicos.map((medico) => ( +
{ + setSearchTermDoctor(medico.nomeMedico); + setFiltredTodosMedicos([]); + setMedicoFiltrado(medico) + + }} + > +

{medico.nomeMedico}

+
+ ))}
- )} + )} +
-
- +
@@ -434,71 +441,285 @@ const handleSearchMedicos = (term) => {
Cancelado
- - {/* Componentes de Tabela - Adicionado props de delete da main */} + + {/* Componentes de Tabela - Adicionado props de delete da main */} {tabela === "diario" && } - {tabela === 'semanal' && } - {tabela === 'mensal' && } + {tabela === 'semanal' && } + {tabela === 'mensal' && }
) : ( -
-
- setSearchTerm(e.target.value)} - /> -

Fila de Espera

-
- - - - {/* Ajustado o cabeçalho */} - {/* Ajustado o cabeçalho */} - {/* Ajustado o cabeçalho */} - {/* Ajustado o cabeçalho */} - - - - - {filaEsperaData.map((item, index) => ( - - - - - - - - ))} - -
Nome do PacienteCPFMédico SolicitadoData da SolicitaçãoAções

{item.Infos?.paciente_nome}

{item.Infos?.paciente_cpf}

{item.Infos?.nome_medico}

{dayjs(item.agendamento.created_at).format('DD/MM/YYYY HH:mm')}
- - - +
+
+
+
+
+

Fila de Espera

+
- -
+
+ {/* Filtros */} +
+
+ Filtros +
+ +
+ setSearchTermFila(e.target.value)} + /> + + Digite o nome completo ou número do CPF + +
+ +
+ setFiltroMedicoFila(e.target.value || 'Todos')} + /> + + Digite o nome do médico para filtrar + +
+ +
+ +
+ +
+
+ {(() => { + const filtrados = filaEsperaData.filter((item) => { + const buscaNome = item.Infos?.paciente_nome?.toLowerCase().includes(searchTermFila.toLowerCase()); + const buscaCPF = item.Infos?.paciente_cpf?.toLowerCase().includes(searchTermFila.toLowerCase()); + const passaBusca = searchTermFila === "" || buscaNome || buscaCPF; + const passaMedico = filtroMedicoFila === "Todos" || item.Infos?.nome_medico?.toLowerCase().includes(filtroMedicoFila.toLowerCase()); + return passaBusca && passaMedico; + }); + return filtrados.length; + })()} DE {filaEsperaData.length} SOLICITAÇÕES ENCONTRADAS +
+
+
+ + {/* Filtros Ativos */} + {(searchTermFila || filtroMedicoFila !== "Todos") && ( +
+ Filtros ativos: +
+ {searchTermFila && Busca: "{searchTermFila}"} + {filtroMedicoFila !== "Todos" && Médico: {filtroMedicoFila}} +
+
+ )} + + {/* Tabela */} +
+ + + + + + + + + + + + {(() => { + // Filtrar dados + const filaFiltrada = filaEsperaData.filter((item) => { + const buscaNome = item.Infos?.paciente_nome?.toLowerCase().includes(searchTermFila.toLowerCase()); + const buscaCPF = item.Infos?.paciente_cpf?.toLowerCase().includes(searchTermFila.toLowerCase()); + const passaBusca = searchTermFila === "" || buscaNome || buscaCPF; + const passaMedico = filtroMedicoFila === "Todos" || item.Infos?.nome_medico?.toLowerCase().includes(filtroMedicoFila.toLowerCase()); + return passaBusca && passaMedico; + }); + + // Paginação + const totalPaginasFila = Math.ceil(filaFiltrada.length / itensPorPaginaFila); + const indiceInicial = (paginaAtualFila - 1) * itensPorPaginaFila; + const indiceFinal = indiceInicial + itensPorPaginaFila; + const filaPaginada = filaFiltrada.slice(indiceInicial, indiceFinal); + + if (filaPaginada.length > 0) { + return filaPaginada.map((item, index) => ( + + + + + + + + )); + } else { + return ( + + + + ); + } + })()} + +
Nome do PacienteCPFMédico SolicitadoData da SolicitaçãoAções
+
+ {item.Infos?.paciente_nome} +
+
{item.Infos?.paciente_cpf} + + {item.Infos?.nome_medico || 'Não informado'} + + {dayjs(item.agendamento.created_at).format('DD/MM/YYYY HH:mm')} +
+ + + +
+
+
+ +

Nenhuma solicitação encontrada com os filtros aplicados.

+ {(searchTermFila || filtroMedicoFila !== "Todos") && ( + + )} +
+
+ + {/* Paginação */} + {(() => { + const filaFiltrada = filaEsperaData.filter((item) => { + const buscaNome = item.Infos?.paciente_nome?.toLowerCase().includes(searchTermFila.toLowerCase()); + const buscaCPF = item.Infos?.paciente_cpf?.toLowerCase().includes(searchTermFila.toLowerCase()); + const passaBusca = searchTermFila === "" || buscaNome || buscaCPF; + const passaMedico = filtroMedicoFila === "Todos" || item.Infos?.nome_medico?.toLowerCase().includes(filtroMedicoFila.toLowerCase()); + return passaBusca && passaMedico; + }); + + const totalPaginasFila = Math.ceil(filaFiltrada.length / itensPorPaginaFila); + const indiceInicial = (paginaAtualFila - 1) * itensPorPaginaFila; + const indiceFinal = indiceInicial + itensPorPaginaFila; + + if (filaFiltrada.length > 0) { + return ( +
+
+ Itens por página: + +
+ +
+ + Página {paginaAtualFila} de {totalPaginasFila} • + Mostrando {indiceInicial + 1}-{Math.min(indiceFinal, filaFiltrada.length)} de {filaFiltrada.length} solicitações + + + +
+
+ ); + } + return null; + })()} +
+
+
+
+
) } @@ -508,8 +729,8 @@ const handleSearchMedicos = (term) => { )} - {/* Modal de Confirmação de Exclusão */} - {showDeleteModal && ( + {/* Modal de Confirmação de Exclusão */} + {showDeleteModal && (
{ >
- +
Confirmação de Cancelamento @@ -537,47 +758,49 @@ const handleSearchMedicos = (term) => {

- Qual o motivo do cancelamento? + Qual o motivo do cancelamento?

-
- -