UNPKG

@mcp-shark/mcp-shark

Version:

Aggregate multiple Model Context Protocol (MCP) servers into a single unified interface with a powerful monitoring UI. Prov deep visibility into every request and response.

144 lines (133 loc) 3.74 kB
import { useEffect, useRef, useState } from 'react'; import { colors, fonts } from './theme'; import { SharkLogo } from './components/SharkLogo'; import { NetworkIcon, LogsIcon, SettingsIcon, PlaygroundIcon, ShieldIcon, } from './components/TabNavigationIcons'; import MobileDropdown from './components/TabNavigation/MobileDropdown'; import DesktopTabs from './components/TabNavigation/DesktopTabs'; function TabNavigation({ activeTab, onTabChange }) { const tabs = [ { id: 'traffic', label: 'Traffic Capture', icon: NetworkIcon, description: 'Wireshark-like HTTP request/response analysis for forensic investigation', }, { id: 'logs', label: 'MCP Shark Logs', icon: LogsIcon, description: 'View MCP Shark server console output and debug logs', }, { id: 'setup', label: 'MCP Server Setup', icon: SettingsIcon, description: 'Configure and manage MCP Shark server', }, { id: 'playground', label: 'MCP Playground', icon: PlaygroundIcon, description: 'Test and interact with MCP tools, prompts, and resources', }, { id: 'smart-scan', label: 'Smart Scan', icon: ShieldIcon, description: 'AI-powered security analysis for MCP servers', }, ]; const tabRefs = useRef({}); const indicatorRef = useRef(null); const [isMobile, setIsMobile] = useState(false); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const dropdownRef = useRef(null); // Check window size and handle resize useEffect(() => { const checkMobile = () => { setIsMobile(window.innerWidth < 1200); }; checkMobile(); window.addEventListener('resize', checkMobile); return () => window.removeEventListener('resize', checkMobile); }, []); // Close dropdown when clicking outside useEffect(() => { const handleClickOutside = (event) => { if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { setIsDropdownOpen(false); } }; if (isDropdownOpen) { document.addEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isDropdownOpen]); return ( <div style={{ borderBottom: `1px solid ${colors.borderLight}`, background: colors.bgCard, boxShadow: `0 1px 3px ${colors.shadowSm}`, }} > <div style={{ display: 'flex', alignItems: 'center', padding: '0 16px', gap: '12px', }} > <div style={{ display: 'flex', alignItems: 'center', gap: '8px', paddingRight: '12px', borderRight: `1px solid ${colors.borderLight}`, }} > <SharkLogo size={24} /> <span style={{ fontSize: '16px', fontWeight: '600', color: colors.textPrimary, fontFamily: fonts.body, }} > MCP Shark </span> </div> {isMobile ? ( <MobileDropdown tabs={tabs} activeTab={activeTab} onTabChange={onTabChange} isDropdownOpen={isDropdownOpen} setIsDropdownOpen={setIsDropdownOpen} dropdownRef={dropdownRef} /> ) : ( <DesktopTabs tabs={tabs} activeTab={activeTab} onTabChange={onTabChange} tabRefs={tabRefs} indicatorRef={indicatorRef} /> )} </div> </div> ); } export default TabNavigation;