Skip to content

Commit

Permalink
improved stats page design
Browse files Browse the repository at this point in the history
  • Loading branch information
Ncookiez committed Jul 10, 2024
1 parent 3ea0b51 commit b7cbcc2
Show file tree
Hide file tree
Showing 12 changed files with 324 additions and 251 deletions.
2 changes: 1 addition & 1 deletion apps/analytics/src/components/Charts/PPCOverTimeChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const PPCOverTimeChart = (props: PPCOverTimeChartProps) => {
<div
className={classNames('w-full flex flex-col gap-2 font-medium text-pt-purple-800', className)}
>
<span className='ml-2 text-pt-purple-200'>PPCs Over Time</span>
<span className='ml-2 text-pt-purple-100 font-bold'>PPCs Over Time</span>
{isReady ? (
<BarChart
data={chartData}
Expand Down
2 changes: 1 addition & 1 deletion apps/analytics/src/components/Charts/TVLByToken.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const TVLByTokenChart = (props: TVLByTokenChartProps) => {

return (
<div className={classNames('w-full flex flex-col font-medium text-pt-purple-800', className)}>
<span className='ml-2 text-pt-purple-200'>TVL By Token</span>
<span className='ml-2 text-pt-purple-100 font-bold'>TVL By Token</span>
{isReady ? (
<PieChart
data={chartData}
Expand Down
2 changes: 1 addition & 1 deletion apps/analytics/src/components/Charts/TVLOverTimeChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const TVLOverTimeChart = (props: TVLOverTimeChartProps) => {
<div
className={classNames('w-full flex flex-col gap-2 font-medium text-pt-purple-800', className)}
>
<span className='ml-2 text-pt-purple-200'>TVL Over Time</span>
<span className='ml-2 text-pt-purple-100 font-bold'>TVL Over Time</span>
{isReady ? (
<AreaChart
data={chartData}
Expand Down
16 changes: 16 additions & 0 deletions apps/analytics/src/components/Stats/CategoryHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import classNames from 'classnames'

interface CategoryHeaderProps {
name: string
className?: string
}

export const CategoryHeader = (props: CategoryHeaderProps) => {
const { name, className } = props

return (
<h2 className={classNames('text-center text-3xl text-pt-purple-100 font-bold', className)}>
{name}
</h2>
)
}
83 changes: 83 additions & 0 deletions apps/analytics/src/components/Stats/PrizeStats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { PrizePool } from '@generationsoftware/hyperstructure-client-js'
import {
usePrizeDrawWinners,
usePrizeTokenData
} from '@generationsoftware/hyperstructure-react-hooks'
import { formatNumberForDisplay } from '@shared/utilities'
import classNames from 'classnames'
import { useMemo } from 'react'
import { formatUnits } from 'viem'
import { CategoryHeader } from './CategoryHeader'
import { StatCards } from './StatCards'

interface PrizeStatsProps {
prizePool: PrizePool
className?: string
}

export const PrizeStats = (props: PrizeStatsProps) => {
const { prizePool, className } = props

const { data: prizeToken } = usePrizeTokenData(prizePool)

const { data: draws } = usePrizeDrawWinners(prizePool)

const totalPrizes = useMemo(() => {
if (!!draws && !!prizeToken) {
let numPrizes = 0
let numPrizesWithCanary = 0
let sumAmount = 0n

draws.forEach((draw) => {
draw.prizeClaims.forEach((claim) => {
numPrizesWithCanary++

if (!!claim.payout) {
numPrizes++
sumAmount += claim.payout
}
})
})

return {
num: numPrizes,
numWithCanary: numPrizesWithCanary,
amount: parseFloat(formatUnits(sumAmount, prizeToken.decimals))
}
}
}, [draws, prizeToken])

return (
<div className={classNames('w-full flex flex-col items-center gap-4', className)}>
<CategoryHeader name='Prizes' />
<StatCards
cards={[
{
id: 'totalNumPrizes',
title: 'Total Prizes Awarded',
value: totalPrizes !== undefined ? formatNumberForDisplay(totalPrizes.num) : undefined
},
{
id: 'totalPrizeAmount',
title: 'Total Amount Awarded',
value:
totalPrizes !== undefined
? formatNumberForDisplay(totalPrizes.amount, { maximumFractionDigits: 4 })
: undefined,
unit: prizeToken?.symbol
},
{
id: 'totalNumPrizesWithCanary',
title: 'Total Prizes Awarded',
subtitle: '(including canary)',
value:
totalPrizes !== undefined
? formatNumberForDisplay(totalPrizes.numWithCanary)
: undefined
}
]}
className='sm:grid-cols-2 md:grid-cols-3'
/>
</div>
)
}
132 changes: 0 additions & 132 deletions apps/analytics/src/components/Stats/PrizesCard.tsx

This file was deleted.

71 changes: 71 additions & 0 deletions apps/analytics/src/components/Stats/StatCards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Spinner } from '@shared/ui'
import classNames from 'classnames'

interface StatCardsProps {
cards: {
id: string
title: string
subtitle?: string
value?: string
unit?: string
className?: string
titleClassName?: string
subtitleClassName?: string
valueClassName?: string
unitClassName?: string
}[]
className?: string
}

export const StatCards = (props: StatCardsProps) => {
const { cards, className } = props

return (
<div
className={classNames('w-full grid gap-8 px-4 py-6 bg-pt-transparent rounded-2xl', className)}
>
{cards.map((card) => (
<StatCard key={`stat-card-${card.id}`} {...card} />
))}
</div>
)
}

const StatCard = (props: StatCardsProps['cards'][number]) => {
const {
title,
subtitle,
value,
unit,
className,
titleClassName,
subtitleClassName,
valueClassName,
unitClassName
} = props

return (
<div className={classNames('flex flex-col items-center gap-2', className)}>
<div className='flex flex-col items-center text-center text-sm text-pt-purple-100'>
<span className={classNames('font-bold', titleClassName)}>{title}</span>
<span className={classNames('h-5', subtitleClassName)}>{subtitle}</span>
</div>
<div className='w-full h-[4.25rem] flex items-center justify-center p-4 bg-pt-purple-300 rounded-lg'>
{value !== undefined ? (
<div className='flex items-end gap-1 font-bold'>
<span className={classNames('text-3xl text-pt-purple-700', valueClassName)}>
{value}
</span>
{!!unit && (
<span className={classNames('mt-auto text-xl text-pt-purple-500', unitClassName)}>
{unit}
</span>
)}
</div>
) : (
<Spinner />
)}
</div>
</div>
)
}
52 changes: 52 additions & 0 deletions apps/analytics/src/components/Stats/TVLStats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { PrizePool } from '@generationsoftware/hyperstructure-client-js'
import { formatNumberForDisplay } from '@shared/utilities'
import classNames from 'classnames'
import { TVLByTokenChart } from '@components/Charts/TVLByToken'
import { TVLOverTimeChart } from '@components/Charts/TVLOverTimeChart'
import { useDeposits } from '@hooks/useDeposits'
import { CategoryHeader } from './CategoryHeader'
import { StatCards } from './StatCards'

interface TVLStatsProps {
prizePool: PrizePool
className?: string
}

export const TVLStats = (props: TVLStatsProps) => {
const { prizePool, className } = props

const { data: deposits } = useDeposits(prizePool)

return (
<div className={classNames('w-full flex flex-col items-center gap-4', className)}>
<CategoryHeader name='Deposits' />
<div className='w-full grid grid-cols-1 gap-6 px-4 py-6 bg-pt-transparent rounded-2xl md:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]'>
<TVLOverTimeChart prizePool={prizePool} />
<TVLByTokenChart prizePool={prizePool} />
</div>
<StatCards
cards={[
{
id: 'medianDeposit',
title: 'Median Deposit Transaction',
value:
deposits !== undefined
? formatNumberForDisplay(deposits.medianValue, { maximumFractionDigits: 4 })
: undefined,
unit: 'ETH'
},
{
id: 'avgDeposit',
title: 'Average Deposit Transaction',
value:
deposits !== undefined
? formatNumberForDisplay(deposits.avgValue, { maximumFractionDigits: 4 })
: undefined,
unit: 'ETH'
}
]}
className='sm:grid-cols-2'
/>
</div>
)
}
Loading

0 comments on commit b7cbcc2

Please sign in to comment.