Files
nexus-mcp/src/App.tsx

97 lines
3.8 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { Header } from './components/Header';
import { OverviewTab } from './components/OverviewTab';
import { MCPHubTab } from './components/MCPHubTab';
import { AIToolStudioTab } from './components/AIToolStudioTab';
import { WorkflowsTab } from './components/WorkflowsTab';
import { SecurityGatewayTab } from './components/SecurityGatewayTab';
import { AnalyticsTab } from './components/AnalyticsTab';
import { MCPGuideTab } from './components/MCPGuideTab';
import { ToolPlaygroundTab } from './components/ToolPlaygroundTab';
import { MemoryVaultTab } from './components/MemoryVaultTab';
import { ActivityLogsTab } from './components/ActivityLogsTab';
import { SettingsTab } from './components/SettingsTab';
import { ServerStats, MCPServerDefinition } from './types';
export default function App() {
const [activeTab, setActiveTab] = useState<string>('mcp-hub');
const [stats, setStats] = useState<ServerStats | null>(null);
const fetchStats = async () => {
try {
const res = await fetch('/api/v1/system/status');
if (res.ok) {
const data = await res.json();
setStats(data);
}
} catch (err) {
console.error('Failed to fetch server stats:', err);
}
};
const handleRegisterServerFromStudio = async (server: Omit<MCPServerDefinition, 'id' | 'createdAt'>) => {
const res = await fetch('/api/v1/mcp/servers', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(server),
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.error || 'Failed to register server');
}
await fetchStats();
};
useEffect(() => {
fetchStats();
const interval = setInterval(fetchStats, 5000);
return () => clearInterval(interval);
}, []);
return (
<div className="min-h-screen bg-slate-50 text-slate-900 font-sans flex flex-col antialiased selection:bg-indigo-500 selection:text-white">
<Header activeTab={activeTab} setActiveTab={setActiveTab} stats={stats} />
<main className="flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-8">
{activeTab === 'overview' && <OverviewTab stats={stats} setActiveTab={setActiveTab} />}
{activeTab === 'mcp-hub' && (
<MCPHubTab
stats={stats}
onRefreshStats={fetchStats}
onNavigateToStudio={() => setActiveTab('mcp-studio')}
/>
)}
{activeTab === 'mcp-studio' && (
<AIToolStudioTab
onRegisterServer={handleRegisterServerFromStudio}
onNavigateToHub={() => setActiveTab('mcp-hub')}
/>
)}
{activeTab === 'workflows' && <WorkflowsTab />}
{activeTab === 'security' && <SecurityGatewayTab />}
{activeTab === 'analytics' && <AnalyticsTab stats={stats} />}
{activeTab === 'mcp-guide' && <MCPGuideTab />}
{activeTab === 'playground' && <ToolPlaygroundTab />}
{activeTab === 'memory' && <MemoryVaultTab />}
{activeTab === 'logs' && <ActivityLogsTab />}
{activeTab === 'settings' && <SettingsTab stats={stats} />}
</main>
<footer className="border-t border-slate-200 bg-white py-6 mt-12">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col sm:flex-row items-center justify-between text-xs text-slate-500 space-y-2 sm:space-y-0 font-mono">
<div>
<span>Do Everything MCP Hub & Proxy Server v1.0.0</span>
<span className="mx-2 text-slate-300"></span>
<span>JSON-RPC 2.0 / SSE Enabled</span>
</div>
<div>
<span>Status: Healthy</span>
<span className="mx-2 text-slate-300"></span>
<span>Host: 0.0.0.0:3000</span>
</div>
</div>
</footer>
</div>
);
}