@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.
179 lines (173 loc) • 5.63 kB
JSX
import { useState } from 'react';
import { colors } from './theme';
import SmartScanHeader from './components/SmartScan/SmartScanHeader';
import SmartScanControls from './components/SmartScan/SmartScanControls';
import ViewModeTabs from './components/SmartScan/ViewModeTabs';
import ScanViewContent from './components/SmartScan/ScanViewContent';
import ListViewContent from './components/SmartScan/ListViewContent';
import { useSmartScan } from './components/SmartScan/useSmartScan';
function SmartScan() {
const [viewMode, setViewMode] = useState('scan'); // 'scan' or 'list'
const {
apiToken,
setApiToken,
discoveredServers,
selectedServers,
setSelectedServers,
loadingData,
scanning,
scanResult,
scanResults,
error,
saveToken,
discoverMcpData,
runScan,
clearCache,
clearingCache,
allScans,
loadingScans,
loadAllScans,
selectedScan,
setSelectedScan,
loadingScanDetail,
loadScanDetail,
} = useSmartScan();
return (
<div
data-tab-content
style={{
flex: 1,
overflow: 'hidden',
display: 'flex',
flexDirection: 'column',
background: colors.bgPrimary,
}}
>
{/* Top Bar - Controls */}
<div
style={{
background: colors.bgCard,
borderBottom: `1px solid ${colors.borderLight}`,
padding: '16px 24px',
boxShadow: `0 2px 4px ${colors.shadowSm}`,
}}
>
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '24px',
flexWrap: 'wrap',
}}
>
<SmartScanHeader />
<ViewModeTabs
viewMode={viewMode}
setViewMode={setViewMode}
onSwitchToScan={() => setSelectedScan(null)}
onSwitchToList={() => {
setSelectedScan(null);
if (allScans.length === 0) {
loadAllScans();
}
}}
/>
{viewMode === 'scan' && (
<SmartScanControls
apiToken={apiToken}
setApiToken={setApiToken}
saveToken={saveToken}
loadingData={loadingData}
discoverMcpData={discoverMcpData}
discoveredServers={discoveredServers}
selectedServers={selectedServers}
setSelectedServers={setSelectedServers}
runScan={runScan}
scanning={scanning}
clearCache={clearCache}
clearingCache={clearingCache}
/>
)}
</div>
</div>
{/* Content based on view mode */}
{viewMode === 'scan' ? (
<ScanViewContent
discoveredServers={discoveredServers}
selectedServers={selectedServers}
setSelectedServers={setSelectedServers}
runScan={runScan}
scanning={scanning}
apiToken={apiToken}
error={error}
scanResults={scanResults}
scanResult={scanResult}
selectedScan={selectedScan}
loadingScanDetail={loadingScanDetail}
setSelectedScan={setSelectedScan}
loadScanDetail={loadScanDetail}
onViewScan={(scanData) => {
console.log('onViewScan - scanData:', scanData);
if (scanData.scan_id && apiToken) {
loadScanDetail(scanData.scan_id);
} else if (scanData.data && typeof scanData.data === 'object') {
const actualScan = scanData.data;
setSelectedScan({
...actualScan,
scan_id: scanData.scan_id || actualScan.id || actualScan.scan_id,
});
} else {
setSelectedScan(scanData);
}
}}
/>
) : (
<div
style={{
flex: 1,
overflowY: 'auto',
overflowX: 'hidden',
padding: '24px',
background: colors.bgPrimary,
}}
>
<ListViewContent
error={error}
loadingScans={loadingScans}
selectedScan={selectedScan}
loadingScanDetail={loadingScanDetail}
allScans={allScans}
setSelectedScan={setSelectedScan}
loadScanDetail={loadScanDetail}
onViewScan={(scanData) => {
console.log('onViewScan - scanData:', scanData);
const scanId = scanData.scan_id || scanData.id || scanData.hash;
const matchingScan = allScans.find(
(s) => s.data?.scan_id === scanId || s.data?.data?.scan_id === scanId
);
const serverName =
matchingScan?.serverName || scanData.serverName || 'Unknown Server';
if (scanData && scanData.data && typeof scanData.data === 'object') {
const actualScan = scanData.data;
setSelectedScan({
...actualScan,
scan_id: scanId || actualScan.id || actualScan.scan_id || actualScan.hash,
serverName: serverName,
});
} else if (scanData && typeof scanData === 'object') {
setSelectedScan({
...scanData,
scan_id: scanId || scanData.id || scanData.hash,
serverName: serverName,
});
} else {
console.warn('Invalid scanData structure:', scanData);
}
}}
/>
</div>
)}
</div>
);
}
export default SmartScan;