implementacao do sistema de logout com modal e API

This commit is contained in:
Caio Miguel Lima Nunes 2025-10-07 22:22:18 -03:00
parent fe455a256a
commit efa723dbe3

View File

@ -1,13 +1,13 @@
import React, { useState } from "react";
import { Link } from "react-router-dom";
import menuItems from "../data/sidebar-items-medico.json"; // Use "sidebar-items-secretaria.json" para secretaria e "sidebar-items-adm.json" para ADM
import { Link, useNavigate } from "react-router-dom";
import menuItems from "../data/sidebar-items-medico.json";
import TrocardePerfis from "./TrocardePerfis";
// 1. Recebe 'menuItems' e 'onLogout' como props
function Sidebar({ menuItems, onLogout }) {
function Sidebar({ menuItems }) {
const [isActive, setIsActive] = useState(true);
const [openSubmenu, setOpenSubmenu] = useState(null);
const [showLogoutModal, setShowLogoutModal] = useState(false);
const navigate = useNavigate();
const toggleSidebar = () => {
setIsActive(!isActive);
@ -17,8 +17,87 @@ function Sidebar({ menuItems, onLogout }) {
setOpenSubmenu(openSubmenu === submenuName ? null : submenuName);
};
const handleLogoutClick = () => {
setShowLogoutModal(true);
};
const handleLogoutConfirm = async () => {
try {
const token = localStorage.getItem('token') ||
localStorage.getItem('authToken') ||
localStorage.getItem('userToken') ||
localStorage.getItem('access_token') ||
sessionStorage.getItem('token') ||
sessionStorage.getItem('authToken');
if (token) {
const response = await fetch('https://mock.apidog.com/m1/1053378-0-default/auth/v1/logout', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
});
if (response.status === 204) {
console.log('Logout realizado com sucesso');
} else if (response.status === 401) {
console.log('Token inválido ou expirado');
} else {
try {
const errorData = await response.json();
console.error('Erro no logout:', errorData);
} catch {
console.error('Erro no logout - status:', response.status);
}
}
}
clearAuthData();
navigate('/login');
} catch (error) {
console.error('Erro durante logout:', error);
clearAuthData();
navigate('/login');
} finally {
setShowLogoutModal(false);
}
};
const clearAuthData = () => {
localStorage.removeItem('token');
localStorage.removeItem('authToken');
localStorage.removeItem('userToken');
localStorage.removeItem('access_token');
localStorage.removeItem('user');
localStorage.removeItem('auth');
localStorage.removeItem('userData');
sessionStorage.removeItem('token');
sessionStorage.removeItem('authToken');
sessionStorage.removeItem('userToken');
sessionStorage.removeItem('access_token');
sessionStorage.removeItem('user');
sessionStorage.removeItem('auth');
sessionStorage.removeItem('userData');
if (window.caches) {
caches.keys().then(names => {
names.forEach(name => {
if (name.includes('auth') || name.includes('api')) {
caches.delete(name);
}
});
});
}
};
const handleLogoutCancel = () => {
setShowLogoutModal(false);
};
const renderLink = (item) => {
// Links internos (rotas do React Router)
if (item.url && item.url.startsWith("/")) {
return (
<Link to={item.url} className="sidebar-link">
@ -28,7 +107,6 @@ function Sidebar({ menuItems, onLogout }) {
);
}
// Links externos
return (
<a
href={item.url}
@ -43,10 +121,64 @@ function Sidebar({ menuItems, onLogout }) {
};
return (
<>
{showLogoutModal && (
<div className="modal-overlay" style={{
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
zIndex: 9999
}}>
<div className="modal-content" style={{
backgroundColor: 'white',
padding: '2rem',
borderRadius: '8px',
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
maxWidth: '400px',
width: '90%'
}}>
<h3 style={{ marginBottom: '1rem' }}>Confirmar Logout</h3>
<p style={{ marginBottom: '2rem' }}>Tem certeza que deseja encerrar a sessão?</p>
<div style={{ display: 'flex', gap: '1rem', justifyContent: 'flex-end' }}>
<button
onClick={handleLogoutCancel}
style={{
padding: '0.5rem 1rem',
border: '1px solid #ccc',
borderRadius: '4px',
backgroundColor: 'transparent',
cursor: 'pointer'
}}
>
Cancelar
</button>
<button
onClick={handleLogoutConfirm}
style={{
padding: '0.5rem 1rem',
border: 'none',
borderRadius: '4px',
backgroundColor: '#dc3545',
color: 'white',
cursor: 'pointer'
}}
>
Sair
</button>
</div>
</div>
</div>
)}
<div id="sidebar" className={isActive ? "active" : ""}>
<div className="sidebar-wrapper active">
<div className="sidebar-header">
{/* ... Header... */}
<div className="d-flex justify-content-between">
<div className="logo">
<Link to="/">
@ -80,11 +212,9 @@ function Sidebar({ menuItems, onLogout }) {
return (
<li
key={index}
className={`sidebar-item has-sub ${
openSubmenu === item.key ? "active" : ""
className={`sidebar-item has-sub ${openSubmenu === item.key ? "active" : ""
}`}
>
{/* ... Lógica de Submenu ... */}
<button
type="button"
className="sidebar-link btn"
@ -94,8 +224,7 @@ function Sidebar({ menuItems, onLogout }) {
<span>{item.name}</span>
</button>
<ul
className={`submenu ${
openSubmenu === item.key ? "active" : ""
className={`submenu ${openSubmenu === item.key ? "active" : ""
}`}
>
{item.submenu.map((subItem, subIndex) => (
@ -114,16 +243,19 @@ function Sidebar({ menuItems, onLogout }) {
</li>
);
})}
{/* 3. Adiciona o botão de logout no final do menu */}
<li className="sidebar-item" onClick={onLogout}>
<button type="button" className="sidebar-link btn">
<li className="sidebar-item">
<button
type="button"
className="sidebar-link btn"
onClick={handleLogoutClick}
>
<i className="bi bi-box-arrow-right"></i>
<span>Sair (Logout)</span>
</button>
</li>
<TrocardePerfis />
</ul>
</div>
@ -132,6 +264,7 @@ function Sidebar({ menuItems, onLogout }) {
</button>
</div>
</div>
</>
);
}