From 7368c9cc68a332eea44955243f18cab825b9f653 Mon Sep 17 00:00:00 2001 From: Norbi <37236152+KatunaNorbert@users.noreply.github.com> Date: Thu, 22 Jul 2021 14:07:52 +0300 Subject: [PATCH] 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 --- src/components/atoms/Tooltip.tsx | 7 +- .../molecules/MarketStats.module.css | 36 +++- src/components/molecules/MarketStats.tsx | 182 +++++++++++++++--- .../UserPreferences/Networks/index.tsx | 2 +- src/utils/subgraph.ts | 2 +- 5 files changed, 189 insertions(+), 40 deletions(-) diff --git a/src/components/atoms/Tooltip.tsx b/src/components/atoms/Tooltip.tsx index afb2dc489..1719ff0a0 100644 --- a/src/components/atoms/Tooltip.tsx +++ b/src/components/atoms/Tooltip.tsx @@ -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({
{content} - {link && {reference}}
diff --git a/src/components/molecules/MarketStats.module.css b/src/components/molecules/MarketStats.module.css index 51f06eb70..fd872c98d 100644 --- a/src/components/molecules/MarketStats.module.css +++ b/src/components/molecules/MarketStats.module.css @@ -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); +} diff --git a/src/components/molecules/MarketStats.tsx b/src/components/molecules/MarketStats.tsx index f6ba2cd75..f669e1b39 100644 --- a/src/components/molecules/MarketStats.tsx +++ b/src/components/molecules/MarketStats.tsx @@ -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 ( + <> + {' '} + TVL across{' '} + {poolCount} asset pools that contain{' '} + , + plus datatokens for each pool. + + ) +} + +function MarketNetworkStatsTooltip({ + totalValueLocked, + poolCount, + totalOceanLiquidity, + mainChainIds +}: { + totalValueLocked: Value + poolCount: Value + totalOceanLiquidity: Value + mainChainIds: number[] +}): ReactElement { + return ( + <> +
    + {totalValueLocked && + totalOceanLiquidity && + poolCount && + mainChainIds?.map((chainId, key) => ( +
  • + +
    + {' '} + TVL + {' | '} + {poolCount[chainId] || '0'} pools + {' | '} + +
  • + ))} +
+

+ Counted on-chain from our pool factory. Does not filter out assets in{' '} + + list-purgatory + +

+ + ) +} + export default function MarketStats(): ReactElement { - const [totalValueLocked, setTotalValueLocked] = useState() - const [totalOceanLiquidity, setTotalOceanLiquidity] = useState() - const [poolCount, setPoolCount] = useState() - const [result] = useQuery({ - query: getTotalPoolsValues - // pollInterval: 20000 - }) - const { data } = result + const [totalValueLocked, setTotalValueLocked] = useState() + const [totalOceanLiquidity, setTotalOceanLiquidity] = useState() + const [poolCount, setPoolCount] = useState() + const [totalValueLockedSum, setTotalValueLockedSum] = useState() + const [totalOceanLiquiditySum, setTotalOceanLiquiditySum] = useState() + const [poolCountSum, setPoolCountSum] = useState() + const [mainChainIds, setMainChainIds] = useState() + 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 (
- {' '} - TVL across{' '} - {poolCount} data set pools that contain{' '} - , - plus datatokens for each pool. - + <> + {' '} + + } + /> +
) } diff --git a/src/components/molecules/UserPreferences/Networks/index.tsx b/src/components/molecules/UserPreferences/Networks/index.tsx index 388e63e8c..8910930d3 100644 --- a/src/components/molecules/UserPreferences/Networks/index.tsx +++ b/src/components/molecules/UserPreferences/Networks/index.tsx @@ -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 }[] diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index 6cc7b5355..41efbc1ce 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -150,7 +150,7 @@ export async function fetchData( query: TypedDocumentNode, variables: any, context: OperationContext -): Promise { +): Promise { try { const client = getUrqlClientInstance() const response = await client.query(query, variables, context).toPromise()