'use client'; import React from 'react'; import Link from 'next/link'; import { usePathname, useRouter } from 'next/navigation'; import { Bell, Bot, ChevronDown, FolderOpen, ListTodo, LogOut, Mail, MessageSquare, Puzzle, Settings, Store, Wrench } from 'lucide-react'; import { logout } from '@/lib/api'; import { LanguageSwitcher } from '@/components/LanguageSwitcher'; import { Avatar, AvatarFallback } from '@/components/ui/avatar'; import { Button } from '@/components/ui/button'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { appConnectionStatusLabel } from '@/lib/i18n/common'; import { pickAppText } from '@/lib/i18n/core'; import { useAppI18n } from '@/lib/i18n/provider'; import { useChatStore } from '@/lib/store'; type NavItem = { key: 'chat' | 'tasks' | 'notifications' | 'skills' | 'files' | 'tools' | 'agents' | 'outlook' | 'marketplace' | 'settings'; href: string; icon: React.ComponentType<{ className?: string }>; matchPrefixes?: string[]; }; const NAV_ITEMS: NavItem[] = [ { key: 'chat', href: '/', icon: MessageSquare }, { key: 'tasks', href: '/tasks', icon: ListTodo, matchPrefixes: ['/tasks', '/cron'] }, { key: 'notifications', href: '/notifications', icon: Bell, matchPrefixes: ['/notifications'] }, { key: 'skills', href: '/skills', icon: Puzzle }, { key: 'files', href: '/files', icon: FolderOpen, matchPrefixes: ['/files'] }, { key: 'tools', href: '/mcp', icon: Wrench, matchPrefixes: ['/mcp'] }, { key: 'agents', href: '/agents', icon: Bot, matchPrefixes: ['/agents'] }, { key: 'outlook', href: '/outlook', icon: Mail, matchPrefixes: ['/outlook'] }, { key: 'marketplace', href: '/marketplace', icon: Store, matchPrefixes: ['/marketplace'] }, { key: 'settings', href: '/settings', icon: Settings, matchPrefixes: ['/settings', '/status', '/logs'], }, ]; function ConnectionDot() { const { locale } = useAppI18n(); const wsStatus = useChatStore((s) => s.wsStatus); const beaverReady = useChatStore((s) => s.beaverReady); const isOnline = wsStatus === 'connected' && beaverReady === true; const isChecking = wsStatus === 'connected' && beaverReady === null; const isConnecting = wsStatus === 'connecting' || isChecking; const isOffline = wsStatus === 'disconnected' || (wsStatus === 'connected' && beaverReady === false); const color = isOnline ? 'bg-[#869683]' : isConnecting ? 'bg-[#8B7E77]' : 'bg-[#5F5550]'; const label = appConnectionStatusLabel(wsStatus, beaverReady, locale); return (
{label}
); } const Header = () => { const { locale } = useAppI18n(); const pathname = usePathname(); const router = useRouter(); const user = useChatStore((s) => s.user); const isAuthLoading = useChatStore((s) => s.isAuthLoading); const setUser = useChatStore((s) => s.setUser); const navLabel = React.useCallback((key: NavItem['key']) => { if (key === 'chat') return pickAppText(locale, '对话', 'Chat'); if (key === 'tasks') return 'Task'; if (key === 'notifications') return pickAppText(locale, '通知', 'Notifications'); if (key === 'skills') return pickAppText(locale, '技能', 'Skills'); if (key === 'files') return pickAppText(locale, '文件', 'Files'); if (key === 'tools') return pickAppText(locale, '工具', 'Tools'); if (key === 'agents') return pickAppText(locale, '智能体', 'Agents'); if (key === 'outlook') return 'Outlook'; if (key === 'marketplace') return pickAppText(locale, '市场', 'Marketplace'); return pickAppText(locale, '配置', 'Settings'); }, [locale]); const handleLogout = async () => { await logout(); setUser(null); router.replace('/login'); router.refresh(); }; const userInitial = (user?.username || user?.email || '?').trim().charAt(0).toUpperCase(); return (
Beaver
{user ? (

{user.email}

{userInitial}

{pickAppText(locale, `${user.username},你好!`, `Hi, ${user.username}`)}

{pickAppText(locale, '当前已登录到你的工作区实例。', 'You are currently signed in to your workspace instance.')}

) : !isAuthLoading ? null : null}
); }; export default Header;