src/components/Footer/MarketStats/index.tsx
import React, { ReactElement, useCallback, useEffect, useState } from 'react'
import { OperationContext } from 'urql'
import { fetchData, getSubgraphUri } from '@utils/subgraph'
import useNetworkMetadata, {
filterNetworksByType
} from '@hooks/useNetworkMetadata'
import { LoggerInstance } from '@oceanprotocol/lib'
import styles from './index.module.css'
import { FooterStatsValues_globalStatistics as FooterStatsValuesGlobalStatistics } from '../../../../src/@types/subgraph/FooterStatsValues'
import MarketStatsTotal from './Total'
import { queryGlobalStatistics } from './_queries'
import { StatsTotal } from './_types'
import { useMarketMetadata } from '@context/MarketMetadata'
import Tooltip from '@shared/atoms/Tooltip'
import Markdown from '@shared/Markdown'
import content from '../../../../content/footer.json'
import Loader from '@components/@shared/atoms/Loader'
const initialTotal: StatsTotal = {
nfts: 0,
datatokens: 0,
orders: 0
}
function LoaderArea() {
return (
<div className={styles.loaderWrap}>
<Loader />
</div>
)
}
export default function MarketStats(): ReactElement {
const { appConfig } = useMarketMetadata()
const { networksList } = useNetworkMetadata()
const [mainChainIds, setMainChainIds] = useState<number[]>()
const [data, setData] = useState<{
[chainId: number]: FooterStatsValuesGlobalStatistics
}>()
const [total, setTotal] = useState(initialTotal)
const [loading, setLoading] = useState<boolean>(false)
//
// Set the main chain ids we want to display stats for
//
useEffect(() => {
if (!networksList || !appConfig || !appConfig?.chainIds) return
const mainChainIdsList = filterNetworksByType(
'mainnet',
appConfig.chainIds,
networksList
)
setMainChainIds(mainChainIdsList)
}, [appConfig, appConfig?.chainIds, networksList])
//
// Helper: fetch data from subgraph
//
const getMarketStats = useCallback(async () => {
if (!mainChainIds?.length) return
const newData: {
[chainId: number]: FooterStatsValuesGlobalStatistics
} = {}
for (const chainId of mainChainIds) {
const context: OperationContext = {
url: `${getSubgraphUri(
chainId
)}/subgraphs/name/oceanprotocol/ocean-subgraph`,
requestPolicy: 'network-only'
}
try {
const response = await fetchData(queryGlobalStatistics, null, context)
if (!response?.data?.globalStatistics) return
newData[chainId] = response.data.globalStatistics[0]
} catch (error) {
LoggerInstance.error('Error fetching global stats: ', error.message)
}
}
setData(newData)
}, [mainChainIds])
//
// 1. Fetch Data
//
useEffect(() => {
getMarketStats()
}, [getMarketStats])
//
// 2. Data Manipulation
//
useEffect(() => {
if (!data || !mainChainIds?.length) return
setLoading(true)
const newTotal: StatsTotal = total
for (const chainId of mainChainIds) {
try {
const nftCount = data[chainId]?.nftCount || 0
const datatokenCount = data[chainId]?.datatokenCount || 0
const orderCount = data[chainId]?.orderCount || 0
newTotal.nfts += nftCount
newTotal.datatokens += datatokenCount
newTotal.orders += orderCount
} catch (error) {
LoggerInstance.error('Error data manipulation: ', error.message)
}
}
async function setTotalAllocatedAndLocked() {
setTotal(newTotal)
setLoading(false)
}
setTotalAllocatedAndLocked()
}, [data, mainChainIds])
return loading ? (
<LoaderArea />
) : (
<div className={styles.stats}>
<div>
<MarketStatsTotal total={total} />{' '}
<Tooltip
className={styles.info}
content={
<Markdown className={styles.note} text={content.stats.note} />
}
/>
</div>
</div>
)
}