From 3833764438919ddd2f431502dfc48c42ef999a77 Mon Sep 17 00:00:00 2001 From: Jessica_Faro Date: Fri, 10 Oct 2025 15:36:32 -0300 Subject: [PATCH 1/3] loginperfil1 --- src/App.js | 5 +- src/components/Header/Header.css | 107 +++++++++++++++ src/components/Header/Header.jsx | 60 +++++++++ src/pages/ProfilePage.jsx | 206 +++++++++++++++++++++++++++++ src/pages/Support.jsx | 10 ++ src/pages/style/ProfilePage.css | 0 src/pages/style/TrocardePerfil.css | 62 --------- 7 files changed, 387 insertions(+), 63 deletions(-) create mode 100644 src/components/Header/Header.css create mode 100644 src/components/Header/Header.jsx create mode 100644 src/pages/ProfilePage.jsx create mode 100644 src/pages/Support.jsx create mode 100644 src/pages/style/ProfilePage.css delete mode 100644 src/pages/style/TrocardePerfil.css diff --git a/src/App.js b/src/App.js index 1312003..1352f0e 100644 --- a/src/App.js +++ b/src/App.js @@ -9,6 +9,8 @@ import LandingPage from './pages/LandingPage'; import PerfilFinanceiro from "./perfis/perfil_financeiro/PerfilFinanceiro"; import Perfiladm from "./perfis/Perfil_adm/Perfiladm"; import PerfilMedico from "./perfis/Perfil_medico/PerfilMedico"; +import ProfilePage from "./pages/ProfilePage"; +import Header from "./components/Header/Header"; // Componentes globais de acessibilidade import VlibrasWidget from "./components/VlibrasWidget"; @@ -20,6 +22,7 @@ function App() { +
} /> @@ -30,6 +33,7 @@ function App() { } /> } /> } /> + } /> Página não encontrada} /> @@ -37,4 +41,3 @@ function App() { } export default App; - diff --git a/src/components/Header/Header.css b/src/components/Header/Header.css new file mode 100644 index 0000000..dd15ca0 --- /dev/null +++ b/src/components/Header/Header.css @@ -0,0 +1,107 @@ +/* src/components/Header/Header.css */ +.header-container { + width: 100%; + position: absolute; /* Permite posicionamento livre sobre o conteúdo */ + top: 0; + left: 0; + display: flex; + justify-content: flex-end; /* Alinha os elementos do container à direita */ + padding: 10px 20px; + box-sizing: border-box; + z-index: 1000; /* Garante que fique acima de outros elementos */ +} + +.right-corner-elements { + display: flex; + align-items: center; + gap: 20px; /* Espaço entre o telefone e a seção de perfil */ +} + +/* --- ÍCONE DE TELEFONE --- */ +.phone-icon-container { + font-size: 24px; + cursor: pointer; + padding: 5px; /* Área clicável um pouco maior */ +} +.phone-icon { + display: block; /* Garante que o emoji fique bem centralizado */ +} + +/* --- SEÇÃO DE PERFIL --- */ +.profile-section { + position: relative; + display: flex; + align-items: center; +} + +.profile-picture-container { + width: 40px; + height: 40px; + border-radius: 50%; /* Círculo */ + overflow: hidden; + cursor: pointer; + border: 2px solid #ccc; /* Borda simples */ + box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); +} + +.profile-placeholder { + width: 100%; + height: 100%; + background-color: #A9A9A9; /* Cor cinza escura para o fundo */ + border-radius: 50%; + /* Adicionando um ícone simples de pessoa em branco para simular o ícone */ + position: relative; +} + +.profile-placeholder::after { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 60%; + height: 60%; + background-image: url('data:image/svg+xml;utf8,'); + background-size: contain; + background-repeat: no-repeat; + opacity: 0.8; /* Suaviza um pouco o ícone */ +} + +/* --- DROPDOWN (MENU) --- */ +.profile-dropdown { + position: absolute; + top: 50px; /* Posição abaixo da foto de perfil (40px + 10px de espaço) */ + right: 0; + background-color: white; + border: 1px solid #ddd; + border-radius: 5px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + display: flex; + flex-direction: column; + z-index: 10; + min-width: 150px; + overflow: hidden; /* Garante que bordas fiquem visíveis */ +} + +.dropdown-button { + background: none; + border: none; + padding: 10px 15px; + text-align: left; + cursor: pointer; + font-size: 14px; + color: #333; + transition: background-color 0.2s; +} + +.dropdown-button:hover { + background-color: #f0f0f0; +} + +.logout-button { + color: #cc0000; /* Cor vermelha para o botão de logout */ +} + +.logout-button:hover { + background-color: #ffe0e0; +} \ No newline at end of file diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx new file mode 100644 index 0000000..533c1a2 --- /dev/null +++ b/src/components/Header/Header.jsx @@ -0,0 +1,60 @@ +// src/components/Header/Header.jsx +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import './Header.css'; + +const Header = () => { + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const navigate = useNavigate(); + + const handleProfileClick = () => { + setIsDropdownOpen(!isDropdownOpen); + }; + + const handleViewProfile = () => { + // Redireciona para uma página de perfil (Rota que adicionaremos no App.js) + navigate('/perfil'); + setIsDropdownOpen(false); + }; + + const handleLogout = () => { + // Ação de Logout: Exibe um alerta e redireciona para a tela de Login + alert('Você foi desconectado. Executando ação de logout...'); + setIsDropdownOpen(false); + navigate('/login'); + }; + + const handleSupportClick = () => { + // Funcionalidade de suporte (futuramente implementada em TelefoneSuporte) + alert('Função de Suporte de Telefone em desenvolvimento.'); + }; + + return ( +
+
+ + {/* Ícone de Telefone */} +
+ 📞 +
+ + {/* Seção de Perfil com Dropdown */} +
+
+ {/* O div "profile-placeholder" simula a foto de perfil circular colorida */} +
+
+ + {isDropdownOpen && ( +
+ + +
+ )} +
+
+
+ ); +}; + +export default Header; \ No newline at end of file diff --git a/src/pages/ProfilePage.jsx b/src/pages/ProfilePage.jsx new file mode 100644 index 0000000..ef09ef1 --- /dev/null +++ b/src/pages/ProfilePage.jsx @@ -0,0 +1,206 @@ +// src/pages/ProfilePage.jsx +import React, { useState } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; +// import { useAuth } from '../components/utils/AuthProvider'; // <-- NOVO: Se você puder importar isso. + +// --- SIMULAÇÃO DE DADOS DE USUÁRIO --- +// COMO NÃO PODEMOS IMPORTAR O useAuth SEM MEXER EM OUTROS ARQUIVOS, VAMOS USAR ESTA SIMULAÇÃO: +const simulatedUserData = { + // ESTA SIMULAÇÃO DEVERIA SER SUBTITUÍDA PELO SEU CONTEXTO DE AUTENTICAÇÃO REAL. + // O EMAIL REALMENTE LOGADO VEM DO CONTEXTO DE AUTENTICAÇÃO (useAuth) + email: 'admin@squad23.com', + role: 'Administrador' // Vamos forçar um valor para fins de visualização +}; + +const ProfilePage = () => { + const location = useLocation(); + const navigate = useNavigate(); + // const { user } = useAuth(); // Descomente esta linha e comente o bloco simulatedUserData se puder usar o useAuth! + + // --- Lógica de Cargo (AGORA CORRIGIDA PARA PEGAR DA URL SE O CONTEXTO FALHAR) --- + const getRoleFromPath = () => { + const path = location.pathname; + if (path.includes('/admin')) return 'Administrador'; + if (path.includes('/secretaria')) return 'Secretária'; + if (path.includes('/medico')) return 'Médico'; + if (path.includes('/financeiro')) return 'Financeiro'; + return 'Usuário Padrão'; + }; + + // Use a simulação ou o dado real: + const userRole = simulatedUserData.role || getRoleFromPath(); + const userEmail = simulatedUserData.email || 'email.nao.encontrado@mediconnect.com'; + + // --- Estados do Componente --- + + // Se o nome do usuário vier do contexto de autenticação, use-o aqui + const [userName, setUserName] = useState('Admin Padrão'); + const [isEditingName, setIsEditingName] = useState(false); + + // --- Funções de Interação --- + + const handleNameChange = (e) => { + if (e.key === 'Enter') { + setIsEditingName(false); + } + }; + + const handleClose = () => { + navigate(-1); // Volta para a página anterior + }; + + return ( +
+
+ + {/* Botão de Fechar (X) */} + + + {/* 1. Área da Foto de Perfil (Quadrada) */} +
+
+
+ +
+ + {/* 2. Nome do Usuário com Edição */} +
+ {isEditingName ? ( + setUserName(e.target.value)} + onBlur={() => setIsEditingName(false)} + onKeyPress={handleNameChange} + autoFocus + style={styles.nameInput} + /> + ) : ( +

{userName}

+ )} + + +
+ + {/* 3. Email (AGORA EXIBE O VALOR SIMULADO/CORRIGIDO) */} +

