This repository has been archived by the owner on Feb 2, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
487 additions
and
97 deletions.
There are no files selected for viewing
178 changes: 178 additions & 0 deletions
178
src/apps/explorer/components/SummaryCardsWidget/SummaryCards.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
import React from 'react' | ||
import styled, { css } from 'styled-components' | ||
import { media } from 'theme/styles/media' | ||
import { formatDistanceToNowStrict } from 'date-fns' | ||
|
||
import { Card, CardContent } from 'components/common/Card' | ||
import { CardRow } from 'components/common/CardRow' | ||
import { TotalSummaryResponse } from '.' | ||
import { abbreviateString } from 'utils' | ||
import { useMediaBreakpoint } from 'hooks/useMediaBreakPoint' | ||
import { CopyButton } from 'components/common/CopyButton' | ||
import { LinkWithPrefixNetwork } from 'components/common/LinkWithPrefixNetwork' | ||
|
||
const BatchInfoHeight = '19.6rem' | ||
const DESKTOP_TEXT_SIZE = 1.8 // rem | ||
const MOBILE_TEXT_SIZE = 1.65 // rem | ||
|
||
const WrapperCardRow = styled(CardRow)` | ||
max-width: 70%; | ||
${media.mobile} { | ||
max-width: 100%; | ||
} | ||
` | ||
|
||
const DoubleContentSize = css` | ||
min-height: ${BatchInfoHeight}; | ||
` | ||
const WrapperColumn = styled.div` | ||
/* Equivalent to use lg={8} MUI grid system */ | ||
flex-grow: 0; | ||
max-width: 66.666667%; | ||
flex-basis: 66.666667%; | ||
padding-right: 2rem; | ||
> div { | ||
margin: 1rem; | ||
max-height: ${BatchInfoHeight}; | ||
} | ||
${media.mediumDownMd} { | ||
flex-grow: 0; | ||
max-width: 100%; | ||
flex-basis: 100%; | ||
} | ||
` | ||
const DoubleCardStyle = css` | ||
${DoubleContentSize} | ||
${media.mediumDownMd} { | ||
min-height: 16rem; | ||
} | ||
` | ||
const WrappedDoubleCard = styled(Card)` | ||
${DoubleCardStyle} | ||
` | ||
|
||
const CardTransactions = styled(Card)` | ||
${media.mediumDownMd} { | ||
${DoubleCardStyle} | ||
} | ||
` | ||
|
||
const WrapperDoubleContent = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 3rem; | ||
${media.mediumDownMd} { | ||
gap: 2rem; | ||
} | ||
` | ||
|
||
interface SummaryCardsProps { | ||
summaryData: TotalSummaryResponse | undefined | ||
children: React.ReactNode | ||
} | ||
|
||
function calcDiff(a: number, b: number): number { | ||
return (a - b === 0 ? 0 : (100 * (a - b)) / b) || 0 | ||
} | ||
|
||
function getColorBySign(n: number): string { | ||
if (n > 0) { | ||
return 'green' | ||
} else if (n < 0) { | ||
return 'red1' | ||
} | ||
|
||
return 'grey' | ||
} | ||
|
||
export function SummaryCards({ summaryData, children }: SummaryCardsProps): JSX.Element { | ||
const { batchInfo, dailyTransactions, totalTokens, dailyFees, isLoading } = summaryData || {} | ||
const isDesktop = useMediaBreakpoint(['xl', 'lg']) | ||
const valueTextSize = isDesktop ? DESKTOP_TEXT_SIZE : MOBILE_TEXT_SIZE | ||
const rowsByCard = isDesktop ? '2row' : '3row' | ||
const diffTransactions = (dailyTransactions && calcDiff(dailyTransactions.now, dailyTransactions.before)) || 0 | ||
const diffFees = (dailyFees && calcDiff(dailyFees.now, dailyFees.before)) || 0 | ||
|
||
return ( | ||
<WrapperCardRow> | ||
<> | ||
<WrapperColumn>{children}</WrapperColumn> | ||
<WrappedDoubleCard xs={6} lg={4}> | ||
<WrapperDoubleContent> | ||
<CardContent | ||
variant="3row" | ||
label1="Last Batch" | ||
value1={batchInfo && formatDistanceToNowStrict(batchInfo.lastBatchDate)} | ||
loading={isLoading} | ||
valueSize={valueTextSize} | ||
/> | ||
<CardContent | ||
variant={rowsByCard} | ||
label1="Batch ID" | ||
value1={ | ||
batchInfo && ( | ||
<> | ||
<LinkWithPrefixNetwork to={`/tx/${batchInfo.batchId}`}> | ||
{abbreviateString(batchInfo?.batchId, 6, 4)} | ||
</LinkWithPrefixNetwork> | ||
<CopyButton heightIcon={1.35} text={batchInfo?.batchId || ''} /> | ||
</> | ||
) | ||
} | ||
loading={isLoading} | ||
valueSize={valueTextSize} | ||
/> | ||
</WrapperDoubleContent> | ||
</WrappedDoubleCard> | ||
<CardTransactions xs={6} lg={4}> | ||
<CardContent | ||
variant={rowsByCard} | ||
label1="24h Transactions" | ||
value1={dailyTransactions?.now} | ||
caption1={`${diffTransactions.toFixed(2)}%`} | ||
captionColor={getColorBySign(diffTransactions)} | ||
loading={isLoading} | ||
valueSize={valueTextSize} | ||
/> | ||
</CardTransactions> | ||
<Card xs={6} lg={4}> | ||
<CardContent | ||
variant="2row" | ||
label1="Total Tokens" | ||
value1={totalTokens} | ||
loading={isLoading} | ||
valueSize={valueTextSize} | ||
/> | ||
</Card> | ||
<Card xs={6} lg={4}> | ||
<CardContent | ||
variant={rowsByCard} | ||
label1="24h Fees" | ||
value1={`$${dailyFees?.now.toFixed(2)}`} | ||
caption1={`${diffFees.toFixed(2)}%`} | ||
captionColor={getColorBySign(diffFees)} | ||
loading={isLoading} | ||
valueSize={valueTextSize} | ||
/> | ||
</Card> | ||
{/** Surplus is not yet available */} | ||
{/* <Card> | ||
<CardContent | ||
variant="2row" | ||
label1="30d Surplus" | ||
value1={monthSurplus.now} | ||
caption1={monthSurplus.before} | ||
captionColor="green" | ||
loading={isLoading} | ||
valueSize={valueTextSize} | ||
/> | ||
</Card> */} | ||
</> | ||
</WrapperCardRow> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import React, { useEffect, useState } from 'react' | ||
import styled from 'styled-components' | ||
import { SummaryCards } from './SummaryCards' | ||
|
||
import summaryData from './summaryGraphResp.json' | ||
|
||
const DELAY_SECONDS = 3 // Emulating API request | ||
|
||
export interface BatchInfo { | ||
lastBatchDate: Date | ||
batchId: string | ||
} | ||
|
||
interface PastAndPresentValue { | ||
now: number | ||
before: number | ||
} | ||
|
||
interface TotalSummary { | ||
batchInfo?: BatchInfo | ||
dailyTransactions?: PastAndPresentValue | ||
totalTokens?: number | ||
dailyFees?: PastAndPresentValue | ||
} | ||
|
||
type RawTotalSummary = Omit<TotalSummary, 'batchInfo'> & { | ||
batchInfo: { lastBatchDate: number; batchId: string } | ||
} | ||
|
||
function buildSummary(data: RawTotalSummary): TotalSummary { | ||
return { | ||
...data, | ||
batchInfo: { | ||
...data.batchInfo, | ||
lastBatchDate: new Date(data.batchInfo.lastBatchDate * 1000), | ||
}, | ||
} | ||
} | ||
|
||
export type TotalSummaryResponse = TotalSummary & { | ||
isLoading: boolean | ||
} | ||
|
||
function useGetTotalSummary(): TotalSummaryResponse | undefined { | ||
const [summary, setSummary] = useState<TotalSummaryResponse | undefined>() | ||
|
||
useEffect(() => { | ||
setSummary((prevState) => { | ||
return { ...prevState, isLoading: true } | ||
}) | ||
const timer = setTimeout(() => setSummary({ ...buildSummary(summaryData), isLoading: false }), DELAY_SECONDS * 1000) | ||
|
||
return (): void => clearTimeout(timer) | ||
}, []) | ||
|
||
return summary | ||
} | ||
|
||
const Wrapper = styled.div` | ||
display: flex; | ||
flex: 1; | ||
justify-content: center; | ||
` | ||
const VolumeChart = styled.div` | ||
background: #28f3282c; | ||
border-radius: 0.4rem; | ||
height: 19.6rem; | ||
width: 100%; | ||
` | ||
|
||
export function StatsSummaryCardsWidget(): JSX.Element { | ||
const summary = useGetTotalSummary() | ||
|
||
return ( | ||
<Wrapper> | ||
<SummaryCards summaryData={summary}> | ||
<VolumeChart /> | ||
</SummaryCards> | ||
</Wrapper> | ||
) | ||
} |
6 changes: 6 additions & 0 deletions
6
src/apps/explorer/components/SummaryCardsWidget/summaryGraphResp.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"batchInfo": { "lastBatchDate": 1649881035, "batchId": "0x0003723b9eb1598e12d15c69206bf13c971be0310fa5744cf9601ed79f89e29c" }, | ||
"dailyTransactions": {"now": 612, "before": 912}, | ||
"totalTokens": 193, | ||
"dailyFees": {"now": 55225.61205047748511254485049406426, "before": 40361.20651840192742698089787142249} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import styled, { keyframes } from 'styled-components' | ||
|
||
const ShimmerKeyframe = keyframes` | ||
0% { | ||
background-position: 0px top; | ||
} | ||
90% { | ||
background-position: 300px top; | ||
} | ||
100% { | ||
background-position: 300px top; | ||
} | ||
` | ||
|
||
const ShimmerBar = styled.div` | ||
width: 100%; | ||
height: 12px; | ||
border-radius: 2px; | ||
color: white; | ||
background: ${({ theme }): string => | ||
`${theme.greyOpacity} -webkit-gradient(linear, 100% 0, 0 0, from(${theme.greyOpacity}), color-stop(0.5, ${theme.borderPrimary}), to(${theme.gradient1}))`}; | ||
background-position: -5rem top; | ||
background-repeat: no-repeat; | ||
-webkit-animation-name: ${ShimmerKeyframe}; | ||
-webkit-animation-duration: 1.3s; | ||
-webkit-animation-iteration-count: infinite; | ||
-webkit-background-size: 5rem 100%; | ||
` | ||
|
||
export default ShimmerBar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.