From ce3f8e23dd9fbfb118ceecc2bc5b9bda95e8b2b9 Mon Sep 17 00:00:00 2001 From: joao_pedro Date: Fri, 31 Oct 2025 20:12:42 -0300 Subject: [PATCH 1/5] =?UTF-8?q?Toggle=20finalizado=20sem=20estiliza=C3=A7?= =?UTF-8?q?=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Sidebar.jsx | 95 ++++++++++--------- .../perfil_secretaria/PerfilSecretaria.jsx | 2 +- 2 files changed, 53 insertions(+), 44 deletions(-) diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx index e05dbeb..d920d0c 100644 --- a/src/components/Sidebar.jsx +++ b/src/components/Sidebar.jsx @@ -2,6 +2,15 @@ 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 { 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,52 +249,25 @@ function Sidebar({ menuItems }) {
+ + + + } + + ) +} + +export default ToggleSidebar \ No newline at end of file From d8e63f8abee1021249d1874775578419ea81c3d5 Mon Sep 17 00:00:00 2001 From: Caio Miguel Lima Nunes Date: Tue, 4 Nov 2025 15:39:02 -0300 Subject: [PATCH 3/5] =?UTF-8?q?Atualiza=C3=A7=C3=B5es=20de=20estilos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 14 - .../AgendarConsulta/FormNovaConsulta.jsx | 1 - .../style/formagendamentos.css | 248 +++++++++++--- src/components/Estilo/Toggle.css | 310 +++++++++++++++++- src/components/Sidebar.jsx | 10 +- src/components/ToggleSidebar.jsx | 191 ++++++----- src/components/doctors/DoctorForm.jsx | 1 - src/data/sidebar-items-adm.json | 4 - src/data/sidebar-items-financeiro.json | 4 - src/data/sidebar-items-medico.json | 4 - src/data/sidebar-items-secretaria.json | 5 - 11 files changed, 624 insertions(+), 168 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1663be2..3b9ac4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29151,18 +29151,6 @@ "minimalistic-assert": "^1.0.0" } }, -<<<<<<< HEAD - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "license": "MIT", - "peer": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", @@ -29172,8 +29160,6 @@ "node": ">= 8" } }, -======= ->>>>>>> c180e9a5c9e6bdaf28914332ba603acaf6d028a5 "node_modules/web-vitals": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", diff --git a/src/components/AgendarConsulta/FormNovaConsulta.jsx b/src/components/AgendarConsulta/FormNovaConsulta.jsx index 2dc2ef5..a3ec8f3 100644 --- a/src/components/AgendarConsulta/FormNovaConsulta.jsx +++ b/src/components/AgendarConsulta/FormNovaConsulta.jsx @@ -177,7 +177,6 @@ const FormNovaConsulta = ({ onCancel, onSave, setAgendamento, agendamento }) =>
Sucesso
-

Agendamento salvo com sucesso!

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 index 53827c6..22dac7b 100644 --- a/src/components/Estilo/Toggle.css +++ b/src/components/Estilo/Toggle.css @@ -1,9 +1,309 @@ -.toggle-title{ - color:#25396f; - font-weight: 1000; - font-size: 20px; +/* ========== 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-title{ +/* ========== 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 223e491..5922c08 100644 --- a/src/components/Sidebar.jsx +++ b/src/components/Sidebar.jsx @@ -1,6 +1,5 @@ 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"; @@ -9,6 +8,7 @@ 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"; @@ -264,13 +264,15 @@ function Sidebar({ menuItems }) { :null } + {roleUser.includes("admin") || roleUser.includes("financeiro") ? + + :null + } + {roleUser.includes("admin") || roleUser.includes("paciente") ? : null } - {/* Logout */} - -
diff --git a/src/components/ToggleSidebar.jsx b/src/components/ToggleSidebar.jsx index fc8e103..2065de1 100644 --- a/src/components/ToggleSidebar.jsx +++ b/src/components/ToggleSidebar.jsx @@ -1,102 +1,137 @@ import React from 'react' -import {useState} from 'react' -import { Link } from 'react-router-dom' +import { useState, useEffect } from 'react' +import { Link, useLocation } from 'react-router-dom' import "./Estilo/Toggle.css" -const ToggleSidebar = ({perfil, items}) => { - const [isOpen, setOpen] = useState(false) +const ToggleSidebar = ({ perfil, items, defaultOpen = false }) => { + const [isOpen, setOpen] = useState(defaultOpen) + const [openSubmenu, setOpenSubmenu] = useState(null) + const [activeLink, setActiveLink] = useState('') + const location = useLocation() - const [openSubmenu, setOpenSubmenu] = useState(null); + 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]) - console.log(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' : ''}` - const renderLink = (item) => { if (item.url && item.url.startsWith("/")) { return ( - + !isSubmenu && setActiveLink(item.url)} + > {item.icon && } {item.name} + {isActive &&
} - ); + ) } + return ( - + {item.icon && } {item.name} + - ); - }; - - const OpenClose = () => { - if(isOpen){ - setOpen(false) - }else if(!isOpen){ - setOpen(true) - } - } + ) + } return ( -
-
-

OpenClose()} className='toggle-title' > {perfil}

- - {isOpen ? : } -
- {isOpen && -
- {items.map((item, index) => { +
+
+

{perfil}

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

    Agendar nova consulta

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

    {medico.nomeMedico}

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

    {medico.nomeMedico}

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

    Fila de Espera

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

    {item.Infos?.paciente_nome}

    {item.Infos?.paciente_cpf}

    {item.Infos?.nome_medico}

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

    Fila de Espera

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

    Nenhuma solicitação encontrada com os filtros aplicados.

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

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

    -
    - - -
    - - - -
    - - -
    - -
    - - -
    - +
    + + +
    + +
    +
    + + +
    +
    + +

    Informações do atendimento

    + +
    +
    +
    + + +
    + + {isDropdownOpen && profissionaisFiltrados.length > 0 && ( +
    + {profissionaisFiltrados.map((profissional) => ( +
    handleSelectProfissional(profissional)} + > + {profissional.full_name} +
    + ))} +
    + )} +
    + +
    + + +
    +
    + +
    +
    +
    + + +
    + +
    +
    + + +
    + +
    + +
    + + +

    {sessoes}

    + + +
    +
    + +
    + + +
    +
    +
    + +
    + +