forked from RiseUP/riseup-squad23
Merge branch 'perfillogin' of https://git.popcode.com.br/RiseUP/riseup-squad23
This commit is contained in:
commit
a01c62440e
@ -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() {
|
||||
<Router>
|
||||
<VlibrasWidget />
|
||||
<BotaoAcessibilidade />
|
||||
<Header />
|
||||
|
||||
<Routes>
|
||||
<Route path="/" element={<LandingPage />} />
|
||||
@ -30,6 +33,7 @@ function App() {
|
||||
<Route path="/financeiro/*" element={<PerfilFinanceiro />} />
|
||||
<Route path="/medico/*" element={<PerfilMedico />} />
|
||||
<Route path="/admin/*" element={<Perfiladm />} />
|
||||
<Route path="/perfil" element={<ProfilePage />} />
|
||||
<Route path="*" element={<h2>Página não encontrada</h2>} />
|
||||
</Routes>
|
||||
</Router>
|
||||
@ -37,4 +41,3 @@ function App() {
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
|
||||
107
src/components/Header/Header.css
Normal file
107
src/components/Header/Header.css
Normal file
@ -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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="%23FFFFFF" d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm-45.7 48C79.8 304 0 383.8 0 482.3c0 16.7 13.5 30.2 30.2 30.2h387.6c16.7 0 30.2-13.5 30.2-30.2 0-98.5-79.8-178.3-178.3-178.3h-45.7z"/></svg>');
|
||||
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;
|
||||
}
|
||||
60
src/components/Header/Header.jsx
Normal file
60
src/components/Header/Header.jsx
Normal file
@ -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 (
|
||||
<div className="header-container">
|
||||
<div className="right-corner-elements">
|
||||
|
||||
{/* Ícone de Telefone */}
|
||||
<div className="phone-icon-container" onClick={handleSupportClick}>
|
||||
<span className="phone-icon" role="img" aria-label="telefone">📞</span>
|
||||
</div>
|
||||
|
||||
{/* Seção de Perfil com Dropdown */}
|
||||
<div className="profile-section">
|
||||
<div className="profile-picture-container" onClick={handleProfileClick}>
|
||||
{/* O div "profile-placeholder" simula a foto de perfil circular colorida */}
|
||||
<div className="profile-placeholder"></div>
|
||||
</div>
|
||||
|
||||
{isDropdownOpen && (
|
||||
<div className="profile-dropdown">
|
||||
<button onClick={handleViewProfile} className="dropdown-button">Ver Perfil</button>
|
||||
<button onClick={handleLogout} className="dropdown-button logout-button">Sair (Logout)</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
206
src/pages/ProfilePage.jsx
Normal file
206
src/pages/ProfilePage.jsx
Normal file
@ -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 (
|
||||
<div style={styles.overlay}>
|
||||
<div style={styles.modalContainer}>
|
||||
|
||||
{/* Botão de Fechar (X) */}
|
||||
<button onClick={handleClose} style={styles.closeButton} aria-label="Fechar Perfil">
|
||||
×
|
||||
</button>
|
||||
|
||||
{/* 1. Área da Foto de Perfil (Quadrada) */}
|
||||
<div style={styles.profilePictureContainer}>
|
||||
<div style={styles.profilePicturePlaceholder}></div>
|
||||
</div>
|
||||
|
||||
<div style={styles.infoContainer}>
|
||||
|
||||
{/* 2. Nome do Usuário com Edição */}
|
||||
<div style={styles.nameSection}>
|
||||
{isEditingName ? (
|
||||
<input
|
||||
type="text"
|
||||
value={userName}
|
||||
onChange={(e) => setUserName(e.target.value)}
|
||||
onBlur={() => setIsEditingName(false)}
|
||||
onKeyPress={handleNameChange}
|
||||
autoFocus
|
||||
style={styles.nameInput}
|
||||
/>
|
||||
) : (
|
||||
<h2 style={styles.userName}>{userName}</h2>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={() => setIsEditingName(!isEditingName)}
|
||||
style={styles.editButton}
|
||||
aria-label="Editar Nome"
|
||||
>
|
||||
<span role="img" aria-label="lapis">✏️</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 3. Email (AGORA EXIBE O VALOR SIMULADO/CORRIGIDO) */}
|
||||
<p style={styles.emailText}>Email: <strong>{userEmail}</strong></p>
|
||||
|
||||
{/* 4. Cargo (AGORA EXIBE O VALOR SIMULADO/CORRIGIDO) */}
|
||||
<p style={styles.roleText}>Cargo: <strong>{userRole}</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="%23FFFFFF" d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm-45.7 48C79.8 304 0 383.8 0 482.3c0 16.7 13.5 30.2 30.2 30.2h387.6c16.7 0 30.2-13.5 30.2-30.2 0-98.5-79.8-178.3-178.3-178.3h-45.7z"/></svg>\')',
|
||||
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;
|
||||
10
src/pages/Support.jsx
Normal file
10
src/pages/Support.jsx
Normal file
@ -0,0 +1,10 @@
|
||||
import React from "react";
|
||||
|
||||
export default function Support() {
|
||||
return (
|
||||
<div style={{padding:40}}>
|
||||
<h3>Suporte por telefone</h3>
|
||||
<p>Funcionalidade de chamada/suporte será implementada em breve.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
0
src/pages/style/ProfilePage.css
Normal file
0
src/pages/style/ProfilePage.css
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user