import { useEffect, useRef } from 'react' import { Link, useLocation } from 'react-router-dom' import { AnimatePresence, motion } from 'framer-motion' import { ChevronDown, LogOut, Settings, User as UserIcon, UserCog } from 'lucide-react' import clsx from 'clsx' import type { PlayProfile } from '../types' type LayoutUser = { username?: string role?: string } type LayoutUserMenuProps = { user: LayoutUser | null | undefined isOpen: boolean profiles: PlayProfile[] activeProfileId: string | null activeProfile: PlayProfile | null onToggle: () => void onClose: () => void onUseDefaultProfile: () => void onSwitchProfile: (profile: PlayProfile) => void onLogout: () => void } export function LayoutUserMenu({ user, isOpen, profiles, activeProfileId, activeProfile, onToggle, onClose, onUseDefaultProfile, onSwitchProfile, onLogout, }: LayoutUserMenuProps) { const location = useLocation() const rootRef = useRef(null) const lastLocationRef = useRef(`${location.pathname}${location.search}`) useEffect(() => { if (!isOpen) return undefined const handlePointerDown = (event: PointerEvent) => { const root = rootRef.current const target = event.target if (!root || !(target instanceof Node) || root.contains(target)) return onClose() } const handleKeyDown = (event: KeyboardEvent) => { if (event.key === 'Escape') onClose() } document.addEventListener('pointerdown', handlePointerDown, true) document.addEventListener('keydown', handleKeyDown) return () => { document.removeEventListener('pointerdown', handlePointerDown, true) document.removeEventListener('keydown', handleKeyDown) } }, [isOpen, onClose]) useEffect(() => { const nextLocation = `${location.pathname}${location.search}` if (lastLocationRef.current === nextLocation) return lastLocationRef.current = nextLocation if (isOpen) onClose() }, [isOpen, location.pathname, location.search, onClose]) return (
{isOpen && ( } label="个人基本信息" onClick={onClose} /> {user?.role === 'admin' && ( } label="管理主控制台" onClick={onClose} /> )}

当前观影 Profile

{profiles.map((profile) => ( ))}
} label="管理观影 Profile" onClick={onClose} />
)}
) } function UserMenuLink({ to, icon, label, onClick, }: { to: string icon: React.ReactNode label: string onClick: () => void }) { return ( {icon} {label} ) } function profileButtonClass(active: boolean): string { return clsx( 'flex w-full items-center justify-between rounded-xl px-2.5 py-2 text-left text-xs transition-colors', active ? 'bg-[var(--app-active-bg)] text-[var(--app-active-text)]' : 'text-[var(--app-subtle)] hover:bg-[var(--app-hover)]', ) }