import React, { useState, useRef, useEffect } from 'react'; import { User, LogOut, ChevronDown, Shield, Clock } from 'lucide-react'; import { useAuth } from '../contexts/AuthContext'; import UserProfilePanel from './UserProfilePanel'; // ============================================ // INLINE STYLES — Dark theme matching DESIGN_SYSTEM.md // ============================================ const STYLES = { container: { position: 'relative', }, menuButton: { display: 'flex', alignItems: 'center', gap: '0.5rem', padding: '0.5rem 0.75rem', borderRadius: '0.5rem', background: 'transparent', border: 'none', cursor: 'pointer', transition: 'background 0.2s', }, menuButtonHover: { background: 'rgba(14, 165, 233, 0.1)', }, avatar: { width: '2rem', height: '2rem', backgroundColor: '#0476D9', borderRadius: '9999px', display: 'flex', alignItems: 'center', justifyContent: 'center', }, avatarIcon: { color: '#FFFFFF', }, userInfo: { textAlign: 'left', }, username: { fontSize: '0.875rem', fontWeight: '500', color: '#F8FAFC', margin: 0, lineHeight: 1.25, }, groupLabel: { fontSize: '0.75rem', color: '#E2E8F0', margin: 0, lineHeight: 1.25, }, chevron: { color: '#E2E8F0', transition: 'transform 0.2s', }, chevronOpen: { transform: 'rotate(180deg)', }, // Dropdown panel dropdown: { position: 'absolute', right: 0, marginTop: '0.5rem', width: '16rem', background: 'linear-gradient(135deg, rgba(30, 41, 59, 0.95) 0%, rgba(51, 65, 85, 0.9) 50%, rgba(30, 41, 59, 0.95) 100%)', borderRadius: '0.5rem', boxShadow: '0 20px 60px rgba(0, 0, 0, 0.6), 0 10px 30px rgba(14, 165, 233, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.1)', border: '1.5px solid rgba(14, 165, 233, 0.3)', padding: '0.5rem 0', zIndex: 50, }, // Dropdown header section dropdownHeader: { padding: '0.75rem 1rem', borderBottom: '1px solid rgba(14, 165, 233, 0.2)', }, dropdownHeaderName: { fontSize: '0.875rem', fontWeight: '500', color: '#F8FAFC', margin: 0, }, dropdownHeaderEmail: { fontSize: '0.875rem', color: '#94A3B8', margin: 0, }, // Menu items menuItem: { width: '100%', padding: '0.5rem 1rem', textAlign: 'left', fontSize: '0.875rem', color: '#F8FAFC', background: 'transparent', border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: '0.75rem', transition: 'background 0.15s', }, menuItemHover: { background: 'rgba(14, 165, 233, 0.1)', }, // Sign out item signOutItem: { width: '100%', padding: '0.5rem 1rem', textAlign: 'left', fontSize: '0.875rem', color: '#F87171', background: 'transparent', border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: '0.75rem', transition: 'background 0.15s', }, signOutItemHover: { background: 'rgba(239, 68, 68, 0.1)', }, }; /** * Returns inline style for the group badge in the dropdown header. * Retains the existing color-coding logic per group. */ function getGroupBadgeStyle(group) { const colors = { Admin: { bg: 'rgba(239, 68, 68, 0.2)', border: 'rgba(239, 68, 68, 0.5)', text: '#FCA5A5' }, Standard_User: { bg: 'rgba(14, 165, 233, 0.2)', border: 'rgba(14, 165, 233, 0.5)', text: '#7DD3FC' }, Leadership: { bg: 'rgba(168, 85, 247, 0.2)', border: 'rgba(168, 85, 247, 0.5)', text: '#D8B4FE' }, Read_Only: { bg: 'rgba(148, 163, 184, 0.2)', border: 'rgba(148, 163, 184, 0.5)', text: '#CBD5E1' }, }; const c = colors[group] || colors.Read_Only; return { display: 'inline-block', marginTop: '0.5rem', padding: '0.125rem 0.5rem', borderRadius: '0.25rem', fontSize: '0.75rem', fontWeight: '500', background: c.bg, border: `1px solid ${c.border}`, color: c.text, }; } export default function UserMenu({ onManageUsers, onAuditLog }) { const { user, logout, isAdmin } = useAuth(); const [isOpen, setIsOpen] = useState(false); const [buttonHovered, setButtonHovered] = useState(false); const [hoveredItem, setHoveredItem] = useState(null); const [showProfile, setShowProfile] = useState(false); const menuRef = useRef(null); // Close menu when clicking outside useEffect(() => { function handleClickOutside(event) { if (menuRef.current && !menuRef.current.contains(event.target)) { setIsOpen(false); } } document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); const formatGroupName = (group) => { if (!group) return ''; return group.replace(/_/g, ' '); }; const handleLogout = async () => { setIsOpen(false); await logout(); }; const handleProfile = () => { setIsOpen(false); setShowProfile(true); }; const handleManageUsers = () => { setIsOpen(false); if (onManageUsers) { onManageUsers(); } }; const handleAuditLog = () => { setIsOpen(false); if (onAuditLog) { onAuditLog(); } }; if (!user) return null; return (
{user.username}
{user.email}
{formatGroupName(user.group)}