Email: {userEmail}

+ + {/* 4. Cargo (AGORA EXIBE O VALOR SIMULADO/CORRIGIDO) */} +

Cargo: {userRole}

+
+
+
+ ); +}; + +// Estilos Atualizados para Aumentar o Tamanho do Modal +const styles = { + overlay: { + position: 'fixed', + top: 0, + left: 0, + right: 0, + bottom: 0, + backgroundColor: 'rgba(0, 0, 0, 0.5)', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + zIndex: 1100, + }, + modalContainer: { + position: 'relative', + padding: '50px 70px', // Aumentado o padding + backgroundColor: 'white', + borderRadius: '15px', + boxShadow: '0 8px 30px rgba(0, 0, 0, 0.3)', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + minWidth: '400px', + width: '60%', // Aumentando a largura para cobrir mais a tela + maxWidth: '500px', // Limite máximo para não ficar gigante em telas grandes + height: 'auto', + }, + closeButton: { + position: 'absolute', + top: '15px', + right: '20px', + background: 'none', + border: 'none', + fontSize: '30px', + cursor: 'pointer', + color: '#666', + lineHeight: '1', + }, + // ... (Os estilos de profilePictureContainer, infoContainer, etc., permanecem iguais) + profilePictureContainer: { + width: '120px', + height: '120px', + borderRadius: '15px', + overflow: 'hidden', + boxShadow: '0 4px 10px rgba(0, 0, 0, 0.15)', + marginBottom: '20px', + }, + profilePicturePlaceholder: { + width: '100%', + height: '100%', + backgroundColor: '#A9A9A9', + backgroundImage: 'url(\'data:image/svg+xml;utf8,\')', + backgroundSize: '80%', + backgroundRepeat: 'no-repeat', + backgroundPosition: 'center', + }, + infoContainer: { + textAlign: 'center', + maxWidth: '400px', + width: '100%', + }, + nameSection: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + marginBottom: '10px', + }, + userName: { + margin: '0 5px 0 0', + fontSize: '1.8rem', + color: '#333', + }, + nameInput: { + fontSize: '1.8rem', + padding: '5px', + border: '1px solid #ccc', + borderRadius: '5px', + textAlign: 'center', + marginRight: '5px', + }, + editButton: { + background: 'none', + border: 'none', + cursor: 'pointer', + fontSize: '1.2rem', + marginLeft: '5px', + }, + emailText: { + fontSize: '1rem', + color: '#666', + margin: '5px 0', + }, + roleText: { + fontSize: '1.1rem', + color: '#333', + marginTop: '15px', + paddingTop: '10px', + borderTop: '1px solid #eee', + } +}; + +export default ProfilePage; \ No newline at end of file diff --git a/src/pages/Support.jsx b/src/pages/Support.jsx new file mode 100644 index 0000000..008b4c1 --- /dev/null +++ b/src/pages/Support.jsx @@ -0,0 +1,10 @@ +import React from "react"; + +export default function Support() { + return ( +
+

Suporte por telefone

+

Funcionalidade de chamada/suporte será implementada em breve.

