From 7474639137f18d338cc5ec565eb769cd1741186c Mon Sep 17 00:00:00 2001 From: jp-lima Date: Fri, 17 Oct 2025 10:23:37 -0300 Subject: [PATCH] =?UTF-8?q?Agendamentos=20da=20secretaria=20filtrado=20pel?= =?UTF-8?q?o=20id=20do=20m=C3=A9dico?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 103 +++++++++++ package.json | 1 + .../AgendarConsulta/CardConsulta.jsx | 9 +- .../AgendarConsulta/TabelaAgendamentoDia.jsx | 3 +- .../TabelaAgendamentoSemana.jsx | 1 - .../style/styleTabelas/tabeladia.css | 7 +- .../style/styleTabelas/tabelames.css | 3 +- .../utils/Functions-Endpoints/Doctor.js | 2 +- src/pages/Agendamento.jsx | 166 +++++++++++++++--- src/pages/style/Agendamento.css | 79 ++++++++- 10 files changed, 337 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index 26a38b0..1d1f1bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "react-scripts": "5.0.1", "recharts": "^3.1.2", "sweetalert2": "^11.22.4", + "tiptap": "^1.32.2", "toastify-js": "^1.12.0", "web-vitals": "^2.1.4" }, @@ -19029,6 +19030,30 @@ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "license": "ISC" }, + "node_modules/@vue/compiler-sfc": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz", + "integrity": "sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==", + "peer": true, + "dependencies": { + "@babel/parser": "^7.23.5", + "postcss": "^8.4.14", + "source-map": "^0.6.1" + }, + "optionalDependencies": { + "prettier": "^1.18.2 || ^2.0.0" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -22153,6 +22178,13 @@ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==" }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "license": "MIT", + "peer": true + }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -34198,6 +34230,54 @@ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", "license": "MIT" }, + "node_modules/tiptap": { + "version": "1.32.2", + "resolved": "https://registry.npmjs.org/tiptap/-/tiptap-1.32.2.tgz", + "integrity": "sha512-5IwVj8nGo8y5V3jbdtoEd7xNUsi8Q0N6WV2Nfs70olqz3fldXkiImBrDhZJ4Anx8vhyP6PIBttrg0prFVmwIvw==", + "license": "MIT", + "dependencies": { + "prosemirror-commands": "^1.1.4", + "prosemirror-dropcursor": "^1.3.2", + "prosemirror-gapcursor": "^1.1.5", + "prosemirror-inputrules": "^1.1.3", + "prosemirror-keymap": "^1.1.4", + "prosemirror-model": "^1.13.1", + "prosemirror-state": "^1.3.3", + "prosemirror-view": "^1.16.5", + "tiptap-commands": "^1.17.1", + "tiptap-utils": "^1.13.1" + }, + "peerDependencies": { + "vue": "^2.5.17", + "vue-template-compiler": "^2.5.17" + } + }, + "node_modules/tiptap-commands": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/tiptap-commands/-/tiptap-commands-1.17.1.tgz", + "integrity": "sha512-CyGvMD/c6fNer5LThWGtrVMXHAqHn93ivGQpqJ58x3HNZFuoIiF9QTWXAiWbY/4QrG0ANYHKCSe9n5afickTqw==", + "license": "MIT", + "dependencies": { + "prosemirror-commands": "^1.1.4", + "prosemirror-inputrules": "^1.1.2", + "prosemirror-model": "^1.13.1", + "prosemirror-schema-list": "^1.1.4", + "prosemirror-state": "^1.3.3", + "prosemirror-tables": "^1.1.1", + "tiptap-utils": "^1.13.1" + } + }, + "node_modules/tiptap-utils": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/tiptap-utils/-/tiptap-utils-1.13.1.tgz", + "integrity": "sha512-RoCvMfkdu7fp9u7nsRr1OgsYU8RFjoHKHEKpx075rJ9X0t+j5Vxah9n6QzTTr4yjvcavq22WO2flFacm36zYtA==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.13.1", + "prosemirror-state": "^1.3.3", + "prosemirror-tables": "^1.1.1" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -34973,6 +35053,29 @@ "d3-timer": "^3.0.1" } }, + "node_modules/vue": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz", + "integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==", + "deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.", + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/compiler-sfc": "2.7.16", + "csstype": "^3.1.0" + } + }, + "node_modules/vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", diff --git a/package.json b/package.json index 728f80b..3213c63 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "react-scripts": "5.0.1", "recharts": "^3.1.2", "sweetalert2": "^11.22.4", + "tiptap": "^1.32.2", "toastify-js": "^1.12.0", "web-vitals": "^2.1.4" }, diff --git a/src/components/AgendarConsulta/CardConsulta.jsx b/src/components/AgendarConsulta/CardConsulta.jsx index acd627c..a1f1eaf 100644 --- a/src/components/AgendarConsulta/CardConsulta.jsx +++ b/src/components/AgendarConsulta/CardConsulta.jsx @@ -41,6 +41,10 @@ const CardConsulta = ( {DadosConsulta, TabelaAgendamento, setShowDeleteModal} ) BuscarMedicoEPaciente(); }, [ids, authHeader]); + let nameArrayPaciente = Paciente?.full_name.split(' ') + + let nameArrayMedico = Medico?.full_name.split(' ') + return (
@@ -51,11 +55,12 @@ const CardConsulta = ( {DadosConsulta, TabelaAgendamento, setShowDeleteModal} )
-

