diff --git a/package-lock.json b/package-lock.json index df32786..eed1a01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28080,27 +28080,6 @@ } } }, - "node_modules/jsdom/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -28447,12 +28426,15 @@ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", "license": "MIT" }, +<<<<<<< HEAD "node_modules/long": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", "license": "Apache-2.0" }, +======= +>>>>>>> Modificacoes "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -31756,6 +31738,23 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -32881,6 +32880,20 @@ "node": ">=14.0.0" } }, + "node_modules/react-scripts/node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", @@ -35706,9 +35719,15 @@ } }, "node_modules/typescript": { +<<<<<<< HEAD "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", +======= + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", +>>>>>>> Modificacoes "license": "Apache-2.0", "peer": true, "bin": { @@ -35716,7 +35735,11 @@ "tsserver": "bin/tsserver" }, "engines": { +<<<<<<< HEAD "node": ">=4.2.0" +======= + "node": ">=14.17" +>>>>>>> Modificacoes } }, "node_modules/uc.micro": { @@ -36254,6 +36277,11 @@ "minimalistic-assert": "^1.0.0" } }, +<<<<<<< HEAD +======= +<<<<<<< HEAD +======= +>>>>>>> Modificacoes "node_modules/web-namespaces": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", @@ -36265,6 +36293,7 @@ "url": "https://github.com/sponsors/wooorm" } }, +>>>>>>> a3f1116608aac77dd74095ed474ef04c74999e3c "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", @@ -36767,6 +36796,27 @@ "node": ">= 0.6" } }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/webpack-manifest-plugin": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", @@ -37444,16 +37494,16 @@ } }, "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=8.3.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "utf-8-validate": "^5.0.2" }, "peerDependenciesMeta": { "bufferutil": { diff --git a/package.json b/package.json index 07df497..1d98465 100644 --- a/package.json +++ b/package.json @@ -84,4 +84,4 @@ "overrides": { "react": "$react" } -} +} \ No newline at end of file diff --git a/src/PagesPaciente/ConsultasPaciente.jsx b/src/PagesPaciente/ConsultasPaciente.jsx index bad704c..8390c8d 100644 --- a/src/PagesPaciente/ConsultasPaciente.jsx +++ b/src/PagesPaciente/ConsultasPaciente.jsx @@ -1,5 +1,6 @@ import React from 'react' import "./style.css" +import "../pages/style/TablePaciente.css" import CardConsultaPaciente from './CardConsultaPaciente' import { useNavigate } from 'react-router-dom' import { useEffect, useState, useMemo } from 'react' @@ -33,6 +34,15 @@ const ConsultasPaciente = ({ setDictInfo }) => { const [coresConsultas,setCoresConsultas] = useState([]) const [showConfirmModal, setShowConfirmModal] = useState(false) +<<<<<<< HEAD +======= + + // 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); +>>>>>>> Modificacoes useEffect(() => { @@ -208,6 +218,7 @@ const confirmConsulta = (selectedPatientId) => { {viewFila ? +<<<<<<< HEAD
{ listaConsultasID={listaConsultasID} setShowConfirmModal={setShowConfirmModal} />
+======= +
+
+
+
+
+

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 = filaDeEspera.filter((item) => { + const buscaNome = item?.paciente_nome?.toLowerCase().includes(searchTermFila.toLowerCase()); + const buscaCPF = item?.paciente_cpf?.toLowerCase().includes(searchTermFila.toLowerCase()); + const passaBusca = searchTermFila === "" || buscaNome || buscaCPF; + const passaMedico = filtroMedicoFila === "Todos" || item?.medico_nome?.toLowerCase().includes(filtroMedicoFila.toLowerCase()); + return passaBusca && passaMedico; + }); + return filtrados.length; + })()} DE {filaDeEspera.length} SOLICITAÇÕES ENCONTRADAS +
+
+
+ + {/* Filtros Ativos */} + {(searchTermFila || filtroMedicoFila !== "Todos") && ( +
+ Filtros ativos: +
+ {searchTermFila && Busca: "{searchTermFila}"} + {filtroMedicoFila !== "Todos" && Médico: {filtroMedicoFila}} +
+
+ )} + + {/* Tabela */} +
+ + + + + + + + + + + + {(() => { + // Filtrar dados + const filaFiltrada = filaDeEspera.filter((item) => { + const buscaNome = item?.paciente_nome?.toLowerCase().includes(searchTermFila.toLowerCase()); + const buscaCPF = item?.paciente_cpf?.toLowerCase().includes(searchTermFila.toLowerCase()); + const passaBusca = searchTermFila === "" || buscaNome || buscaCPF; + const passaMedico = filtroMedicoFila === "Todos" || item?.medico_nome?.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?.paciente_nome} +
+
{item?.paciente_cpf} + + {item?.medico_nome || 'Não informado'} + + {dayjs(item?.created_at).format('DD/MM/YYYY HH:mm')} +
+ +
+
+
+ +

Nenhuma solicitação encontrada com os filtros aplicados.

+ {(searchTermFila || filtroMedicoFila !== "Todos") && ( + + )} +
+
+ + {/* Paginação */} + {(() => { + const filaFiltrada = filaDeEspera.filter((item) => { + const buscaNome = item?.paciente_nome?.toLowerCase().includes(searchTermFila.toLowerCase()); + const buscaCPF = item?.paciente_cpf?.toLowerCase().includes(searchTermFila.toLowerCase()); + const passaBusca = searchTermFila === "" || buscaNome || buscaCPF; + const passaMedico = filtroMedicoFila === "Todos" || item?.medico_nome?.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: + + + Mostrando {indiceInicial + 1}-{Math.min(indiceFinal, filaFiltrada.length)} de {filaFiltrada.length} + +
+ + +
+ ); + } + return null; + })()} +
+
+
+
+
+
+ : +
+

Suas proximas consultas

+ + +
+>>>>>>> Modificacoes } {showDeleteModal && ( diff --git a/src/components/AgendarConsulta/style/formagendamentos.css b/src/components/AgendarConsulta/style/formagendamentos.css index 2e90f74..76ac620 100644 --- a/src/components/AgendarConsulta/style/formagendamentos.css +++ b/src/components/AgendarConsulta/style/formagendamentos.css @@ -414,96 +414,248 @@ html[data-bs-theme="dark"] svg { } +/* ========== Modal Overlay ========== */ .modal-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; - z-index: 1000; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 9999; + animation: fadeIn 0.3s ease-in; } -.modal-content { - background: white; - padding: 2rem; - border-radius: 12px; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); - max-width: 400px; - width: 90%; - text-align: center; - animation: modalAppear 0.3s ease-out; -} - -@keyframes modalAppear { +@keyframes fadeIn { from { opacity: 0; - transform: scale(0.9) translateY(-20px); } to { opacity: 1; - transform: scale(1) translateY(0); } } -.modal-header h3 { - margin: 0 0 1rem 0; - color: #28a745; - font-size: 1.5rem; - font-weight: 600; +/* ========== Modal Content ========== */ +.modal-content { + background-color: #fff; + border-radius: 10px; + width: 400px; + max-width: 90%; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); + overflow: hidden; + animation: slideIn 0.3s ease-out; } -.modal-body { - margin-bottom: 1.5rem; +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(-20px) scale(0.95); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } } -.modal-body p { +/* ========== Modal Header ========== */ +.modal-header { + background-color: #1e3a8a; + padding: 15px 20px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.modal-header.success { + background-color: #1e3a8a !important; +} + +.modal-header.error { + background-color: #dc3545 !important; +} + +.modal-header .modal-title { + color: #fff; margin: 0; - color: #333; - font-size: 1.1rem; - line-height: 1.5; + font-size: 1.2rem; + font-weight: bold; } +.modal-close-btn { + background: none; + border: none; + font-size: 20px; + color: #fff; + cursor: pointer; + padding: 0; + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + transition: background-color 0.2s; +} + +.modal-close-btn:hover { + background-color: rgba(255, 255, 255, 0.2); +} + +/* ========== Modal Body ========== */ +.modal-body { + padding: 25px 20px; + background: #fff; +} + +.modal-body .modal-message { + color: #111; + font-size: 1.1rem; + margin: 0; + font-weight: 600; + line-height: 1.4; + text-align: center; +} + +.modal-submessage { + color: #666; + font-size: 0.9rem; + margin: 10px 0 0 0; + line-height: 1.4; + text-align: center; +} + +/* ========== Modal Footer ========== */ .modal-footer { display: flex; - justify-content: center; + justify-content: flex-end; + padding: 15px 20px; + border-top: 1px solid #ddd; + background: #fff; } -.modal-footer .btn-primary { - background: #28a745; - padding: 10px 24px; +.modal-confirm-btn { + background-color: #1e3a8a; + color: #fff; + border: none; + padding: 8px 20px; + border-radius: 6px; + cursor: pointer; font-size: 1rem; - font-weight: 500; + font-weight: bold; + transition: all 0.2s ease; } -.modal-footer .btn-primary:hover { - background: #218838; +.modal-confirm-btn:hover { + background-color: #1e40af; + transform: translateY(-1px); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} + +.modal-confirm-btn.success { + background-color: #1e3a8a !important; +} + +.modal-confirm-btn.success:hover { + background-color: #1e40af !important; +} + +.modal-confirm-btn.error { + background-color: #dc3545 !important; +} + +.modal-confirm-btn.error:hover { + background-color: #c82333 !important; } +/* ========== Dark Mode ========== */ html[data-bs-theme="dark"] .modal-content { background: #232323 !important; - color: #e0e0e0 !important; - border: 1px solid #404053 !important; + border: 1px solid #404053; } -html[data-bs-theme="dark"] .modal-header h3 { - color: #4ade80 !important; +html[data-bs-theme="dark"] .modal-header { + background: #1e3a8a !important; } -html[data-bs-theme="dark"] .modal-body p { +html[data-bs-theme="dark"] .modal-header.success { + background-color: #1e3a8a !important; +} + +html[data-bs-theme="dark"] .modal-header.error { + background-color: #dc3545 !important; +} + +html[data-bs-theme="dark"] .modal-header .modal-title, +html[data-bs-theme="dark"] .modal-close-btn { + color: white !important; +} + +html[data-bs-theme="dark"] .modal-body { + background: #232323 !important; +} + +html[data-bs-theme="dark"] .modal-body .modal-message { color: #e0e0e0 !important; } -html[data-bs-theme="dark"] .modal-footer .btn-primary { - background: #16a34a !important; +html[data-bs-theme="dark"] .modal-submessage { + color: #b0b7c3 !important; } -html[data-bs-theme="dark"] .modal-footer .btn-primary:hover { - background: #15803d !important; +html[data-bs-theme="dark"] .modal-footer { + background: #232323 !important; + border-top: 1px solid #404053; +} + +html[data-bs-theme="dark"] .modal-confirm-btn { + background: #2563eb !important; +} + +html[data-bs-theme="dark"] .modal-confirm-btn:hover { + background: #1e40af !important; +} + +/* ========== Responsive ========== */ +@media (max-width: 768px) { + .modal-content { + width: 95%; + margin: 1rem; + } + + .modal-body { + padding: 20px 15px; + } + + .modal-message { + font-size: 1rem; + } +} + +@media (max-width: 480px) { + .modal-header { + padding: 12px 15px; + } + + .modal-header .modal-title { + font-size: 1.1rem; + } + + .modal-body { + padding: 15px; + } + + .modal-footer { + padding: 12px 15px; + } + + .modal-confirm-btn { + padding: 6px 16px; + font-size: 0.9rem; + } } diff --git a/src/components/Estilo/Toggle.css b/src/components/Estilo/Toggle.css new file mode 100644 index 0000000..22dac7b --- /dev/null +++ b/src/components/Estilo/Toggle.css @@ -0,0 +1,309 @@ +/* ========== Variáveis CSS ========== */ +:root { + --primary-blue: #4a90e2; + --primary-blue-light: #5da3f5; + --primary-blue-lighter: #70b4ff; + --dark-blue: #1a3a5c; + --dark-blue-deep: #0d2640; + --white: #ffffff; + --transition: all 0.3s ease; +} + +/* ========== Container Principal ========== */ +.toggle-sidebar-wrapper { + background: linear-gradient(135deg, var(--primary-blue) 0%, var(--primary-blue-light) 100%); + border-radius: 12px; + padding: 8px; + margin-bottom: 20px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); + border: 1px solid var(--primary-blue-lighter); +} + +.container-title { + display: flex; + align-items: center; + padding: 14px 20px; + cursor: pointer; + background-color: var(--primary-blue); + border-radius: 8px; + margin-bottom: 12px; + transition: var(--transition); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25); + border: 1px solid var(--primary-blue-light); +} + +.container-title:hover { + background-color: var(--primary-blue-light); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); + transform: translateY(-1px); +} + +.container-title:hover .toggle-arrow { + color: var(--dark-blue-deep) !important; + transform: scale(1.1); +} + +.toggle-title { + color: var(--white) !important; + font-weight: 700; + font-size: 18px; + margin: 0; + flex-grow: 1; + user-select: none; +} + +.toggle-arrow { + transition: var(--transition); + color: var(--dark-blue) !important; +} + +/* ========== Menu Lista ========== */ +.sidebar-menu-list { + list-style: none; + padding: 0; + margin: 0; + animation: fadeIn 0.3s ease; +} + +.sidebar-item { + list-style: none; + margin: 6px 0; + border-radius: 6px; + transition: all 0.2s ease; +} + +/* ========== Links da Sidebar ========== */ +.sidebar-link { + display: flex; + align-items: center; + text-decoration: none; + color: var(--white) !important; + padding: 12px 20px; + border-radius: 6px; + transition: all 0.2s ease; + font-size: 16px; + width: 100%; + text-align: left; + border: none; + background: none; + cursor: pointer; + position: relative; + overflow: hidden; + font-weight: 500; +} + +.sidebar-link::before { + content: ''; + position: absolute; + left: 0; + top: 0; + height: 100%; + width: 3px; + background-color: var(--dark-blue); + transform: scaleY(0); + transition: transform 0.2s ease; +} + +.sidebar-link i { + margin-right: 12px; + font-size: 19px; + transition: transform 0.2s ease; + color: var(--dark-blue) !important; +} + +.sidebar-link:hover { + color: var(--white) !important; + background-color: var(--primary-blue-light); + padding-left: 25px; +} + +.sidebar-link:hover::before { + transform: scaleY(1); +} + +.sidebar-link:hover i { + transform: scale(1.1); + color: var(--dark-blue-deep) !important; +} + +.sidebar-link.active { + color: var(--white) !important; + background-color: #1e3a8a; + font-weight: 600; + box-shadow: 0 4px 12px rgba(30, 58, 138, 0.4); + padding-left: 25px; +} + +.sidebar-link.active::before { + transform: scaleY(1); + background-color: var(--primary-blue-lighter); +} + +.sidebar-link.active i { + color: var(--white) !important; +} + +/* ========== Título da Sidebar ========== */ +.sidebar-title { + padding: 20px 20px 8px; + font-size: 14px; + color: var(--white) !important; + text-transform: uppercase; + font-weight: 700; + letter-spacing: 1px; + position: relative; +} + +.sidebar-title::after { + content: ''; + position: absolute; + bottom: 4px; + left: 20px; + right: 20px; + height: 2px; + background: linear-gradient(90deg, var(--white), transparent); +} + +/* ========== Itens com Submenu ========== */ +.sidebar-item.has-sub { + border-radius: 6px 6px 0 0; + overflow: hidden; + background-color: rgba(74, 144, 226, 0.6); +} + +.sidebar-item.has-sub.active { + background-color: var(--primary-blue-light); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); +} + +.sidebar-item.has-sub .sidebar-link { + background-color: var(--primary-blue); + color: var(--white) !important; +} + +.sidebar-item.has-sub .sidebar-link::after { + content: "\F282"; + font-family: "bootstrap-icons"; + font-weight: 900; + margin-left: auto; + transition: var(--transition); + display: flex; + align-items: center; + font-size: 14px; + color: var(--dark-blue) !important; +} + +.sidebar-item.has-sub.active .sidebar-link::after, +.sidebar-item.has-sub .sidebar-link:hover::after { + color: var(--dark-blue-deep) !important; +} + +.sidebar-item.has-sub.active .sidebar-link::after { + transform: rotate(180deg); +} + +.sidebar-item.has-sub .sidebar-link.submenu-active, +.sidebar-item.has-sub.active .sidebar-link.submenu-active { + color: var(--white) !important; +} + +.sidebar-item.has-sub .sidebar-link.submenu-active i { + color: var(--dark-blue) !important; +} + +.sidebar-item.has-sub.active .sidebar-link.submenu-active { + background-color: #1e3a8a; +} + +.sidebar-item.has-sub.active .sidebar-link.submenu-active i { + color: var(--white) !important; +} + +/* ========== Submenu ========== */ +.submenu { + list-style: none; + padding-left: 0; + margin: 0; + max-height: 0; + overflow: hidden; + transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1); + background-color: rgba(74, 144, 226, 0.9); + border-radius: 0 0 6px 6px; +} + +.sidebar-item.has-sub.active .submenu { + max-height: 800px; +} + +.submenu-item { + position: relative; +} + +.submenu-item .sidebar-link { + padding-left: 45px; + font-size: 15px; + color: var(--white) !important; + background-color: transparent; + font-weight: 500; +} + +.submenu-item .sidebar-link::before { + left: 30px; + width: 2px; + background-color: var(--dark-blue); +} + +.submenu-item .sidebar-link:hover { + background-color: var(--primary-blue-lighter); + color: var(--white) !important; + padding-left: 48px; +} + +.submenu-item .sidebar-link:hover::before { + background-color: var(--dark-blue-deep); +} + +.submenu-item:last-child .sidebar-link { + border-radius: 0 0 6px 6px; +} + +.sidebar-item.has-sub.active .submenu-item:first-child .sidebar-link { + border-radius: 0; +} + +.sidebar-link.submenu-link.active::before { + background-color: var(--primary-blue-lighter); +} + +/* ========== Ícones e Indicadores ========== */ +.external-icon { + font-size: 12px; + margin-left: 8px; + opacity: 0.8; + color: var(--dark-blue) !important; +} + +.active-indicator { + position: absolute; + right: 15px; + top: 50%; + transform: translateY(-50%); + width: 8px; + height: 8px; + background-color: var(--primary-blue-lighter); + border-radius: 50%; + animation: pulse 2s infinite; + box-shadow: 0 0 10px rgba(112, 180, 255, 0.6); +} + +/* ========== Animações ========== */ +@keyframes fadeIn { + from { opacity: 0; transform: translateY(-10px); } + to { opacity: 1; transform: translateY(0); } +} + +@keyframes pulse { + 0% { transform: translateY(-50%) scale(1); opacity: 1; } + 50% { transform: translateY(-50%) scale(1.3); opacity: 0.8; } + 100% { transform: translateY(-50%) scale(1); opacity: 1; } +} \ No newline at end of file diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx index e64a80f..5922c08 100644 --- a/src/components/Sidebar.jsx +++ b/src/components/Sidebar.jsx @@ -1,7 +1,16 @@ import React, { useState, useEffect } from "react"; import { Link, useNavigate } from "react-router-dom"; -import TrocardePerfis from "./TrocardePerfis"; import MobileMenuToggle from "./MobileMenuToggle"; +import ToggleSidebar from "./ToggleSidebar"; +import { useAuth } from "./utils/AuthProvider"; + +import PacienteItems from "../data/sidebar-items-paciente.json" +import DoctorItems from "../data/sidebar-items-medico.json" +import admItems from "../data/sidebar-items-adm.json" +import SecretariaItems from "../data/sidebar-items-secretaria.json" +import FinanceiroItems from "../data/sidebar-items-financeiro.json" + +import { UserInfos } from "./utils/Functions-Endpoints/General"; function Sidebar({ menuItems }) { const [isActive, setIsActive] = useState(true); @@ -10,6 +19,16 @@ function Sidebar({ menuItems }) { const [showLogoutModal, setShowLogoutModal] = useState(false); const navigate = useNavigate(); + const [roleUser, setRoleUser] = useState([]) + + const {getAuthorizationHeader} = useAuth(); + + const authHeader = getAuthorizationHeader(); + + + + + // Detecta se é mobile/tablet useEffect(() => { const checkScreenSize = () => { @@ -18,6 +37,15 @@ function Sidebar({ menuItems }) { setIsActive(!mobile); }; + const fetchInfoUser = async () => { + const InfoUser = await UserInfos(authHeader); + console.log(InfoUser.roles, "dados") + + setRoleUser(InfoUser.roles) + } + + fetchInfoUser() + checkScreenSize(); window.addEventListener("resize", checkScreenSize); return () => window.removeEventListener("resize", checkScreenSize); @@ -89,8 +117,16 @@ function Sidebar({ menuItems }) { } }; + useEffect(() => { + if(roleUser.includes("admin")){ + console.log("tem") + } + console.log(roleUser) + }, [roleUser]) + const handleLogoutCancel = () => setShowLogoutModal(false); + const renderLink = (item) => { if (item.url && item.url.startsWith("/")) { return ( @@ -213,55 +249,30 @@ function Sidebar({ menuItems }) {
diff --git a/src/components/ToggleSidebar.jsx b/src/components/ToggleSidebar.jsx new file mode 100644 index 0000000..2065de1 --- /dev/null +++ b/src/components/ToggleSidebar.jsx @@ -0,0 +1,139 @@ +import React from 'react' +import { useState, useEffect } from 'react' +import { Link, useLocation } from 'react-router-dom' +import "./Estilo/Toggle.css" + +const ToggleSidebar = ({ perfil, items, defaultOpen = false }) => { + const [isOpen, setOpen] = useState(defaultOpen) + const [openSubmenu, setOpenSubmenu] = useState(null) + const [activeLink, setActiveLink] = useState('') + const location = useLocation() + + useEffect(() => { + const currentPath = location.pathname + setActiveLink(currentPath) + + const findActiveSubmenu = () => { + for (let item of items) { + if (item.submenu) { + const activeSubItem = item.submenu.find(subItem => + subItem.url === currentPath + ) + if (activeSubItem) { + setOpenSubmenu(item.key) + return + } + } else if (item.url === currentPath) { + setActiveLink(currentPath) + } + } + } + + findActiveSubmenu() + }, [location.pathname, items]) + + const OpenClose = () => { + setOpen(!isOpen) + } + + const handleSubmenuClick = (key) => { + setOpenSubmenu(openSubmenu === key ? null : key) + } + + const isLinkActive = (url) => { + return activeLink === url + } + + const renderLink = (item, isSubmenu = false) => { + const isActive = isLinkActive(item.url) + const linkClass = `sidebar-link ${isActive ? 'active' : ''} ${isSubmenu ? 'submenu-link' : ''}` + + if (item.url && item.url.startsWith("/")) { + return ( + !isSubmenu && setActiveLink(item.url)} + > + {item.icon && } + {item.name} + {isActive &&
} + + ) + } + + return ( + + {item.icon && } + {item.name} + + + ) + } + + return ( +
+
+

{perfil}

+ {isOpen + ? + : + } +
+ + {isOpen && ( + + )} +
+ ) +} + +export default ToggleSidebar \ No newline at end of file diff --git a/src/components/doctors/DoctorForm.jsx b/src/components/doctors/DoctorForm.jsx index 8b74684..8f553ab 100644 --- a/src/components/doctors/DoctorForm.jsx +++ b/src/components/doctors/DoctorForm.jsx @@ -338,7 +338,6 @@ function DoctorForm({ onSave, onCancel, formData, setFormData, isLoading }) { } } - alert("Médico salvo com sucesso!"); } catch (error) { console.error("Erro ao salvar médico ou disponibilidade:", error); alert("Erro ao salvar médico ou disponibilidade."); diff --git a/src/data/sidebar-items-adm.json b/src/data/sidebar-items-adm.json index 4ab0555..be4969a 100644 --- a/src/data/sidebar-items-adm.json +++ b/src/data/sidebar-items-adm.json @@ -1,8 +1,4 @@ [ - { - "name": "Menu", - "isTitle": true - }, { "name": "Lista de Pacientes", "icon": "clipboard-heart-fill", diff --git a/src/data/sidebar-items-financeiro.json b/src/data/sidebar-items-financeiro.json index dfce9bc..0495b53 100644 --- a/src/data/sidebar-items-financeiro.json +++ b/src/data/sidebar-items-financeiro.json @@ -1,8 +1,4 @@ [ - { - "name": "Menu-Financeiro", - "isTitle": true - }, { "name": "Controle Financeiro", "icon": "cash-coin", diff --git a/src/data/sidebar-items-medico.json b/src/data/sidebar-items-medico.json index b22796a..b8b67b4 100644 --- a/src/data/sidebar-items-medico.json +++ b/src/data/sidebar-items-medico.json @@ -1,8 +1,4 @@ [ - { - "name": "Menu", - "isTitle": true - }, { "name": "Prontuário", diff --git a/src/data/sidebar-items-secretaria.json b/src/data/sidebar-items-secretaria.json index afe9e0a..c74cbf5 100644 --- a/src/data/sidebar-items-secretaria.json +++ b/src/data/sidebar-items-secretaria.json @@ -1,9 +1,4 @@ [ - { - "name": "Menu", - "isTitle": true - }, - { "name":"Início", "url": "/secretaria/", diff --git a/src/pages/Agendamento.jsx b/src/pages/Agendamento.jsx index 44e7e6a..3b15a4a 100644 --- a/src/pages/Agendamento.jsx +++ b/src/pages/Agendamento.jsx @@ -20,37 +20,42 @@ import './style/FilaEspera.css'; import { Search } from 'lucide-react'; import Spinner from '../components/Spinner.jsx'; +<<<<<<< HEAD + +======= +>>>>>>> Modificacoes -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([]) +<<<<<<< HEAD const [showConfirmModal, setShowConfirmModal] = useState(false) const [motivoCancelamento, setMotivoCancelamento] = useState("") @@ -64,15 +69,47 @@ const Agendamento = ({setDictInfo}) => { const cacheMedicos = {}; const cachePacientes = {}; +======= + const [showConfirmModal, setShowConfirmModal] = useState(false) - -useMemo(() => { - if (!listaTodosAgendamentos.length) return { agendamentosOrganizados: {}, filaEsperaData: [] }; -console.log("recarregando") - const DictAgendamentosOrganizados = {}; - const ListaFilaDeEspera = []; + const [motivoCancelamento, setMotivoCancelamento] = useState("") + const [corModal, setCorModal] = 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 = {}; +>>>>>>> Modificacoes + + 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); + } + +<<<<<<< HEAD const fetchDados = async () => { for (const agendamento of listaTodosAgendamentos) { @@ -112,30 +149,52 @@ console.log("recarregando") DictAgendamentosOrganizados[DiaAgendamento].push(agendamentoMelhorado); } else { DictAgendamentosOrganizados[DiaAgendamento] = [agendamentoMelhorado]; +======= + 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); + } else { + DictAgendamentosOrganizados[DiaAgendamento] = [agendamento]; + } +>>>>>>> Modificacoes } } - } - // 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(() => { @@ -151,15 +210,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() @@ -167,31 +227,13 @@ 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) +<<<<<<< HEAD const confirmConsulta = (selectedPatientId) => { var myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); @@ -215,6 +257,53 @@ const confirmConsulta = (selectedPatientId) => { .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)); + + } +>>>>>>> Modificacoes @@ -253,70 +342,84 @@ 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 } +<<<<<<< HEAD useEffect(() => { console.log("mudou FiltredTodosMedicos:", FiltredTodosMedicos); if (MedicoFiltrado.id != "vazio" ) { const unicoMedico = MedicoFiltrado; +======= + const handleClickAgendamento = (agendamento) => { + if (agendamento.status !== 'vazio') return + else setPageConsulta(true) + }; + + + useEffect(() => { + console.log("mudou FiltredTodosMedicos:", FiltredTodosMedicos); + if (MedicoFiltrado.id != "vazio") { + const unicoMedico = MedicoFiltrado; +>>>>>>> Modificacoes 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); +<<<<<<< HEAD }; useEffect(() => { @@ -328,27 +431,39 @@ useEffect(() => {

Agendar nova consulta

+======= + }; + + + return ( +
+
+

Agendar nova consulta

+ + +>>>>>>> Modificacoes
- - - - - + + + + +
{!PageNovaConsulta ? (
+<<<<<<< HEAD
{/* Bloco de busca por médico */} @@ -363,31 +478,47 @@ useEffect(() => { value={searchTermDoctor} onChange={(e) => handleSearchMedicos(e.target.value)} /> +======= +
+ + {/* Bloco de busca por médico */} +
+
+
+
+ + handleSearchMedicos(e.target.value)} + /> +>>>>>>> Modificacoes
-
- - {/* 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}

+
+ ))}
- )} + )} +
-
- +
@@ -436,57 +567,33 @@ useEffect(() => {
Cancelado
+<<<<<<< HEAD {/* Componentes de Tabela - Adicionado props de delete da main */} {tabela === "diario" && } {tabela === 'semanal' && } {tabela === 'mensal' && } +======= + + {/* Componentes de Tabela - Adicionado props de delete da main */} + {tabela === "diario" && } + {tabela === 'semanal' && } + {tabela === 'mensal' && } +>>>>>>> Modificacoes
) : ( -
-
- 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

+
+<<<<<<< HEAD
+======= +
+ {/* 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; + })()} +
+
+
+ + +>>>>>>> Modificacoes ) } @@ -519,8 +889,8 @@ useEffect(() => { )} - {/* Modal de Confirmação de Exclusão */} - {showDeleteModal && ( + {/* Modal de Confirmação de Exclusão */} + {showDeleteModal && (
{ >
- +
Confirmação de Cancelamento @@ -548,47 +918,49 @@ useEffect(() => {

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

-
- -