+
+ ); +} diff --git a/src/pages/style/ProfilePage.css b/src/pages/style/ProfilePage.css new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/style/TrocardePerfil.css b/src/pages/style/TrocardePerfil.css deleted file mode 100644 index 3a253c2..0000000 --- a/src/pages/style/TrocardePerfil.css +++ /dev/null @@ -1,62 +0,0 @@ -.container-perfis { - position: absolute; - top: 80px; - left: 30px; - width: calc(100% - 60px); - display: flex; - flex-direction: column; - align-items: flex-start; - z-index: 60; -} - -.acesso-text { - font-size: 15px; - font-weight: 600; - color: #1e2b57; - margin-bottom: 6px; -} - -/* estilo visual refinado do select */ -.perfil-select { - width: 100%; - padding: 10px 14px; - border-radius: 10px; - border: 1.8px solid #d0d5dd; - background-color: #f9fafc; - color: #1e2b57; - font-weight: 600; - font-size: 14px; - outline: none; - cursor: pointer; - transition: all 0.2s ease; - box-shadow: 0 1px 3px rgba(30, 43, 87, 0.08); -} - -.perfil-select:hover { - border-color: #7a85ff; - background-color: #ffffff; - box-shadow: 0 2px 6px rgba(30, 43, 87, 0.1); -} - -.perfil-select:focus { - border-color: #5a46ff; - box-shadow: 0 0 0 3px rgba(90, 70, 255, 0.2); -} - -.perfil-select option[value=""] { - color: #777; - font-weight: 500; -} - -/* responsivo */ -@media (max-width: 780px) { - .container-perfis { - top: 60px; - left: 20px; - width: calc(100% - 40px); - } - .perfil-select { - font-size: 13px; - padding: 8px 12px; - } -} From 97840ebed4b913136b45cadbfc95eb0b60f953a0 Mon Sep 17 00:00:00 2001 From: Jessica_Faro Date: Sun, 12 Oct 2025 15:40:07 -0300 Subject: [PATCH 2/3] =?UTF-8?q?mudan=C3=A7as2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ProfilePage.jsx | 253 ++++++++++---------------------- src/pages/style/ProfilePage.css | 178 ++++++++++++++++++++++ 2 files changed, 255 insertions(+), 176 deletions(-) diff --git a/src/pages/ProfilePage.jsx b/src/pages/ProfilePage.jsx index ef09ef1..6d4f10b 100644 --- a/src/pages/ProfilePage.jsx +++ b/src/pages/ProfilePage.jsx @@ -1,206 +1,107 @@ // src/pages/ProfilePage.jsx -import React, { useState } from 'react'; -import { useLocation, useNavigate } from 'react-router-dom'; -// import { useAuth } from '../components/utils/AuthProvider'; // <-- NOVO: Se você puder importar isso. +import React, { useState } from "react"; +import { useLocation, useNavigate } from "react-router-dom"; +import "./style/ProfilePage.css"; -// --- SIMULAÇÃO DE DADOS DE USUÁRIO --- -// COMO NÃO PODEMOS IMPORTAR O useAuth SEM MEXER EM OUTROS ARQUIVOS, VAMOS USAR ESTA SIMULAÇÃO: const simulatedUserData = { - // ESTA SIMULAÇÃO DEVERIA SER SUBTITUÍDA PELO SEU CONTEXTO DE AUTENTICAÇÃO REAL. - // O EMAIL REALMENTE LOGADO VEM DO CONTEXTO DE AUTENTICAÇÃO (useAuth) - email: 'admin@squad23.com', - role: 'Administrador' // Vamos forçar um valor para fins de visualização + email: "admin@squad23.com", + role: "Administrador", }; const ProfilePage = () => { const location = useLocation(); const navigate = useNavigate(); - // const { user } = useAuth(); // Descomente esta linha e comente o bloco simulatedUserData se puder usar o useAuth! - // --- Lógica de Cargo (AGORA CORRIGIDA PARA PEGAR DA URL SE O CONTEXTO FALHAR) --- const getRoleFromPath = () => { const path = location.pathname; - if (path.includes('/admin')) return 'Administrador'; - if (path.includes('/secretaria')) return 'Secretária'; - if (path.includes('/medico')) return 'Médico'; - if (path.includes('/financeiro')) return 'Financeiro'; - return 'Usuário Padrão'; + if (path.includes("/admin")) return "Administrador"; + if (path.includes("/secretaria")) return "Secretária"; + if (path.includes("/medico")) return "Médico"; + if (path.includes("/financeiro")) return "Financeiro"; + return "Usuário Padrão"; }; - - // Use a simulação ou o dado real: - const userRole = simulatedUserData.role || getRoleFromPath(); - const userEmail = simulatedUserData.email || 'email.nao.encontrado@mediconnect.com'; - - // --- Estados do Componente --- - // Se o nome do usuário vier do contexto de autenticação, use-o aqui - const [userName, setUserName] = useState('Admin Padrão'); + const userRole = simulatedUserData.role || getRoleFromPath(); + const userEmail = simulatedUserData.email || "email.nao.encontrado@example.com"; + + const [userName, setUserName] = useState("Admin Padrão"); const [isEditingName, setIsEditingName] = useState(false); - // --- Funções de Interação --- - - const handleNameChange = (e) => { - if (e.key === 'Enter') { - setIsEditingName(false); - } + const handleNameKeyDown = (e) => { + if (e.key === "Enter") setIsEditingName(false); }; - const handleClose = () => { - navigate(-1); // Volta para a página anterior - }; + const handleClose = () => navigate(-1); return ( -
-
- - {/* Botão de Fechar (X) */} - - {/* 1. Área da Foto de Perfil (Quadrada) */} -
-
-
- -
- - {/* 2. Nome do Usuário com Edição */} -
- {isEditingName ? ( - setUserName(e.target.value)} - onBlur={() => setIsEditingName(false)} - onKeyPress={handleNameChange} - autoFocus - style={styles.nameInput} - /> - ) : ( -

{userName}

- )} - - +
+
+
+
+ +
- {/* 3. Email (AGORA EXIBE O VALOR SIMULADO/CORRIGIDO) */} -

Email: {userEmail}

+
+
+ {isEditingName ? ( + setUserName(e.target.value)} + onBlur={() => setIsEditingName(false)} + onKeyDown={handleNameKeyDown} + autoFocus + /> + ) : ( +

{userName}

+ )} - {/* 4. Cargo (AGORA EXIBE O VALOR SIMULADO/CORRIGIDO) */} -

