mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Statistics footer (#746)
* display multiple chains statistics * fetching stats data from multiple subgraphs * design changes * display one combined stat for all main networks * tooltip updates * added Loader component * refactoring * refactor for better fallback, remove loader * tooltip styling and refactor Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
This commit is contained in:
parent
fddd5ff144
commit
7368c9cc68
@ -28,9 +28,7 @@ export default function Tooltip({
|
||||
trigger,
|
||||
disabled,
|
||||
className,
|
||||
placement,
|
||||
link,
|
||||
reference
|
||||
placement
|
||||
}: {
|
||||
content: ReactNode
|
||||
children?: ReactNode
|
||||
@ -38,8 +36,6 @@ export default function Tooltip({
|
||||
disabled?: boolean
|
||||
className?: string
|
||||
placement?: Placement
|
||||
link?: string
|
||||
reference?: string
|
||||
}): ReactElement {
|
||||
const [props, setSpring] = useSpring(() => animation.from)
|
||||
|
||||
@ -76,7 +72,6 @@ export default function Tooltip({
|
||||
<animated.div style={props}>
|
||||
<div className={styles.content} {...attrs}>
|
||||
{content}
|
||||
{link && <a href={link}>{reference}</a>}
|
||||
<div className={styles.arrow} data-popper-arrow />
|
||||
</div>
|
||||
</animated.div>
|
||||
|
@ -1,18 +1,42 @@
|
||||
.stats {
|
||||
margin-bottom: calc(var(--spacer) * 2);
|
||||
}
|
||||
|
||||
/* specificity sledgehammer override without !important */
|
||||
.stats,
|
||||
.stats *,
|
||||
.statsList * {
|
||||
font-size: var(--font-size-small);
|
||||
line-height: 2;
|
||||
color: var(--color-secondary);
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.stats > div > div {
|
||||
display: inline-block;
|
||||
.tooltipStats {
|
||||
margin-bottom: calc(var(--spacer) / 3);
|
||||
padding-bottom: calc(var(--spacer) / 3);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.total {
|
||||
color: var(--color-secondary) !important;
|
||||
font-size: var(--font-size-small) !important;
|
||||
.network {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.info {
|
||||
width: 0.85rem;
|
||||
}
|
||||
|
||||
.statsList,
|
||||
.note {
|
||||
padding: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
.statsList {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.note {
|
||||
margin-bottom: 0;
|
||||
padding-top: 0;
|
||||
font-size: var(--font-size-mini);
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
import React, { ReactElement, useEffect, useState } from 'react'
|
||||
import styles from './MarketStats.module.css'
|
||||
import { gql, useQuery } from 'urql'
|
||||
import { gql, OperationContext } from 'urql'
|
||||
import Conversion from '../atoms/Price/Conversion'
|
||||
import PriceUnit from '../atoms/Price/PriceUnit'
|
||||
import Tooltip from '../atoms/Tooltip'
|
||||
import NetworkName from '../atoms/NetworkName'
|
||||
import { fetchData, getSubgrahUri } from '../../utils/subgraph'
|
||||
import { filterNetworksByType } from './UserPreferences/Networks/index'
|
||||
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||
import useNetworkMetadata from '../../hooks/useNetworkMetadata'
|
||||
import { Logger } from '@oceanprotocol/lib'
|
||||
import styles from './MarketStats.module.css'
|
||||
|
||||
const getTotalPoolsValues = gql`
|
||||
query PoolsData {
|
||||
@ -15,36 +21,160 @@ const getTotalPoolsValues = gql`
|
||||
}
|
||||
`
|
||||
|
||||
interface Value {
|
||||
[chainId: number]: string
|
||||
}
|
||||
|
||||
function MarketNetworkStats({
|
||||
totalValueLocked,
|
||||
poolCount,
|
||||
totalOceanLiquidity
|
||||
}: {
|
||||
totalValueLocked: string
|
||||
poolCount: string
|
||||
totalOceanLiquidity: string
|
||||
}): ReactElement {
|
||||
return (
|
||||
<>
|
||||
<Conversion price={totalValueLocked} hideApproximateSymbol />{' '}
|
||||
<abbr title="Total Value Locked">TVL</abbr> across{' '}
|
||||
<strong>{poolCount}</strong> asset pools that contain{' '}
|
||||
<PriceUnit price={totalOceanLiquidity} small className={styles.total} />,
|
||||
plus datatokens for each pool.
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function MarketNetworkStatsTooltip({
|
||||
totalValueLocked,
|
||||
poolCount,
|
||||
totalOceanLiquidity,
|
||||
mainChainIds
|
||||
}: {
|
||||
totalValueLocked: Value
|
||||
poolCount: Value
|
||||
totalOceanLiquidity: Value
|
||||
mainChainIds: number[]
|
||||
}): ReactElement {
|
||||
return (
|
||||
<>
|
||||
<ul className={styles.statsList}>
|
||||
{totalValueLocked &&
|
||||
totalOceanLiquidity &&
|
||||
poolCount &&
|
||||
mainChainIds?.map((chainId, key) => (
|
||||
<li className={styles.tooltipStats} key={key}>
|
||||
<NetworkName networkId={chainId} className={styles.network} />
|
||||
<br />
|
||||
<Conversion
|
||||
price={totalValueLocked[chainId] || '0'}
|
||||
hideApproximateSymbol
|
||||
/>{' '}
|
||||
<abbr title="Total Value Locked">TVL</abbr>
|
||||
{' | '}
|
||||
<strong>{poolCount[chainId] || '0'}</strong> pools
|
||||
{' | '}
|
||||
<PriceUnit price={totalOceanLiquidity[chainId] || '0'} small />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className={styles.note}>
|
||||
Counted on-chain from our pool factory. Does not filter out assets in{' '}
|
||||
<a href="https://github.com/oceanprotocol/list-purgatory">
|
||||
list-purgatory
|
||||
</a>
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default function MarketStats(): ReactElement {
|
||||
const [totalValueLocked, setTotalValueLocked] = useState<string>()
|
||||
const [totalOceanLiquidity, setTotalOceanLiquidity] = useState<string>()
|
||||
const [poolCount, setPoolCount] = useState<number>()
|
||||
const [result] = useQuery({
|
||||
query: getTotalPoolsValues
|
||||
// pollInterval: 20000
|
||||
})
|
||||
const { data } = result
|
||||
const [totalValueLocked, setTotalValueLocked] = useState<Value>()
|
||||
const [totalOceanLiquidity, setTotalOceanLiquidity] = useState<Value>()
|
||||
const [poolCount, setPoolCount] = useState<Value>()
|
||||
const [totalValueLockedSum, setTotalValueLockedSum] = useState<string>()
|
||||
const [totalOceanLiquiditySum, setTotalOceanLiquiditySum] = useState<string>()
|
||||
const [poolCountSum, setPoolCountSum] = useState<string>()
|
||||
const [mainChainIds, setMainChainIds] = useState<number[]>()
|
||||
const { appConfig } = useSiteMetadata()
|
||||
const { networksList } = useNetworkMetadata()
|
||||
|
||||
async function getMarketStats() {
|
||||
const mainChainIdsList = await filterNetworksByType(
|
||||
'mainnet',
|
||||
appConfig.chainIdsSupported,
|
||||
networksList
|
||||
)
|
||||
setMainChainIds(mainChainIdsList)
|
||||
|
||||
let newTotalValueLockedSum = 0
|
||||
let newTotalOceanLiquiditySum = 0
|
||||
let newPoolCountSum = 0
|
||||
|
||||
for (const chainId of mainChainIdsList) {
|
||||
const context: OperationContext = {
|
||||
url: `${getSubgrahUri(
|
||||
chainId
|
||||
)}/subgraphs/name/oceanprotocol/ocean-subgraph`,
|
||||
requestPolicy: 'network-only'
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetchData(getTotalPoolsValues, null, context)
|
||||
if (!response) continue
|
||||
|
||||
const { totalValueLocked, totalOceanLiquidity, finalizedPoolCount } =
|
||||
response?.data?.poolFactories[0]
|
||||
|
||||
await setTotalValueLocked((prevState) => ({
|
||||
...prevState,
|
||||
[chainId]: totalValueLocked
|
||||
}))
|
||||
await setTotalOceanLiquidity((prevState) => ({
|
||||
...prevState,
|
||||
[chainId]: totalOceanLiquidity
|
||||
}))
|
||||
await setPoolCount((prevState) => ({
|
||||
...prevState,
|
||||
[chainId]: finalizedPoolCount
|
||||
}))
|
||||
|
||||
newTotalValueLockedSum += parseInt(totalValueLocked)
|
||||
newTotalOceanLiquiditySum += parseInt(totalOceanLiquidity)
|
||||
newPoolCountSum += parseInt(finalizedPoolCount)
|
||||
} catch (error) {
|
||||
Logger.error('Error fetchData: ', error.message)
|
||||
}
|
||||
}
|
||||
setTotalValueLockedSum(`${newTotalValueLockedSum}`)
|
||||
setTotalOceanLiquiditySum(`${newTotalOceanLiquiditySum}`)
|
||||
setPoolCountSum(`${newPoolCountSum}`)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!data || !data.poolFactories || data.poolFactories.length === 0) return
|
||||
setTotalValueLocked(data.poolFactories[0].totalValueLocked)
|
||||
setTotalOceanLiquidity(data.poolFactories[0].totalOceanLiquidity)
|
||||
setPoolCount(data.poolFactories[0].finalizedPoolCount)
|
||||
}, [data])
|
||||
getMarketStats()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={styles.stats}>
|
||||
<Conversion price={`${totalValueLocked}`} hideApproximateSymbol />{' '}
|
||||
<abbr title="Total Value Locked">TVL</abbr> across{' '}
|
||||
<strong>{poolCount}</strong> data set pools that contain{' '}
|
||||
<PriceUnit price={totalOceanLiquidity} small className={styles.total} />,
|
||||
plus datatokens for each pool.
|
||||
<Tooltip
|
||||
className={styles.info}
|
||||
content="Counted on-chain from our pool factory. Does not filter out data sets in "
|
||||
reference="list-purgatory"
|
||||
link="https://github.com/oceanprotocol/list-purgatory"
|
||||
/>
|
||||
<>
|
||||
<MarketNetworkStats
|
||||
totalValueLocked={totalValueLockedSum || '0'}
|
||||
totalOceanLiquidity={totalOceanLiquiditySum || '0'}
|
||||
poolCount={poolCountSum || '0'}
|
||||
/>{' '}
|
||||
<Tooltip
|
||||
className={styles.info}
|
||||
content={
|
||||
<MarketNetworkStatsTooltip
|
||||
totalValueLocked={totalValueLocked}
|
||||
poolCount={poolCount}
|
||||
totalOceanLiquidity={totalOceanLiquidity}
|
||||
mainChainIds={mainChainIds}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import stylesIndex from '../index.module.css'
|
||||
import styles from './index.module.css'
|
||||
import useNetworkMetadata from '../../../../hooks/useNetworkMetadata'
|
||||
|
||||
function filterNetworksByType(
|
||||
export function filterNetworksByType(
|
||||
type: 'mainnet' | 'testnet',
|
||||
chainIds: number[],
|
||||
networksList: { node: EthereumListsChain }[]
|
||||
|
@ -150,7 +150,7 @@ export async function fetchData(
|
||||
query: TypedDocumentNode,
|
||||
variables: any,
|
||||
context: OperationContext
|
||||
): Promise<OperationResult> {
|
||||
): Promise<any> {
|
||||
try {
|
||||
const client = getUrqlClientInstance()
|
||||
const response = await client.query(query, variables, context).toPromise()
|
||||
|
Loading…
Reference in New Issue
Block a user