import React, { useState, useMemo, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import API_KEY from '../components/utils/apiKeys.js'; import AgendamentoCadastroManager from './AgendamentoCadastroManager.jsx'; import TabelaAgendamentoDia from '../components/AgendarConsulta/TabelaAgendamentoDia'; import TabelaAgendamentoSemana from '../components/AgendarConsulta/TabelaAgendamentoSemana'; import TabelaAgendamentoMes from '../components/AgendarConsulta/TabelaAgendamentoMes'; import FormNovaConsulta from '../components/AgendarConsulta/FormNovaConsulta'; // Importação de endpoints para lógica da Fila de Espera e Médicos (versão main) import { GetPatientByID } from '../components/utils/Functions-Endpoints/Patient.js'; import { GetAllDoctors, GetDoctorByID } from '../components/utils/Functions-Endpoints/Doctor.js'; import { useAuth } from '../components/utils/AuthProvider.js'; // ✨ NOVO: Caminho de importação corrigido com base na sua estrutura de pastas import AgendamentosMes from '../components/AgendarConsulta/DadosConsultasMock.js'; import dayjs from 'dayjs'; import "./style/Agendamento.css"; import './style/FilaEspera.css'; import { Search } from 'lucide-react'; const Agendamento = ({setDictInfo}) => { // Mantido setDictInfo (versão main) const navigate = useNavigate(); // Estados mesclados const [selectedID, setSelectedId] = useState('0') // (main) const [filaEsperaData, setfilaEsperaData] = useState([]) // (main) const [FiladeEspera, setFiladeEspera] = useState(false); const [tabela, setTabela] = useState('diario'); const [PageNovaConsulta, setPageConsulta] = useState(false); const [searchTerm, setSearchTerm] = useState(''); const [agendamentos, setAgendamentos] = useState() // (main) const {getAuthorizationHeader} = useAuth() const [DictAgendamentosOrganizados, setAgendamentosOrganizados ] = useState({}) const [showDeleteModal, setShowDeleteModal] = useState(false) const [AgendamentoFiltrado, setAgendamentoFiltrado] = useState() // (main) const [ListaDeMedicos, setListaDeMedicos] = useState([]) const [FiltredTodosMedicos, setFiltredTodosMedicos] = useState([]) const [searchTermDoctor, setSearchTermDoctor] = useState(''); let authHeader = getAuthorizationHeader() // Função FiltrarAgendamentos (Mesclado: Mantido o da MAIN, mais completo e com ordenação/fila de espera real) const FiltrarAgendamentos = async (listaTodosAgendamentos) => { const ConfigurarFiladeEspera = async (patient_id, doctor_id, agendamento) => { // Assumindo que GetDoctorByID e GetPatientByID estão definidos no seu escopo let medico = await GetDoctorByID(doctor_id, authHeader); let paciente = await GetPatientByID(patient_id, authHeader); let dicionario = { agendamento: agendamento, Infos: { nome_nedico: medico.full_name, doctor_id: medico.id, patient_id: paciente[0].id, paciente_nome: paciente[0].full_name, paciente_cpf: paciente[0].cpf } }; return dicionario; }; let DictAgendamentosOrganizados = {}; let ListaFilaDeEspera = []; // 1. Agrupamento for (const agendamento of listaTodosAgendamentos) { if (agendamento.status === 'requested') { let v = await ConfigurarFiladeEspera(agendamento.patient_id, agendamento.doctor_id, agendamento); ListaFilaDeEspera.push(v); } else { const DiaAgendamento = agendamento.scheduled_at.split("T")[0]; if (DiaAgendamento in DictAgendamentosOrganizados) { DictAgendamentosOrganizados[DiaAgendamento].push(agendamento); } else { DictAgendamentosOrganizados[DiaAgendamento] = [agendamento]; } } } // 2. Ordenação Interna: Ordenar os agendamentos por HORÁRIO (do menor para o maior) for (const DiaAgendamento in DictAgendamentosOrganizados) { DictAgendamentosOrganizados[DiaAgendamento].sort((a, b) => { if (a.scheduled_at < b.scheduled_at) return -1; if (a.scheduled_at > b.scheduled_at) return 1; return 0; }); } // 3. Ordenação Externa: Ordenar os DIAS const chavesOrdenadas = Object.keys(DictAgendamentosOrganizados).sort((a, b) => { if (a < b) return -1; if (a > b) return 1; return 0; }); let DictAgendamentosFinal = {}; for (const data of chavesOrdenadas) { DictAgendamentosFinal[data] = DictAgendamentosOrganizados[data]; } setAgendamentosOrganizados(DictAgendamentosFinal); setfilaEsperaData(ListaFilaDeEspera); }; // Requisição inicial (Mesclado: Mantido o da MAIN, pois o da disponibilidade2 não tem a ordenação/fila de espera no .then) 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);}) .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 })} setListaDeMedicos(lista) } PegarTodosOsMedicos() }, []) // Efeito de filtro de médico (Presente em ambas, mantida a lógica da MAIN/disponibilidade2 que se complementam) useEffect(() => { console.log("mudou FiltredTodosMedicos:", FiltredTodosMedicos); if (FiltredTodosMedicos.length === 1) { const unicoMedico = FiltredTodosMedicos[0]; console.log(unicoMedico) const idMedicoFiltrado = unicoMedico.idMedico; console.log(`Médico único encontrado: ${unicoMedico.nomeMedico}. ID: ${idMedicoFiltrado}`); const agendamentosDoMedico = filtrarAgendamentosPorMedico( 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) } }, [FiltredTodosMedicos]); // Função de Delete (Presente apenas na MAIN) const deleteConsulta = (selectedPatientId) => { console.log("tentando apagar") var myHeaders = new Headers(); myHeaders.append("Authorization", authHeader); myHeaders.append("apikey", API_KEY) var requestOptions = { method: 'DELETE', redirect: 'follow', headers: myHeaders }; fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?id=eq.${selectedPatientId}`, requestOptions) .then(response => response.json()) .then(result => console.log(result)) .catch(error => console.log('error', error)); } // Função auxiliar de filtro de médico (Presente em ambas, mantida a versão mais limpa) const filtrarAgendamentosPorMedico = (dictAgendamentos, idMedicoFiltrado) => { const todasAsListasDeAgendamentos = Object.values(dictAgendamentos); const todosOsAgendamentos = todasAsListasDeAgendamentos.flat(); const agendamentosFiltrados = todosOsAgendamentos.filter(agendamento => agendamento.doctor_id === idMedicoFiltrado ); return agendamentosFiltrados; }; // Lógica para filtrar os dados da AGENDA (useMemo) - (Presente em ambas, mantida a da MAIN, que está melhor formatada) const filteredAgendamentos = useMemo(() => { if (!searchTerm.trim()) { return AgendamentosMes; } const lowerCaseSearchTerm = searchTerm.toLowerCase(); const filteredData = {}; for (const semana in AgendamentosMes) { filteredData[semana] = {}; for (const dia in AgendamentosMes[semana]) { filteredData[semana][dia] = AgendamentosMes[semana][dia].filter(agendamento => agendamento.status === 'vazio' || (agendamento.paciente && agendamento.paciente.toLowerCase().includes(lowerCaseSearchTerm)) ); } } return filteredData; }, [searchTerm]); // ListarDiasdoMes (Presente em ambas) const ListarDiasdoMes = (ano, mes) => { let segundas = []; let tercas = []; let quartas = []; let quintas = []; let sextas = [] const base = dayjs(`${ano}-${mes}-01`) const DiasnoMes = base.daysInMonth() for (let d = 1; d <= DiasnoMes; d++) { const data = dayjs(`${ano}-${mes}-${d}`) const dia = data.format('dddd') switch (dia) { case 'Monday': segundas.push(d); break case 'Tuesday': tercas.push(d); break case 'Wednesday': quartas.push(d); break case 'Thursday': quintas.push(d); break case 'Friday': sextas.push(d); break default: break } } let ListaDiasDatas = {segundas:segundas,tercas:tercas,quartas: quartas,quintas: quintas,sextas: sextas} return ListaDiasDatas } // handleClickAgendamento (Presente em ambas) const handleClickAgendamento = (agendamento) => { if (agendamento.status !== 'vazio') return else setPageConsulta(true) }; // handleSearchMedicos (Presente em ambas) const handleSearchMedicos = (term) => { setSearchTermDoctor(term); if (term.trim() === '') { setFiltredTodosMedicos([]); return; } // Lógica simples de filtragem: const filtered = ListaDeMedicos.filter(medico => medico.nomeMedico.toLowerCase().includes(term.toLowerCase()) ); setFiltredTodosMedicos(filtered); }; const handleClickCancel = () => setPageConsulta(false) return (

Agendar nova consulta

{/* Mesclagem dos botões de navegação: Adicionar Consulta da main + Gerenciamento da disponibilidade2 */}
{!PageNovaConsulta ? (
{/* Bloco de busca por médico */}
handleSearchMedicos(e.target.value)} // Chama a nova função de filtro />
{/* DROPDOWN (RENDERIZAÇÃO CONDICIONAL) */} {searchTermDoctor && FiltredTodosMedicos.length > 0 && (
{FiltredTodosMedicos.map((medico) => (
{ setSearchTermDoctor(medico.nomeMedico); // Preenche o input // setFiltredTodosMedicos([]); // Opcional: fechar o dropdown }} >

{medico.nomeMedico}

))}
)}
{/* Div da disponibilidade2 - Unidade/Selecionar Profissional (manter) */}
{FiladeEspera === false ? (
Realizado
Confirmado
Agendado
Cancelado
{/* Componentes de Tabela - Adicionado props de delete da main */} {tabela === "diario" && } {tabela === 'semanal' && } {tabela === 'mensal' && }
) : ( // Fila de Espera - Restaurada a versão da MAIN com dados reais
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) => ( {/* Formatando a data de criação */} ))}
Nome do PacienteCPFMédico SolicitadoData da SolicitaçãoAções

{item.Infos?.paciente_nome}

{item.Infos?.paciente_cpf}

{item.Infos?.nome_nedico}

{dayjs(item.agendamento.created_at).format('DD/MM/YYYY HH:mm')}
) }
) : ( // AgendamentoCadastroManager - (Mesclado: Mantido o setPageConsulta da main) )} {/* Modal de Confirmação de Exclusão (Da MAIN) */} {showDeleteModal && (
e.target.classList.contains("modal") && setShowDeleteModal(false) } >
Confirmação de Exclusão

Tem certeza que deseja excluir este agendamento?

)}
) } export default Agendamento;