Cargo: {userRole}

+ +
+ +

+ Email: {userEmail} +

+ +

+ Cargo: {userRole} +

+ +
+ +
+
); }; -// Estilos Atualizados para Aumentar o Tamanho do Modal -const styles = { - overlay: { - position: 'fixed', - top: 0, - left: 0, - right: 0, - bottom: 0, - backgroundColor: 'rgba(0, 0, 0, 0.5)', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - zIndex: 1100, - }, - modalContainer: { - position: 'relative', - padding: '50px 70px', // Aumentado o padding - backgroundColor: 'white', - borderRadius: '15px', - boxShadow: '0 8px 30px rgba(0, 0, 0, 0.3)', - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - minWidth: '400px', - width: '60%', // Aumentando a largura para cobrir mais a tela - maxWidth: '500px', // Limite máximo para não ficar gigante em telas grandes - height: 'auto', - }, - closeButton: { - position: 'absolute', - top: '15px', - right: '20px', - background: 'none', - border: 'none', - fontSize: '30px', - cursor: 'pointer', - color: '#666', - lineHeight: '1', - }, - // ... (Os estilos de profilePictureContainer, infoContainer, etc., permanecem iguais) - profilePictureContainer: { - width: '120px', - height: '120px', - borderRadius: '15px', - overflow: 'hidden', - boxShadow: '0 4px 10px rgba(0, 0, 0, 0.15)', - marginBottom: '20px', - }, - profilePicturePlaceholder: { - width: '100%', - height: '100%', - backgroundColor: '#A9A9A9', - backgroundImage: 'url(\'data:image/svg+xml;utf8,\')', - backgroundSize: '80%', - backgroundRepeat: 'no-repeat', - backgroundPosition: 'center', - }, - infoContainer: { - textAlign: 'center', - maxWidth: '400px', - width: '100%', - }, - nameSection: { - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - marginBottom: '10px', - }, - userName: { - margin: '0 5px 0 0', - fontSize: '1.8rem', - color: '#333', - }, - nameInput: { - fontSize: '1.8rem', - padding: '5px', - border: '1px solid #ccc', - borderRadius: '5px', - textAlign: 'center', - marginRight: '5px', - }, - editButton: { - background: 'none', - border: 'none', - cursor: 'pointer', - fontSize: '1.2rem', - marginLeft: '5px', - }, - emailText: { - fontSize: '1rem', - color: '#666', - margin: '5px 0', - }, - roleText: { - fontSize: '1.1rem', - color: '#333', - marginTop: '15px', - paddingTop: '10px', - borderTop: '1px solid #eee', - } -}; - -export default ProfilePage; \ No newline at end of file +export default ProfilePage; diff --git a/src/pages/style/ProfilePage.css b/src/pages/style/ProfilePage.css index e69de29..c9215aa 100644 --- a/src/pages/style/ProfilePage.css +++ b/src/pages/style/ProfilePage.css @@ -0,0 +1,178 @@ +/* src/pages/ProfilePage.css */ + +/* Overlay que cobre toda a tela */ +.profile-overlay { + position: fixed; + inset: 0; + background-color: rgba(0, 0, 0, 0.65); + display: flex; + align-items: center; + justify-content: center; + z-index: 20000; /* acima de header, vlibras, botões de acessibilidade */ + padding: 20px; + box-sizing: border-box; +} + +/* Card central (estilo modal amplo parecido com a 4ª foto) */ +.profile-modal { + background: #ffffff; + border-radius: 10px; + padding: 18px; + width: min(1100px, 96%); + max-width: 1100px; + box-shadow: 0 18px 60px rgba(0, 0, 0, 0.5); + position: relative; + box-sizing: border-box; + overflow: visible; +} + +/* Botão fechar (X) no canto do card */ +.profile-close { + position: absolute; + top: 14px; + right: 14px; + background: none; + border: none; + font-size: 26px; + color: #666; + cursor: pointer; + line-height: 1; +} + +/* Conteúdo dividido em 2 colunas: esquerda avatar / direita infos */ +.profile-content { + display: flex; + gap: 28px; + align-items: flex-start; + padding: 22px 18px; +} + +/* Coluna esquerda - avatar */ +.profile-left { + width: 220px; + display: flex; + justify-content: center; +} + +/* Avatar quadrado com sombra (estilo da foto 4) */ +.avatar-wrapper { + position: relative; + width: 180px; + height: 180px; +} + +.avatar-square { + width: 100%; + height: 100%; + border-radius: 8px; + background-color: #d0d0d0; + background-image: url("data:image/svg+xml;utf8,"); + background-position: center; + background-repeat: no-repeat; + background-size: 55%; + box-shadow: 0 8px 24px rgba(0,0,0,0.25); +} + +/* Botão editar sobre o avatar — círculo pequeno */ +.avatar-edit-btn { + position: absolute; + right: -8px; + bottom: -8px; + transform: translate(0, 0); + border: none; + background: #ffffff; + padding: 8px 9px; + border-radius: 50%; + box-shadow: 0 6px 14px rgba(0,0,0,0.18); + cursor: pointer; + font-size: 0.95rem; + line-height: 1; +} + +/* Coluna direita - informações */ +.profile-right { + flex: 1; + min-width: 280px; + display: flex; + flex-direction: column; + justify-content: center; +} + +/* Nome e botão de editar inline */ +.profile-name-row { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 10px; +} + +.profile-username { + margin: 0; + font-size: 1.9rem; + color: #222; +} + +.profile-edit-inline { + background: none; + border: none; + cursor: pointer; + font-size: 1.05rem; + color: #444; +} + +/* input de edição do nome */ +.profile-name-input { + font-size: 1.6rem; + padding: 6px 8px; + border: 1px solid #e0e0e0; + border-radius: 6px; +} + +/* email/role */ +.profile-email, +.profile-role { + margin: 6px 0; + color: #555; + font-size: 1rem; +} + +.profile-role { + margin-top: 14px; + padding-top: 12px; + border-top: 1px solid #f1f1f1; + color: #333; +} + +/* ações (apenas fechar aqui) */ +.profile-actions-row { + display: flex; + gap: 12px; + margin-top: 18px; +} + +/* botões */ +.btn { + padding: 8px 14px; + border-radius: 8px; + border: 1px solid transparent; + cursor: pointer; + font-size: 0.95rem; +} + +.btn-close { + background: #f0f0f0; + color: #222; + border: 1px solid #e6e6e6; +} + +/* responsividade */ +@media (max-width: 880px) { + .profile-content { + flex-direction: column; + gap: 14px; + align-items: center; + } + .profile-left { width: 100%; } + .avatar-wrapper { width: 140px; height: 140px; } + .profile-right { width: 100%; text-align: center; } +} From 7f14cf16b7722e45ea7a1a9108cec6daed24ac0e Mon Sep 17 00:00:00 2001 From: Jessica_Faro Date: Wed, 15 Oct 2025 20:14:03 -0300 Subject: [PATCH 3/3] tiptap --- package-lock.json | 746 ++++++++++++++++++++- package.json | 3 + src/PagesMedico/DoctorRelatorioManager.jsx | 59 +- src/PagesMedico/EditPageRelatorio.jsx | 183 +++-- src/PagesMedico/TiptapEditor.jsx | 74 ++ src/PagesMedico/TiptapViewer.jsx | 15 + 6 files changed, 1003 insertions(+), 77 deletions(-) create mode 100644 src/PagesMedico/TiptapEditor.jsx create mode 100644 src/PagesMedico/TiptapViewer.jsx diff --git a/package-lock.json b/package-lock.json index 068a8fa..26a38b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,9 @@ "@testing-library/jest-dom": "^6.8.0", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^13.5.0", + "@tiptap/extension-placeholder": "^3.7.1", + "@tiptap/react": "^3.7.1", + "@tiptap/starter-kit": "^3.7.1", "apexcharts": "^5.3.4", "bootstrap": "^5.3.8", "bootstrap-icons": "^1.13.1", @@ -16184,6 +16187,31 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "optional": true, + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "optional": true, + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "optional": true + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", @@ -17174,6 +17202,11 @@ "url": "https://opencollective.com/immer" } }, + "node_modules/@remirror/core-constants": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", + "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==" + }, "node_modules/@restart/hooks": { "version": "0.4.16", "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", @@ -17747,6 +17780,424 @@ "@testing-library/dom": ">=7.21.4" } }, + "node_modules/@tiptap/core": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.7.1.tgz", + "integrity": "sha512-jB6R8EGI34QUmV7EhtE+JVpjbZ6Wa0dcf0LNS36X9V7FtDQcnxl7ekRs/ftELt/6qOjubRdyhaID0wNdJVmFtw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/pm": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-blockquote": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.7.1.tgz", + "integrity": "sha512-UPIne4kD8hwhadPtapn0WfJCNiF+b3ftNYiC1BpNfti5NmM0sXuqOOC0WnVgGgsNuJp4hd+4PMp42InlD6/1aw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-bold": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.7.1.tgz", + "integrity": "sha512-XZRt1blYGpqVlcBo+PKH1mlbsqdc5KsWi/ZsPBV3Ajg/Vx5d6SAY4wK6CW1SpotE1wWucUhfAmXddhBFvYzaUA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-bubble-menu": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.7.1.tgz", + "integrity": "sha512-7qLK49GC7pW6FbAE6vOGphcyjq7CqiBEwr9i9/5UgnadjLtREDzBl28D+95+8TkyF7sM3hP6s6RU+nh87v5fqw==", + "optional": true, + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1", + "@tiptap/pm": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-bullet-list": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.7.1.tgz", + "integrity": "sha512-AO7EVAftvzSw7Sftp36P+HNedxjygMpobYNTBQzHfGljRZh8VDhIUzwyP1OsmlrcCbBxsrjMZLrmk/ozsALq0g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-code": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.7.1.tgz", + "integrity": "sha512-ZRarYvgQ16ZrzKox/iW3bVr5IVNBsD0yjU5S7GVmlRgRQ8lhsTloLk9Gu05uuZ6dOoL3qApLA8+W7w8sxZJ35w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-code-block": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.7.1.tgz", + "integrity": "sha512-/Ov81QXEn6AOiiSUFlM57a+YSye/Lkhvgy303+CEGtDuFVU/SJ0tDsgmSYzkP5q6DIVQLAXp5WkxEo02GnYHgQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1", + "@tiptap/pm": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-document": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.7.1.tgz", + "integrity": "sha512-b7NHWseJSvhhbsiSWjQgiJcs6FUJiEJocfhazDiWAOk5ELQ6+oiIe7ecEgDqBmafk9oziV9r7u9OAgyeyP3JBA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-dropcursor": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.7.1.tgz", + "integrity": "sha512-wZT3bPeNJAasOvNr6tUZAwXFeKlQEToSnVAjFiBzJwLDonuK8ZaAiBCDQgqEQSlP3HsEE4/qkERBNrdyAT26CQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extensions": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-floating-menu": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.7.1.tgz", + "integrity": "sha512-epfA87IIBy5IREMjmlRskp8T/9/avjfM8RtcqDnKQxVVXn8yl5i0Pca0jXD4w7rIAS7G95N9sYRxsou6Y6fTQg==", + "optional": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@floating-ui/dom": "^1.0.0", + "@tiptap/core": "^3.7.1", + "@tiptap/pm": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-gapcursor": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.7.1.tgz", + "integrity": "sha512-1UrZEaqruWPLdgYsAm4au7BAyTDjaNRP0E7UIoEoGsq+MAS2MM3g4suXMzu+l3ZIayrSy98N3T8DIUG+U6+mww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extensions": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-hard-break": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.7.1.tgz", + "integrity": "sha512-pEvRjWexMNxXH5FOy3EhzyMFDFHrRTWOgZbWAxliKDg2dFEJ50e9KcCMDs87e7++V753lEKnFTmz/9WaH7cwcQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-heading": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.7.1.tgz", + "integrity": "sha512-rOUou6b0+5E+DAmEMTC/mlKTLiOr4D0LKzBfqBLQ3zUyZPZabOKzN0L+4MaLNR2CkXy/Ae4du5ucHGrGOWzVrQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-horizontal-rule": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.7.1.tgz", + "integrity": "sha512-f4lXW/LHuJBF11PIrWdNAzTmlapV4fVujJ5eCsLAkpzhx3izVrDW/WlKRrkGUCy/qQT4v7BbHNa5JYlKDzDo0Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1", + "@tiptap/pm": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-italic": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.7.1.tgz", + "integrity": "sha512-Bm6eOtcafc5kjE357GlvIY2hNTRRAkb8D5SRm8zYlVB0fiLto+r15Ht+DTOmLiQKEGtEArQ/C8Rh2j09UdH2vA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-link": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.7.1.tgz", + "integrity": "sha512-6+0/mo+EKDiA1d1pDZSsf/51ZOwdFnN35yF/4celxdr/JL4aupvtttIjGAtWd37h50cadYSL4F1uacKs7yyh8Q==", + "dependencies": { + "linkifyjs": "^4.3.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1", + "@tiptap/pm": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-list": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.7.1.tgz", + "integrity": "sha512-E93oXkV2vsZThsix0OA7RiHNLIMGi+w9ASKZ+8TGB69oy32yujnnZz6YVhTVVDPOw8rCP5CnOPhJbgdcqByr0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1", + "@tiptap/pm": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-list-item": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.7.1.tgz", + "integrity": "sha512-qkXfWRBusJCId9VhRo9vihcrmxvJ83fkzYWI0LiefJCT1LKfMaeInFNxIsFeUU4q9nR0mhZo7ES3E2+Tk0U3Mw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-list-keymap": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.7.1.tgz", + "integrity": "sha512-3WyzWge/g6FoxMTkoAARtMJyIYQbpclNX48HyAqdwjJXuLmz3qckEnJEXo47CvJlRsNAlcDJniRS9j5SVJupRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-ordered-list": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.7.1.tgz", + "integrity": "sha512-iX3DhTwFp84fiCNSF7+kl/sq6orXq2QFcV2AH+CvL+d0WW1STYmmVmE26gHEjyY82QfpvLZYUCEG6RSYpxFIZw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-paragraph": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.7.1.tgz", + "integrity": "sha512-L5dsppKKo46MN3Go5vzqqzjPX89pz1lIkIUN3IhU+KmAHg1TklfR7FQkiIFIIV2rb2ZLuLpD/JcNsZAUmJTW5Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-placeholder": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-3.7.1.tgz", + "integrity": "sha512-35VZ578c9oho62Cpupzo9rZCxhPNtuLHNnpKy7bXYaR0Quy3/axtnly1x09nS/KZ4oqw8rvYtkS6GAXwMKKtLg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extensions": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-strike": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.7.1.tgz", + "integrity": "sha512-Ctqk/SfmGd3hFCDr4/OH0Dnja19UWUrUEY62pwM7JCkbY/Y9QwPLSO32L6KyamwUDek9SL/ATjRPz6GLp0P7hg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-text": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.7.1.tgz", + "integrity": "sha512-m+8FJrFAllJYuzLbEXJ9AztobxmWBTjWorkHcMHBLAbY2ytmAhIM1u3ExtOn9DjvnIT6MffCaq0i/KjhSBYJlA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extension-underline": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.7.1.tgz", + "integrity": "sha512-tyx7ZM2ll8DclKe9Ea/vPyqaZBgnJfIbKBOpecpzawDaJ5ocjwywmYNduevOhw327X2/i8LIQBsPuIOJselcUQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1" + } + }, + "node_modules/@tiptap/extensions": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.7.1.tgz", + "integrity": "sha512-O7eq3frqh7kn/J2P+lpx8blBQrIQxt21J3NvlQJhW5nXIECdo2ox8SQcEfli0EqMSwZCZTdVufdFBkWfIRXhRg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1", + "@tiptap/pm": "^3.7.1" + } + }, + "node_modules/@tiptap/pm": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.7.1.tgz", + "integrity": "sha512-t3n054kplRtRYn8pDnzF/prDUccF7QX7jPYLsYBpLn3+d59J5KKkBmOpPExUGE8kZkNoLfwffAFj6NBfqOu+Xg==", + "dependencies": { + "prosemirror-changeset": "^2.3.0", + "prosemirror-collab": "^1.3.1", + "prosemirror-commands": "^1.6.2", + "prosemirror-dropcursor": "^1.8.1", + "prosemirror-gapcursor": "^1.3.2", + "prosemirror-history": "^1.4.1", + "prosemirror-inputrules": "^1.4.0", + "prosemirror-keymap": "^1.2.2", + "prosemirror-markdown": "^1.13.1", + "prosemirror-menu": "^1.2.4", + "prosemirror-model": "^1.24.1", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.5.0", + "prosemirror-state": "^1.4.3", + "prosemirror-tables": "^1.6.4", + "prosemirror-trailing-node": "^3.0.0", + "prosemirror-transform": "^1.10.2", + "prosemirror-view": "^1.38.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, + "node_modules/@tiptap/react": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.7.1.tgz", + "integrity": "sha512-0tDih8ACrVhKCpNjHcQhxV5DBsyY4xpAjr8nfb2RK+J2l1lGtNuj3PDRHlDLroQiK8svwARz4hsBs8MYWKSkfg==", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "fast-deep-equal": "^3.1.3", + "use-sync-external-store": "^1.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "optionalDependencies": { + "@tiptap/extension-bubble-menu": "^3.7.1", + "@tiptap/extension-floating-menu": "^3.7.1" + }, + "peerDependencies": { + "@tiptap/core": "^3.7.1", + "@tiptap/pm": "^3.7.1", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "@types/react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tiptap/starter-kit": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.7.1.tgz", + "integrity": "sha512-ZYgA3BkASQmHyoDlUYKFPEpCzIcn/FP/Sb+Ic2L7gt2gOC7zvWAVc/2yIbiFuq+48s+5U/KJqDiXn2hiLwXxpA==", + "dependencies": { + "@tiptap/core": "^3.7.1", + "@tiptap/extension-blockquote": "^3.7.1", + "@tiptap/extension-bold": "^3.7.1", + "@tiptap/extension-bullet-list": "^3.7.1", + "@tiptap/extension-code": "^3.7.1", + "@tiptap/extension-code-block": "^3.7.1", + "@tiptap/extension-document": "^3.7.1", + "@tiptap/extension-dropcursor": "^3.7.1", + "@tiptap/extension-gapcursor": "^3.7.1", + "@tiptap/extension-hard-break": "^3.7.1", + "@tiptap/extension-heading": "^3.7.1", + "@tiptap/extension-horizontal-rule": "^3.7.1", + "@tiptap/extension-italic": "^3.7.1", + "@tiptap/extension-link": "^3.7.1", + "@tiptap/extension-list": "^3.7.1", + "@tiptap/extension-list-item": "^3.7.1", + "@tiptap/extension-list-keymap": "^3.7.1", + "@tiptap/extension-ordered-list": "^3.7.1", + "@tiptap/extension-paragraph": "^3.7.1", + "@tiptap/extension-strike": "^3.7.1", + "@tiptap/extension-text": "^3.7.1", + "@tiptap/extension-underline": "^3.7.1", + "@tiptap/extensions": "^3.7.1", + "@tiptap/pm": "^3.7.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -18078,6 +18529,20 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "license": "MIT" }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -18088,6 +18553,11 @@ "@types/unist": "*" } }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==" + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -18184,14 +18654,22 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "19.1.12", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz", - "integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==", - "license": "MIT", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "dependencies": { "csstype": "^3.0.2" } }, + "node_modules/@types/react-dom": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", + "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", + "peer": true, + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, "node_modules/@types/react-transition-group": { "version": "4.4.12", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", @@ -21060,6 +21538,11 @@ "node": ">=10" } }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -26850,6 +27333,19 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/linkifyjs": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.2.tgz", + "integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==" + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -27041,6 +27537,38 @@ "tmpl": "1.0.5" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/markdown-table": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", @@ -27329,6 +27857,11 @@ "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", "license": "CC0-1.0" }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -28526,6 +29059,11 @@ "node": ">= 0.8.0" } }, + "node_modules/orderedmap": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", + "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==" + }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -30322,6 +30860,183 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/prosemirror-changeset": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.1.tgz", + "integrity": "sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==", + "dependencies": { + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-collab": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", + "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "dependencies": { + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-commands": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz", + "integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.10.2" + } + }, + "node_modules/prosemirror-dropcursor": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz", + "integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0", + "prosemirror-view": "^1.1.0" + } + }, + "node_modules/prosemirror-gapcursor": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.0.tgz", + "integrity": "sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==", + "dependencies": { + "prosemirror-keymap": "^1.0.0", + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-view": "^1.0.0" + } + }, + "node_modules/prosemirror-history": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz", + "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==", + "dependencies": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.31.0", + "rope-sequence": "^1.3.0" + } + }, + "node_modules/prosemirror-inputrules": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.1.tgz", + "integrity": "sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-keymap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz", + "integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==", + "dependencies": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "node_modules/prosemirror-markdown": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.2.tgz", + "integrity": "sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==", + "dependencies": { + "@types/markdown-it": "^14.0.0", + "markdown-it": "^14.0.0", + "prosemirror-model": "^1.25.0" + } + }, + "node_modules/prosemirror-menu": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.5.tgz", + "integrity": "sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==", + "dependencies": { + "crelt": "^1.0.0", + "prosemirror-commands": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-model": { + "version": "1.25.3", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.3.tgz", + "integrity": "sha512-dY2HdaNXlARknJbrManZ1WyUtos+AP97AmvqdOQtWtrrC5g4mohVX5DTi9rXNFSk09eczLq9GuNTtq3EfMeMGA==", + "dependencies": { + "orderedmap": "^2.0.0" + } + }, + "node_modules/prosemirror-schema-basic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz", + "integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==", + "dependencies": { + "prosemirror-model": "^1.25.0" + } + }, + "node_modules/prosemirror-schema-list": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz", + "integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.7.3" + } + }, + "node_modules/prosemirror-state": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", + "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.27.0" + } + }, + "node_modules/prosemirror-tables": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.1.tgz", + "integrity": "sha512-DAgDoUYHCcc6tOGpLVPSU1k84kCUWTWnfWX3UDy2Delv4ryH0KqTD6RBI6k4yi9j9I8gl3j8MkPpRD/vWPZbug==", + "dependencies": { + "prosemirror-keymap": "^1.2.2", + "prosemirror-model": "^1.25.0", + "prosemirror-state": "^1.4.3", + "prosemirror-transform": "^1.10.3", + "prosemirror-view": "^1.39.1" + } + }, + "node_modules/prosemirror-trailing-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", + "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", + "dependencies": { + "@remirror/core-constants": "3.0.0", + "escape-string-regexp": "^4.0.0" + }, + "peerDependencies": { + "prosemirror-model": "^1.22.1", + "prosemirror-state": "^1.4.2", + "prosemirror-view": "^1.33.8" + } + }, + "node_modules/prosemirror-transform": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.4.tgz", + "integrity": "sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==", + "dependencies": { + "prosemirror-model": "^1.21.0" + } + }, + "node_modules/prosemirror-view": { + "version": "1.41.3", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.3.tgz", + "integrity": "sha512-SqMiYMUQNNBP9kfPhLO8WXEk/fon47vc52FQsUiJzTBuyjKgEcoAwMyF04eQ4WZ2ArMn7+ReypYL60aKngbACQ==", + "dependencies": { + "prosemirror-model": "^1.20.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -30365,6 +31080,14 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "engines": { + "node": ">=6" + } + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -31707,6 +32430,11 @@ "randombytes": "^2.1.0" } }, + "node_modules/rope-sequence": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -33802,6 +34530,11 @@ "node": ">=4.2.0" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -34250,6 +34983,11 @@ "browser-process-hrtime": "^1.0.0" } }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" + }, "node_modules/w3c-xmlserializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", diff --git a/package.json b/package.json index 8f30168..728f80b 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,9 @@ "@testing-library/jest-dom": "^6.8.0", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^13.5.0", + "@tiptap/extension-placeholder": "^3.7.1", + "@tiptap/react": "^3.7.1", + "@tiptap/starter-kit": "^3.7.1", "apexcharts": "^5.3.4", "bootstrap": "^5.3.8", "bootstrap-icons": "^1.13.1", diff --git a/src/PagesMedico/DoctorRelatorioManager.jsx b/src/PagesMedico/DoctorRelatorioManager.jsx index ce24602..22a79b2 100644 --- a/src/PagesMedico/DoctorRelatorioManager.jsx +++ b/src/PagesMedico/DoctorRelatorioManager.jsx @@ -5,6 +5,8 @@ import { useAuth } from '../components/utils/AuthProvider'; import { GetPatientByID } from '../components/utils/Functions-Endpoints/Patient'; import { useNavigate } from 'react-router-dom'; import html2pdf from 'html2pdf.js'; +import TiptapViewer from './TiptapViewer'; + const DoctorRelatorioManager = () => { const navigate = useNavigate() const {getAuthorizationHeader} = useAuth(); @@ -13,7 +15,7 @@ const DoctorRelatorioManager = () => { const [PacientesComRelatorios, setPacientesComRelatorios] = useState([]) const [showModal, setShowModal] = useState(false) const [index, setIndex] = useState() - + // 1º useEffect: Busca os dados dos pacientes após carregar os relatórios useEffect( () => { let pacientesDosRelatorios = [] @@ -26,34 +28,32 @@ const DoctorRelatorioManager = () => { if (paciente.length > 0) { pacientesDosRelatorios.push(paciente[0]); } - } setPacientesComRelatorios(pacientesDosRelatorios); - } - ListarPacientes() - console.log(PacientesComRelatorios, 'aqui') - - }, [RelatoriosFiltrados]); - + + }, [RelatoriosFiltrados, authHeader]); + // NOVO: useEffect para logar PacientesComRelatorios após a atualização + useEffect(() => { + console.log(PacientesComRelatorios, 'aqui') + }, [PacientesComRelatorios]) + + // 2º useEffect: Busca a lista de relatórios useEffect(() => { var myHeaders = new Headers(); myHeaders.append("apikey", API_KEY); myHeaders.append("Authorization", authHeader); - var requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' }; - fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?patient_id&status", requestOptions) .then(response => response.json()) .then(data => { setRelatorios(data); console.log(data) }) .catch(error => console.log('error', error)); - }, []) - + }, [authHeader]) const BaixarPDFdoRelatorio = (nome_paciente) => { const elemento = document.getElementById("folhaA4"); // tua div do relatório const opt = { @@ -62,10 +62,8 @@ fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?patient_id&statu html2canvas: { scale: 2 }, jsPDF: { unit: "mm", format: "a4", orientation: "portrait" }, }; - html2pdf().set(opt).from(elemento).save(); } - return (
{showModal && ( @@ -82,36 +80,36 @@ fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?patient_id&statu
-

Clinica Rise up

Dr - CRM/SP 123456

Avenida - (79) 9 4444-4444

-

Paciente: {PacientesComRelatorios[index]?.full_name}

Data de nascimento: {PacientesComRelatorios[index]?.birth_date}

-

Data do exame: {}

-

Exame: {RelatoriosFiltrados[index]?.exam}

- -

Diagnostico: {RelatoriosFiltrados[index]?.diagnosis}

-

Conclusão: {RelatoriosFiltrados[index]?.conclusion}

+ {/* INÍCIO DA MUDANÇA (da resposta anterior) */} +

Conteúdo do Relatório:

+ + {/* FIM DA MUDANÇA */}
-

Dr {RelatoriosFiltrados[index]?.required_by}

Emitido em: 0

-
- -
)} - -

