diff --git a/package-lock.json b/package-lock.json
index 26a38b08..1d1f1bd5 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 728f80ba..3213c638 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 acd627c7..a1f1eaf4 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 a248f234..52632299 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 95a32380..b6cf99fb 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 0e94023d..62284339 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 21972607..99a3bd1b 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 d3c0e28e..befdd242 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 27febb34..9d2f0de8 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)}
- />
-
-
-
- Agendar
- Atendimento
- Sessões
- Urgência
-
-
+
+
+ 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}
+
+ ))}
+
+ )}
+
+
+
diff --git a/src/pages/style/Agendamento.css b/src/pages/style/Agendamento.css
index 8d1e7eb4..be2ea142 100644
--- a/src/pages/style/Agendamento.css
+++ b/src/pages/style/Agendamento.css
@@ -311,7 +311,7 @@ html[data-bs-theme="dark"] {
.container-botons{
display: flex;
- flex-direction: row;
+ flex-direction: column;
}
#tabela-seletor-container {
@@ -358,3 +358,80 @@ html[data-bs-theme="dark"] {
#tabela-seletor-container i {
pointer-events: none;
}
+/* 1. Contêiner de Limitação de Largura e Posicionamento */
+/* Este é o elemento mais importante. Ele deve envolver o input e o dropdown. */
+.input-e-dropdown-wrapper {
+ position: relative;
+
+ /* IMPORTANTE: Defina aqui a largura EXATA que você deseja para o input
+ e para o dropdown. Na sua imagem, o input parece ter cerca de 300px ou mais.
+ */
+ width: 350px; /* Ajuste este valor conforme a largura desejada do seu input */
+
+ /* Se o input original estava alinhado à direita (como na imagem),
+ você pode precisar de um float ou margin para posicionar este wrapper.
+ */
+ margin-left: auto; /* Exemplo para alinhar o wrapper à direita se for o caso */
+}
+
+/* 2. Estilização da Área de Busca (Input) */
+/* Garante que o input utilize toda a largura do wrapper */
+.busca-atendimento {
+ /* ... seus estilos de layout (flex, margin, etc.) para o busca-atendimento, se houver ... */
+}
+
+.busca-atendimento > div {
+ /* Garante que a div interna do input ocupe toda a largura do wrapper */
+ width: 100%;
+ /* Estilos para o contêiner do ícone e input, se necessário */
+}
+
+.busca-atendimento input {
+ /* Garante que o input preencha a largura disponível dentro do seu contêiner */
+ width: calc(100% - 40px); /* Exemplo: 100% menos a largura do ícone (aprox. 40px) */
+ /* ... outros estilos de borda, padding, etc. do seu input ... */
+}
+
+
+/* 3. O Dropdown: Posicionamento e Estilização */
+.dropdown-medicos {
+ /* POSICIONAMENTO: Faz o dropdown flutuar */
+ position: absolute;
+
+ /* POSICIONAMENTO: Coloca o topo do dropdown logo abaixo do input */
+ top: 100%;
+ left: 0;
+
+ /* LARGURA: Essencial. Ocupa 100% do .input-e-dropdown-wrapper, limitando-se a ele. */
+ width: 100%;
+
+ /* SOBREPOSIÇÃO: Garante que fique acima de outros elementos (como a Fila de Espera) */
+ z-index: 1000;
+
+ /* ESTILIZAÇÃO: Aparência */
+ background-color: #ffffff; /* Fundo branco para não vazar */
+ border: 1px solid #ccc; /* Borda leve */
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* Sombra para profundidade */
+ border-top: none; /* Deixa o visual mais integrado ao input */
+
+ /* COMPORTAMENTO: Limite de altura e scroll */
+ max-height: 250px;
+ overflow-y: auto;
+}
+
+/* 4. Estilização de cada item do dropdown */
+.dropdown-item {
+ padding: 10px 15px;
+ cursor: pointer;
+ font-size: 14px;
+ color: #333;
+ /* Evita que nomes muito longos quebrem ou saiam da caixa */
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.dropdown-item:hover {
+ background-color: #f0f0f0; /* Cor ao passar o mouse */
+ color: #007bff;
+}
\ No newline at end of file