import { useEffect, useMemo, useState } from 'react' import { Card } from '@/libs/frontend-ui-primitives' import { explorerFeaturePages } from '@/data/explorerOperations' import { blocksApi, type Block } from '@/services/api/blocks' import { missionControlApi, type MissionControlBridgeStatusResponse, type MissionControlChainStatus, } from '@/services/api/missionControl' import { statsApi, type ExplorerStats } from '@/services/api/stats' import { transactionsApi, type Transaction } from '@/services/api/transactions' import OperationsPageShell, { MetricCard, StatusBadge, formatNumber, relativeAge, truncateMiddle, } from './OperationsPageShell' function getChainStatus(bridgeStatus: MissionControlBridgeStatusResponse | null): MissionControlChainStatus | null { const chains = bridgeStatus?.data?.chains if (!chains) return null const [firstChain] = Object.values(chains) return firstChain || null } export default function AnalyticsOperationsPage() { const [stats, setStats] = useState(null) const [blocks, setBlocks] = useState([]) const [transactions, setTransactions] = useState([]) const [bridgeStatus, setBridgeStatus] = useState(null) const [loadingError, setLoadingError] = useState(null) const page = explorerFeaturePages.analytics useEffect(() => { let cancelled = false const load = async () => { const [statsResult, blocksResult, transactionsResult, bridgeResult] = await Promise.allSettled([ statsApi.get(), blocksApi.list({ chain_id: 138, page: 1, page_size: 5 }), transactionsApi.list(138, 1, 5), missionControlApi.getBridgeStatus(), ]) if (cancelled) return if (statsResult.status === 'fulfilled') setStats(statsResult.value) if (blocksResult.status === 'fulfilled') setBlocks(blocksResult.value.data) if (transactionsResult.status === 'fulfilled') setTransactions(transactionsResult.value.data) if (bridgeResult.status === 'fulfilled') setBridgeStatus(bridgeResult.value) const failedCount = [statsResult, blocksResult, transactionsResult, bridgeResult].filter( (result) => result.status === 'rejected' ).length if (failedCount === 4) { setLoadingError('Analytics data is temporarily unavailable from the public explorer APIs.') } } load().catch((error) => { if (!cancelled) { setLoadingError(error instanceof Error ? error.message : 'Analytics data is temporarily unavailable from the public explorer APIs.') } }) return () => { cancelled = true } }, []) const chainStatus = useMemo(() => getChainStatus(bridgeStatus), [bridgeStatus]) return ( {loadingError ? (

{loadingError}

) : null}
{blocks.map((block) => (
Block {formatNumber(block.number)}
{truncateMiddle(block.hash)} · miner {truncateMiddle(block.miner)}
{formatNumber(block.transaction_count)} tx · {relativeAge(block.timestamp)}
))} {blocks.length === 0 ? (

No recent block data available.

) : null}
{transactions.map((transaction) => (
{truncateMiddle(transaction.hash, 12, 10)}
Block {formatNumber(transaction.block_number)} · from {truncateMiddle(transaction.from_address)}
{relativeAge(transaction.created_at)}
))} {transactions.length === 0 ? (

No recent transaction data available.

) : null}
) }