Lista de Relatórios

@@ -143,14 +139,12 @@ fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?patient_id&statu
-
{" "} Filtros
-
-
@@ -178,7 +171,6 @@ fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?patient_id&statu - @@ -210,7 +202,6 @@ fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?patient_id&statu Ver Detalhes - + ) } diff --git a/src/PagesMedico/TiptapEditor.jsx b/src/PagesMedico/TiptapEditor.jsx new file mode 100644 index 0000000..7194562 --- /dev/null +++ b/src/PagesMedico/TiptapEditor.jsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { useEditor, EditorContent } from '@tiptap/react'; +import StarterKit from '@tiptap/starter-kit'; +import Link from '@tiptap/extension-link'; +// Componente da barra de menu (Menu Bar) +const MenuBar = ({ editor }) => { + if (!editor) { + return null; + } + // Estilos simples para os botões. Você pode e deve estilizar melhor com CSS/Bootstrap. + const buttonStyle = { + marginRight: '4px', + padding: '4px 8px', + cursor: 'pointer', + border: '1px solid #ccc', + borderRadius: '4px', + backgroundColor: editor.isActive('bold') || editor.isActive('italic') ? '#ddd' : 'white', + }; + return ( +
+ + + + + {/* Adicione mais botões conforme a necessidade (link, código, etc.) */} +
+ ); +}; +// Componente principal do Editor +const TiptapEditor = ({ content, onChange }) => { + const editor = useEditor({ + extensions: [ + StarterKit.configure({ + // Desativa 'hardBreak' e 'blockquote' se não forem necessários para simplificar + hardBreak: false, + }), + Link, // Adiciona suporte para links + ], + content: content || '

Inicie o relatório aqui...

', + onUpdate: ({ editor }) => { + // Quando o conteúdo muda, chama a função onChange com o HTML + onChange(editor.getHTML()); + }, + }); + return ( +
+ + +
+ ); +}; +export default TiptapEditor; \ No newline at end of file diff --git a/src/PagesMedico/TiptapViewer.jsx b/src/PagesMedico/TiptapViewer.jsx new file mode 100644 index 0000000..cf21c49 --- /dev/null +++ b/src/PagesMedico/TiptapViewer.jsx @@ -0,0 +1,15 @@ +import React from 'react'; + +// Componente para renderizar o HTML salvo (conteúdo do editor) +const TiptapViewer = ({ htmlContent }) => { + return ( + // 'dangerouslySetInnerHTML' é necessário para renderizar HTML +
+ ); +}; + +export default TiptapViewer; \ No newline at end of file
Paciente CPFExame