93 lines
3.1 KiB
JavaScript
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>
|
|
);
|
|
}; |