{DadosConsulta.horario} {Medico?.full_name}

+

{DadosConsulta.horario} {nameArrayMedico && nameArrayMedico.length > 0 ? nameArrayMedico[0] : ''} {nameArrayMedico && nameArrayMedico.length > 1 ? ` ${nameArrayMedico[1]}` : ''}

-

{Paciente?.full_name} - {DadosConsulta.exam}

+ +

{nameArrayPaciente && nameArrayPaciente.length > 0 ? nameArrayPaciente[0] : ''} {nameArrayPaciente && nameArrayPaciente.length > 1 ? ` ${nameArrayPaciente[1]}` : ''}- {}

diff --git a/src/components/AgendarConsulta/TabelaAgendamentoDia.jsx b/src/components/AgendarConsulta/TabelaAgendamentoDia.jsx index a248f23..5263229 100644 --- a/src/components/AgendarConsulta/TabelaAgendamentoDia.jsx +++ b/src/components/AgendarConsulta/TabelaAgendamentoDia.jsx @@ -12,14 +12,13 @@ const TabelaAgendamentoDia = ({ handleClickAgendamento, agendamentos, setShowDel - console.log(Dia, "hshdhshhsdhs") + //console.log(Dia, "hshdhshhsdhs") useEffect(() => { setDia(ListaDiasComAgendamentos[indiceAcesso]) }, [indiceAcesso]) - return (
diff --git a/src/components/AgendarConsulta/TabelaAgendamentoSemana.jsx b/src/components/AgendarConsulta/TabelaAgendamentoSemana.jsx index 95a3238..b6cf99f 100644 --- a/src/components/AgendarConsulta/TabelaAgendamentoSemana.jsx +++ b/src/components/AgendarConsulta/TabelaAgendamentoSemana.jsx @@ -138,7 +138,6 @@ const TabelaAgendamentoSemana = ({ agendamentos, ListarDiasdoMes }) => { diff --git a/src/components/AgendarConsulta/style/styleTabelas/tabeladia.css b/src/components/AgendarConsulta/style/styleTabelas/tabeladia.css index 0e94023..6228433 100644 --- a/src/components/AgendarConsulta/style/styleTabelas/tabeladia.css +++ b/src/components/AgendarConsulta/style/styleTabelas/tabeladia.css @@ -114,9 +114,4 @@ html[data-bs-theme="dark"] .mostrar-horario th { border: 1px solid #333; color: #e0e0e0; background-color: #232323; -} -/* -.container-botons{ - margin-left: 10rem; - background-color: pink; -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/components/AgendarConsulta/style/styleTabelas/tabelames.css b/src/components/AgendarConsulta/style/styleTabelas/tabelames.css index 2197260..99a3bd1 100644 --- a/src/components/AgendarConsulta/style/styleTabelas/tabelames.css +++ b/src/components/AgendarConsulta/style/styleTabelas/tabelames.css @@ -229,4 +229,5 @@ html[data-bs-theme="dark"] .cards-que-faltam { .container-botons{ margin-left: 5rem; -} \ No newline at end of file +} + diff --git a/src/components/utils/Functions-Endpoints/Doctor.js b/src/components/utils/Functions-Endpoints/Doctor.js index d3c0e28..befdd24 100644 --- a/src/components/utils/Functions-Endpoints/Doctor.js +++ b/src/components/utils/Functions-Endpoints/Doctor.js @@ -53,4 +53,4 @@ const GetDoctorByName = async (nome, authHeader) => { } -export {GetDoctorByID, GetDoctorByName} \ No newline at end of file +export {GetDoctorByID, GetDoctorByName, GetAllDoctors} \ No newline at end of file diff --git a/src/pages/Agendamento.jsx b/src/pages/Agendamento.jsx index 27febb3..9d2f0de 100644 --- a/src/pages/Agendamento.jsx +++ b/src/pages/Agendamento.jsx @@ -6,6 +6,9 @@ import TabelaAgendamentoDia from '../components/AgendarConsulta/TabelaAgendament import TabelaAgendamentoSemana from '../components/AgendarConsulta/TabelaAgendamentoSemana'; import TabelaAgendamentoMes from '../components/AgendarConsulta/TabelaAgendamentoMes'; import FormNovaConsulta from '../components/AgendarConsulta/FormNovaConsulta'; + +import { GetAllDoctors } 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'; @@ -14,6 +17,9 @@ 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 = () => { const navigate = useNavigate(); @@ -28,6 +34,10 @@ const Agendamento = () => { const [showDeleteModal, setShowDeleteModal] = useState(false) const [AgendamentoFiltrado, setAgendamentoFiltrado] = useState() + + const [ListaDeMedicos, setListaDeMedicos] = useState([]) + const [FiltredTodosMedicos, setFiltredTodosMedicos] = useState([]) + const [searchTermDoctor, setSearchTermDoctor] = useState(''); let authHeader = getAuthorizationHeader() @@ -39,7 +49,7 @@ const Agendamento = () => { const agendamento = listaTodosAgendamentos[i]; const DiaAgendamento = agendamento.scheduled_at.split("T")[0]; - console.log(DictAgendamentosOrganizados) + //console.log(DictAgendamentosOrganizados) if (DiaAgendamento in DictAgendamentosOrganizados) { // já existe a data → adiciona na lista @@ -50,14 +60,13 @@ const Agendamento = () => { } } - // faz o set de uma vez só ✅ + setAgendamentosOrganizados(DictAgendamentosOrganizados); } // Requisição inicial para mostrar os agendamentos do banco de dados useEffect(() => { - var myHeaders = new Headers(); myHeaders.append("Authorization", authHeader); myHeaders.append("apikey", API_KEY) @@ -70,10 +79,86 @@ const Agendamento = () => { 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); console.log(result, "aqui")}) + .then(result => {FiltrarAgendamentos(result);}) .catch(error => console.log('error', error)); + + const PegarTodosOsMedicos = async () => { + let lista = [] + const TodosOsMedicos = await GetAllDoctors(authHeader) + + //console.log(TodosOsMedicos, "tentativa") + for(let d = 0; TodosOsMedicos.length > d; d++){ + lista.push({nomeMedico: TodosOsMedicos[d].full_name, idMedico: TodosOsMedicos[d].id })} + setListaDeMedicos(lista) + } + PegarTodosOsMedicos() + }, []) + 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) + + + // AQUI VOCÊ PODE APLICAR SUA LÓGICA FINAL: + // Ex: setar um novo estado com os agendamentos filtrados, se for necessário: + // setAgendamentosFiltrados(agendamentosDoMedico); + + + } else { + // Opcional: Limpar a lista filtrada se a busca não for mais única + // setAgendamentosFiltrados([]); + } + + }, [FiltredTodosMedicos]); + + + +/** + * Filtra todos os agendamentos em um objeto aninhado (data -> [agendamentos]) + * com base no ID do médico. + * + * @param {Object} dictAgendamentos - O dicionário de agendamentos. + * @param {string} idMedicoFiltrado - O ID do médico (doctor_id) para ser usado como filtro. + * @returns {Array} Um array contendo todos os agendamentos que correspondem ao idMedicoFiltrado. + */ +const filtrarAgendamentosPorMedico = (dictAgendamentos, idMedicoFiltrado) => { + + // O corpo da função deve usar esses nomes de variáveis: + const todasAsListasDeAgendamentos = Object.values(dictAgendamentos); + + const todosOsAgendamentos = todasAsListasDeAgendamentos.flat(); + + const agendamentosFiltrados = todosOsAgendamentos.filter(agendamento => + agendamento.doctor_id === idMedicoFiltrado + ); + + return agendamentosFiltrados; +}; + + // Dados da fila de espera (sem alteração) @@ -101,7 +186,6 @@ const Agendamento = () => { if (!searchTerm.trim()) { return AgendamentosMes; } - const lowerCaseSearchTerm = searchTerm.toLowerCase(); const filteredData = {}; @@ -140,7 +224,23 @@ const Agendamento = () => { const handleClickAgendamento = (agendamento) => { if (agendamento.status !== 'vazio') return else setPageConsulta(true) - } +}; + + +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) @@ -154,25 +254,45 @@ const Agendamento = () => { {!PageNovaConsulta ? (
+ +
+ +
+
-
- - setSearchTerm(e.target.value)} - /> -
-
- -
+
+ + handleSearchMedicos(e.target.value)} // Chama a nova função de filtro + /> +
+ + {/* DROPDOWN (RENDERIZAÇÃO CONDICIONAL) */} + {searchTermDoctor && FiltredTodosMedicos.length > 0 && ( +
+ {FiltredTodosMedicos.map((medico) => ( +
{ + // Ação ao selecionar o médico + setSearchTermDoctor(medico.nomeMedico); // Preenche o input + //setFiltredTodosMedicos([]); // Fecha o dropdown + // Lógica adicional, como selecionar o ID do médico... + }} + > +

{medico.nomeMedico}

+
+ ))} +
+ )} +
+
+