Add top metrics page

pull/225/head
artemkolodko 2 years ago
parent b5b2dd8207
commit d02dee86f6
  1. 5
      src/Routes.tsx
  2. 18
      src/api/client.ts
  3. 9
      src/components/appHeader/ToolsButton.tsx
  4. 124
      src/pages/TopStatsPage/CommonTopTable.tsx
  5. 63
      src/pages/TopStatsPage/Transaction.tsx
  6. 26
      src/pages/TopStatsPage/index.tsx
  7. 17
      src/types/api.ts

@ -17,6 +17,7 @@ import { ApprovalPage } from "./pages/ApprovalPage";
import { CheckHRC } from "./pages/tools/CheckHRC";
import {VerifyProxyContract} from "./pages/VerifyProxyContract/VerifyProxyContract";
import { ChartsPage } from "./pages/ChartsPage";
import { TopStatsPage } from "./pages/TopStatsPage";
export function Routes() {
return (
@ -108,6 +109,10 @@ export function Routes() {
<Route path={'/'}><ChartsPage /></Route>
</Route>
<Route path="/topstat">
<Route path={'/'}><TopStatsPage /></Route>
</Route>
<Route path="*">
<Redirect to="/" />
</Route>

@ -1,12 +1,12 @@
import { transport } from "./explorer";
import {
Block,
InternalTransaction,
RPCStakingTransactionHarmony,
RPCTransactionHarmony,
RelatedTransaction,
Log, LogDetailed, AddressDetails,
ShardID, MetricsType, MetricsDailyItem
Block,
InternalTransaction,
RPCStakingTransactionHarmony,
RPCTransactionHarmony,
RelatedTransaction,
Log, LogDetailed, AddressDetails,
ShardID, MetricsType, MetricsDailyItem, MetricsTopType, MetricsTopItem
} from "src/types";
import {
IHoldersInfo,
@ -115,6 +115,10 @@ export function getMetricsByType(type: MetricsType, offset = 0, limit = 14) {
return transport("getMetricsByType", [type, offset, limit]) as Promise<MetricsDailyItem[]>;
}
export function getTopMetricsByType(type: MetricsTopType, period: 1 | 3 | 7, limit = 10) {
return transport("getTopMetricsByType", [type, period, limit]) as Promise<MetricsTopItem[]>;
}
export function getContractsByField(params: any[]) {
return transport("getContractsByField", params) as Promise<AddressDetails>;
}

@ -73,6 +73,15 @@ export function ToolsButton() {
<Text size={'xsmall'} color={'successText'}>(new)</Text>
</Box>
</Anchor>
<Anchor
style={{ textDecoration: "underline" }}
onClick={(e) => {
setIsOpen(false);
history.push("/topstat");
}}
>
Top Statistics
</Anchor>
</Box>
}
style={{

@ -0,0 +1,124 @@
import React from 'react'
import {Box, Text} from "grommet";
import {MetricsTopItem, MetricsTopType} from "../../types";
import styled from "styled-components";
import {Address} from "../../components/ui";
import {ReactComponent as HarmonyLogo} from '../../assets/Logo.svg';
export interface TopTableProps {
items: MetricsTopItem[]
title: string
columns: string[]
}
interface TopTableRowProps {
item: MetricsTopItem
}
const TableContainer = styled(Box)`
flex: 0 0 calc(50% - 16px);
margin-left: 8px;
margin-right: 8px;
@media (max-width: 1024px) {
flex: 0 0 calc(50% - 16px);
margin-bottom: 0.75rem;
}
@media (max-width: 768px) {
flex: 0 0 calc(100% - 16px);
margin-top: 0.75rem;
margin-bottom: 0.75rem;
}
`
const LogoWrapper = styled(Box)`
svg path {
fill: #00AEE9
}
`
const columnsWidth = ['5%', '65%', '15%', '10%']
const TopTableHeader = (props: { columns: string[] }) => {
const { columns } = props
return <Box
direction={'row'}
gap={'8px'}
pad={'8px'}
border={{ size: '2px', side: 'bottom' }}
style={{ fontWeight: 'bold' }}
>
<Box width={columnsWidth[0]}>
<Text size={'xsmall'}>{columns[0]}</Text>
</Box>
<Box width={columnsWidth[1]}>
<Text size={'xsmall'}>{columns[1]}</Text>
</Box>
<Box width={columnsWidth[2]}>
<Text size={'xsmall'}>{columns[2]}</Text>
</Box>
<Box width={columnsWidth[3]}>
<Text size={'xsmall'}>{columns[3]}</Text>
</Box>
</Box>
}
const TopTableRow = (props: TopTableRowProps) => {
const { item: { type, rank, address, value, share } } = props
const isOneTransfer = [MetricsTopType.topOneSender, MetricsTopType.topOneReceiver].includes(type)
const valueFormat = isOneTransfer
? Math.round(+value / Math.pow(10, 18))
: value
const valueFormatEn = Intl.NumberFormat('en-US', {
notation: "compact",
maximumFractionDigits: 2
}).format(+valueFormat)
const shareFormatEn = Intl.NumberFormat('en-US', {
notation: "compact",
maximumFractionDigits: 2
}).format(+share)
return <Box
direction={'row'}
gap={'8px'}
pad={'8px'}
border={{ size: '1px', side: 'bottom' }}
>
<Box width={columnsWidth[0]}>
<Text size={'small'}>{rank}</Text>
</Box>
<Box width={columnsWidth[1]}>
<Address address={address} hideCopyBtn={true} />
</Box>
<Box width={columnsWidth[2]} direction={'row'} align={'center'} gap={'6px'}>
{isOneTransfer && <LogoWrapper>
<HarmonyLogo width={'12px'} height={'12px'} />
</LogoWrapper> }
<Text size={'xsmall'}>{valueFormatEn}</Text>
</Box>
<Box width={columnsWidth[3]}>
<Text size={'xsmall'}>{shareFormatEn}%</Text>
</Box>
</Box>
}
export const TopTable = (props: TopTableProps) => {
return <TableContainer
border={{ size: '1px' }}
round={'8px'}
overflow={'hidden'}
>
<Box>
<Box pad={'8px'} border={{ size: '1px', side: 'bottom' }} background={'backgroundBackEmpty'}>
<Text>{props.title}</Text>
</Box>
<TopTableHeader columns={props.columns} />
{props.items.map(item => <TopTableRow key={item.address} item={item} />)}
</Box>
</TableContainer>
}

@ -0,0 +1,63 @@
import React, {useEffect, useState} from 'react'
import {Box} from "grommet";
import {TopTable} from "./CommonTopTable";
import {getTopMetricsByType} from "../../api/client";
import {MetricsTopItem, MetricsTopType} from "../../types";
enum PeriodOption {
d1 = 1,
d3 = 3,
d7 = 7
}
export const TransactionTopStats = () => {
const [period, setPeriod] = useState(PeriodOption.d1)
const [oneSenders, setOneSenders] = useState<MetricsTopItem[]>([])
const [oneReceivers, setOneReceivers] = useState<MetricsTopItem[]>([])
const [txsSenders, setTxsSenders] = useState<MetricsTopItem[]>([])
const [txsReceivers, setTxsReceivers] = useState<MetricsTopItem[]>([])
useEffect(() => {
const loadData = async () => {
const rowsOneSent = await getTopMetricsByType(MetricsTopType.topOneSender, 1)
const rowsOneReceive = await getTopMetricsByType(MetricsTopType.topOneReceiver, 1)
const rowsTxsSent = await getTopMetricsByType(MetricsTopType.topTxsCountSent, 1)
const rowsTxsReceived = await getTopMetricsByType(MetricsTopType.topTxsCountReceived, 1)
setOneSenders(rowsOneSent)
setOneReceivers(rowsOneReceive)
setTxsSenders(rowsTxsSent)
setTxsReceivers(rowsTxsReceived)
}
loadData()
}, [])
return <Box
wrap
direction={'row'}
pad={"small"}
justify={'center'}
align={'center'}
>
<TopTable
items={oneSenders}
title={'Top ONE Senders'}
columns={['Rank', 'Address', 'Total ONE', 'Share']}
/>
<TopTable
items={oneReceivers}
title={'Top ONE Receivers'}
columns={['Rank', 'Address', 'Total ONE', 'Share']}
/>
<TopTable
items={txsSenders}
title={'Top Txs Count Sent'}
columns={['Rank', 'Address', 'Total Txs', 'Share']}
/>
<TopTable
items={txsReceivers}
title={'Top Txs Count Received'}
columns={['Rank', 'Address', 'Total Txs', 'Share']}
/>
</Box>
}

@ -0,0 +1,26 @@
import React from 'react'
import {Box, Heading, Text} from "grommet";
import {BaseContainer, BasePage} from "../../components/ui";
import {TransactionTopStats} from "./Transaction";
export const TopStatsPage = () => {
return <BaseContainer pad={{ horizontal: "0" }}>
<Heading size="small" margin={{ bottom: "medium", top: "0" }}>
<Box direction={"row"}>Top Statistics</Box>
</Heading>
<BasePage pad={'0'} style={{overflow: 'inherit'}}>
<Box border={{ side: 'bottom' }} pad={"small"}>
<Text weight={'bold'}>Transactions</Text>
</Box>
<Box
wrap
direction={'row'}
pad={"small"}
justify={'start'}
align={'center'}
>
<TransactionTopStats />
</Box>
</BasePage>
</BaseContainer>
}

@ -57,3 +57,20 @@ export enum MetricsType {
averageFee = 'average_fee',
blockSize = 'block_size'
}
export enum MetricsTopType {
topOneSender = 'top_one_sender',
topOneReceiver = 'top_one_receiver',
topTxsCountSent = 'top_txs_count_sent',
topTxsCountReceived = 'top_txs_count_received',
}
export interface MetricsTopItem {
type: MetricsTopType
address: string
period: number
rank: number
share: number
value: string
updatedAt: string
}

Loading…
Cancel
Save