import { useCallback, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { cn } from '@/lib/utils'; import { useThemeStore, useNotificationStore, useUserStore } from '@/store'; import { Button } from '@/components/ui/button'; import { Separator } from '@/components/ui/separator'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Bell, Menu, Settings, User, LogOut, CheckCheck, AlertTriangle, Info, CheckCircle, Palette, Check, } from 'lucide-react'; import { formatDistanceToNow } from '@/lib/utils'; import { useTheme, THEME_OPTIONS } from '@/hooks/useTheme'; // Keyboard shortcut handler — Cmd/Ctrl+B 切换侧边栏 function useKeyboardShortcuts() { useEffect(() => { const handler = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === 'b') { e.preventDefault(); window.dispatchEvent(new CustomEvent('toggle-sidebar')); } }; window.addEventListener('keydown', handler); return () => window.removeEventListener('keydown', handler); }, []); } export function Header() { const { sidebarCollapsed, toggleSidebar } = useThemeStore(); const { notifications, unreadCount, markAsRead, markAllAsRead } = useNotificationStore(); const { user, logout } = useUserStore(); const { theme, setTheme } = useTheme(); const navigate = useNavigate(); useKeyboardShortcuts(); const handleLogout = () => { logout(); window.location.href = '/login'; }; const displayName = user?.real_name || user?.username || '管理员'; const getNotificationIcon = useCallback((type: string) => { switch (type) { case 'error': return ; case 'warning': return ; case 'success': return ; default: return ; } }, []); return ( {/* Left: Toggle & Search */} {/* Sidebar Toggle */} {/* Right: Actions */} {/* Theme Switcher */} 主题切换 {THEME_OPTIONS.map((option) => ( setTheme(option.id)} > {option.name} {option.description} {theme === option.id && ( )} ))} {/* Notifications */} {unreadCount > 0 && ( {unreadCount > 99 ? '99+' : unreadCount} )} {/* Header */} 通知 {unreadCount > 0 && ( 全部已读 )} {/* Notification List */} {notifications.length === 0 ? ( 暂无通知 ) : ( notifications.slice(0, 10).map((notification) => ( markAsRead(notification.id)} > {getNotificationIcon(notification.type)} {notification.title} {notification.message} {formatDistanceToNow(notification.timestamp)} {!notification.read && ( )} )) )} {/* Footer */} {notifications.length > 0 && ( navigate('/alert-center')} > 查看全部通知 )} {/* User Menu */} {displayName.charAt(0).toUpperCase()} {displayName} {displayName} {user?.email || user?.username || ''} navigate('/users')} > 个人中心 navigate('/settings')} > 账号设置 退出登录 ); }
暂无通知
{notification.title}
{notification.message}
{formatDistanceToNow(notification.timestamp)}