/** * 页面头部组件 - 移动端优化 * * 核心概念: * - Web UI 是 MCP 测试工具,不需要全局登录 * - 显示已连接的 MCP 服务器数量 * - 移动端:两行布局,避免挤在一起 */ 'use client'; import { useState, useEffect } from 'react'; import Link from 'next/link'; import { MCP_SERVERS, mcpTokenManager } from '@/lib/mcp-token-manager'; export default function Header() { // 客户端挂载标志 - 用于避免 hydration 错误 const [mounted, setMounted] = useState(false); // 初始值设为 0,避免 SSR/CSR 不匹配 const [enabledCount, setEnabledCount] = useState(0); const [loggedInCount, setLoggedInCount] = useState(0); // 从 MCP_SERVERS 配置获取总数 const total = Object.keys(MCP_SERVERS).length; useEffect(() => { // 设置客户端挂载标志 setMounted(true); // 从 localStorage 读取真实状态(只在客户端执行) const updateStatus = () => { const enabled = mcpTokenManager.getEnabledMcpList().length; const loggedIn = mcpTokenManager.getLoggedInMcpList().length; console.log('[Header] updateStatus:', { enabled, loggedIn }); setEnabledCount(enabled); setLoggedInCount(loggedIn); }; // 初始化时更新状态 updateStatus(); // 监听 storage 变化(其他标签页修改 localStorage) const handleStorageChange = () => updateStatus(); window.addEventListener('storage', handleStorageChange); // 自定义事件:MCP 启用状态变化(当前页面内) const handleMcpEnabledChange = () => updateStatus(); window.addEventListener('mcp-enabled-change', handleMcpEnabledChange); // 监听 focus 事件,确保页面获得焦点时更新状态 const handleFocus = () => updateStatus(); window.addEventListener('focus', handleFocus); return () => { window.removeEventListener('storage', handleStorageChange); window.removeEventListener('mcp-enabled-change', handleMcpEnabledChange); window.removeEventListener('focus', handleFocus); }; }, []); // 空依赖数组,只在挂载时执行一次 return (
{/* 移动端:两行布局 */}
{/* 第一行:标题和导航 */}

AI MCP Web UI

{/* 第二行(移动端)/ 右侧(桌面端):MCP 状态 */}
{/* MCP 连接状态 */}
MCP: 0 ? 'bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200' : 'bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-400' }`}> {mounted ? `已启用 ${enabledCount}/${total}` : '加载中...'} {mounted && loggedInCount > 0 && ( 已登录 {loggedInCount}/{total} )}
{mounted ? (loggedInCount > 0 ? '管理' : '连接 MCP') : 'MCP'}
); }