import { useMemo, useCallback } from 'react'
import { Routes, Route, Navigate, useNavigate } from 'react-router-dom'
import { Dashboard } from './pages/Dashboard/Dashboard'
import { Metrics } from './pages/Metrics/Metrics'
import { RouteDetail } from './pages/RouteDetail/RouteDetail'
import { ExchangeDetail } from './pages/ExchangeDetail/ExchangeDetail'
import { AgentHealth } from './pages/AgentHealth/AgentHealth'
import { Inventory } from './pages/Inventory/Inventory'
import { Admin } from './pages/Admin/Admin'
import { ApiDocs } from './pages/ApiDocs/ApiDocs'
import { CommandPalette } from './design-system/composites/CommandPalette/CommandPalette'
import type { SearchResult } from './design-system/composites/CommandPalette/types'
import { useCommandPalette } from './design-system/providers/CommandPaletteProvider'
import { useGlobalFilters } from './design-system/providers/GlobalFilterProvider'
import { buildSearchData } from './mocks/searchData'
import { exchanges } from './mocks/exchanges'
import { routes } from './mocks/routes'
import { agents } from './mocks/agents'
import { SIDEBAR_APPS } from './mocks/sidebar'
/** Compute which sidebar path to reveal for a given search result */
function computeSidebarRevealPath(result: SearchResult): string | undefined {
if (!result.path) return undefined
if (result.category === 'application') {
// /apps/:id — already a sidebar node path
return result.path
}
if (result.category === 'route') {
// /routes/:id — already a sidebar node path
return result.path
}
if (result.category === 'agent') {
// /agents/:appId/:agentId — already a sidebar node path
return result.path
}
if (result.category === 'exchange') {
// /exchanges/:id — no sidebar entry; resolve to the parent route
const exchange = exchanges.find((e) => e.id === result.id)
if (exchange) {
return `/routes/${exchange.route}`
}
}
return result.path
}
export default function App() {
const navigate = useNavigate()
const { open: paletteOpen, setOpen } = useCommandPalette()
const { isInTimeRange, statusFilters } = useGlobalFilters()
const filteredSearchData = useMemo(() => {
// Filter exchanges by time range and status
let filteredExchanges = exchanges.filter((e) => isInTimeRange(e.timestamp))
if (statusFilters.size > 0) {
filteredExchanges = filteredExchanges.filter((e) => statusFilters.has(e.status))
}
return buildSearchData(filteredExchanges, routes, agents)
}, [isInTimeRange, statusFilters])
const handleSelect = useCallback(
(result: SearchResult) => {
if (result.path) {
const sidebarReveal = computeSidebarRevealPath(result)
navigate(result.path, { state: sidebarReveal ? { sidebarReveal } : undefined })
}
setOpen(false)
},
[navigate, setOpen],
)
return (
<>
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
setOpen(false)}
onOpen={() => setOpen(true)}
data={filteredSearchData}
onSelect={handleSelect}
/>
>
)
}