parent
b5b2dd8207
commit
d02dee86f6
@ -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> |
||||
} |
Loading…
Reference in new issue