Add UI components

This commit is contained in:
Mathias Wagner
2025-09-09 13:07:35 +02:00
parent 12f9eebfad
commit e39a583e95
16 changed files with 580 additions and 198 deletions

View File

@@ -0,0 +1,95 @@
import React, {useState, useRef, useEffect, useContext} from 'react';
import {UserCircleIcon, SignOutIcon, CaretDownIcon} from '@phosphor-icons/react';
import {UserContext} from '@/common/contexts/UserContext.jsx';
import './styles.sass';
export const ProfileMenu = () => {
const {logout} = useContext(UserContext);
const [isOpen, setIsOpen] = useState(false);
const menuRef = useRef(null);
// Close menu when clicking outside
useEffect(() => {
const handleClickOutside = (event) => {
if (menuRef.current && !menuRef.current.contains(event.target)) {
setIsOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
// Close menu on escape key
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">
<UserCircleIcon size={16} weight="fill"/>
</div>
<span className="profile-menu-name">Admin</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">
<UserCircleIcon size={20} weight="fill"/>
</div>
<div className="profile-menu-info">
<div className="profile-menu-name-large">Admin User</div>
<div className="profile-menu-role">Administrator</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>
);
};