Files
Arkendro/webui/src/common/components/ProfileMenu/ProfileMenu.jsx

93 lines
3.1 KiB
JavaScript

import React, {useState, useRef, useEffect, useContext} from 'react';
import {SignOutIcon, CaretDownIcon, UserIcon} from '@phosphor-icons/react';
import {UserContext} from '@/common/contexts/UserContext.jsx';
import './styles.sass';
export const ProfileMenu = () => {
const {logout, user} = useContext(UserContext);
const [isOpen, setIsOpen] = useState(false);
const menuRef = useRef(null);
useEffect(() => {
const handleClickOutside = (event) => {
if (menuRef.current && !menuRef.current.contains(event.target)) {
setIsOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
useEffect(() => {
const handleEscapeKey = (event) => {
if (event.key === 'Escape') {
setIsOpen(false);
}
};
if (isOpen) {
document.addEventListener('keydown', handleEscapeKey);
return () => {
document.removeEventListener('keydown', handleEscapeKey);
};
}
}, [isOpen]);
const handleLogout = () => {
setIsOpen(false);
logout();
};
const toggleMenu = () => {
setIsOpen(!isOpen);
};
return (
<div className="profile-menu" ref={menuRef}>
<button
className={`profile-menu-trigger ${isOpen ? 'active' : ''}`}
onClick={toggleMenu}
aria-label="User menu"
aria-expanded={isOpen}
>
<div className="profile-menu-avatar">
<UserIcon size={16} weight="duotone"/>
</div>
<span className="profile-menu-name">{user.username}</span>
<CaretDownIcon
size={14}
className={`profile-menu-caret ${isOpen ? 'rotated' : ''}`}
/>
</button>
{isOpen && (
<div className="profile-menu-dropdown">
<div className="profile-menu-header">
<div className="profile-menu-avatar profile-menu-avatar--large">
<UserIcon size={20} weight="duotone"/>
</div>
<div className="profile-menu-info">
<div className="profile-menu-name-large">{user.username}</div>
<div className="profile-menu-role">{user.role === 'admin' ? 'Administrator' : 'User'}</div>
</div>
</div>
<div className="profile-menu-divider"></div>
<div className="profile-menu-actions">
<button
className="profile-menu-item"
onClick={handleLogout}
>
<SignOutIcon size={16}/>
<span>Sign Out</span>
</button>
</div>
</div>
)}
</div>
);
};