Skip to content

Commit

Permalink
refactor: pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
franciscotobar committed Nov 19, 2024
1 parent 9e785ac commit 9a542bf
Show file tree
Hide file tree
Showing 16 changed files with 275 additions and 77 deletions.
8 changes: 7 additions & 1 deletion src/app/collective-rewards/metrics/AllTimeRewardsMetrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,13 @@ type AllTimeRewardsProps = {
export const AllTimeRewardsMetrics: FC<AllTimeRewardsProps> = ({ gauges, tokens: { rif, rbtc } }) => {
return (
<MetricsCard borderless>
<MetricsCardTitle title="All time rewards" data-testid="AllTimeRewards" />
<MetricsCardTitle
title="All time rewards"
data-testid="AllTimeRewards"
tooltip={{
text: 'Total of Builders and Backers rewards paid/claimed/received',
}}
/>
<TokenRewardsMetrics gauges={gauges} token={rif} />
<TokenRewardsMetrics gauges={gauges} token={rbtc} />
</MetricsCard>
Expand Down
29 changes: 19 additions & 10 deletions src/app/collective-rewards/metrics/CycleMetrics.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { MetricsCard } from '@/components/MetricsCard'
import { useCycleContext } from '@/app/collective-rewards/metrics'
import { Duration, DateTime } from 'luxon'
import { useEffect, useState } from 'react'
import { MetricsCard, MetricsCardTitle, TokenMetricsCardRow } from '@/app/collective-rewards/rewards'
import { withSpinner } from '@/components/LoadingSpinner/withLoadingSpinner'
import { useHandleErrors } from '@/app/collective-rewards/utils'

let timeout: NodeJS.Timeout

export const CycleMetrics = () => {
const [timeRemaining, setTimeRemaining] = useState<Duration>(Duration.fromObject({ minutes: 0 }))
let {
data: { cycleDuration, cycleNext },
isLoading,
error,
} = useCycleContext()

useHandleErrors({ error, title: 'Error loading cycle metrics' })

const duration =
cycleDuration.as('days') < 1 ? cycleDuration.shiftTo('hours') : cycleDuration.shiftTo('days')

Expand All @@ -19,12 +25,10 @@ export const CycleMetrics = () => {
timeout = setTimeout(() => {
setTimeRemaining(state => state.minus({ minutes: 1 }))
}, 60000) // every minute
} else {
clearTimeout(timeout)
}

return () => clearTimeout(timeout)
}, [timeRemaining.minutes])
}, [timeRemaining])

useEffect(() => {
const now = DateTime.now()
Expand All @@ -38,11 +42,16 @@ export const CycleMetrics = () => {
}, [cycleNext])

return (
<MetricsCard
title="Current cycle"
amount={`${timeRemaining?.toHuman()}`}
fiatAmount={`out of ${duration.toHuman()}. Ends ${cycleNext.toFormat('EEE, dd MMM')}`}
borderless
/>
<MetricsCard borderless>
<MetricsCardTitle title="Current cycle" data-testid="CurrentCycle" />
{withSpinner(
TokenMetricsCardRow,
'min-h-0 grow-0',
)({
amount: `${timeRemaining.toHuman()}`,
fiatAmount: `out of ${duration.toHuman()}. Ends ${cycleNext.toFormat('EEE, dd MMM')}`,
isLoading,
})}
</MetricsCard>
)
}
1 change: 0 additions & 1 deletion src/app/collective-rewards/metrics/Metrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export const Metrics = () => {
<div className="flex gap-4 h-min w-3/4">
<CycleMetrics />
<TotalActiveBuildersMetrics />

<TotalAllocationsMetrics gauges={gauges} token={tokens.rif} />
</div>
<div className="w-1/4">
Expand Down
21 changes: 13 additions & 8 deletions src/app/collective-rewards/metrics/TotalActiveBuildersMetrics.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import { MetricsCardWithSpinner } from '@/components/MetricsCard/MetricsCard'
import { useGetGaugesLength } from '../user'
import { useGetGaugesLength } from '@/app/collective-rewards/user'
import { MetricsCard, MetricsCardTitle, TokenMetricsCardRow } from '@/app/collective-rewards/rewards'
import { withSpinner } from '@/components/LoadingSpinner/withLoadingSpinner'
import { useHandleErrors } from '@/app/collective-rewards/utils'

export const TotalActiveBuildersMetrics = () => {
const { data, isLoading, error } = useGetGaugesLength('active')
useHandleErrors({ error, title: 'Error loading active builders' })

return (
<MetricsCardWithSpinner
title="Total active builders"
amount={Number(data || 0n).toFixed()}
isLoading={isLoading}
borderless
/>
<MetricsCard borderless>
<MetricsCardTitle title="Total active builders" data-testid="TotalActiveBuilders" />
{withSpinner(
TokenMetricsCardRow,
'min-h-0 grow-0',
)({
amount: Number(data || 0n).toFixed(),
isLoading,
})}
</MetricsCard>
)
}
30 changes: 20 additions & 10 deletions src/app/collective-rewards/metrics/TotalAllocationsMetrics.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useGaugesGetFunction } from '@/app/collective-rewards/hooks'
import { Address } from 'viem'
import { useHandleErrors } from '@/app/collective-rewards/utils'
import { MetricsCardWithSpinner } from '@/components/MetricsCard/MetricsCard'
import { FC } from 'react'
import { usePricesContext } from '@/shared/context/PricesContext'
import { Token } from '@/app/collective-rewards/rewards'
import { formatCurrency } from '@/lib/utils'
import { formatBalanceToHuman } from '@/app/user/Balances/balanceUtils'
import { MetricsCard, MetricsCardTitle, TokenMetricsCardRow, Token } from '@/app/collective-rewards/rewards'
import { withSpinner } from '@/components/LoadingSpinner/withLoadingSpinner'
import { useHandleErrors } from '@/app/collective-rewards/utils'

type TotalAllocationsProps = {
gauges: Address[]
Expand All @@ -30,12 +30,22 @@ export const TotalAllocationsMetrics: FC<TotalAllocationsProps> = ({
const fiatAmount = `= ${currency} ${formatCurrency(totalAllocationsInHuman * price, currency)}`

return (
<MetricsCardWithSpinner
title="Total allocations"
amount={`${totalAllocationsInHuman} STRIF`}
fiatAmount={fiatAmount}
isLoading={isLoading}
borderless
/>
<MetricsCard borderless>
<MetricsCardTitle
title="Total allocations"
data-testid="TotalAllocations"
tooltip={{
text: 'Total stRIF allocation from Backers to Builders',
}}
/>
{withSpinner(
TokenMetricsCardRow,
'min-h-0 grow-0',
)({
amount: `${totalAllocationsInHuman} STRIF`,
fiatAmount,
isLoading,
})}
</MetricsCard>
)
}
41 changes: 30 additions & 11 deletions src/app/collective-rewards/metrics/context/CycleContext.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createContext, FC, ReactNode, useContext } from 'react'
import { createContext, FC, ReactNode, useContext, useEffect, useMemo, useState } from 'react'
import { DateTime, Duration } from 'luxon'
import {
useGetCycleNext,
Expand Down Expand Up @@ -32,37 +32,56 @@ type CycleProviderProps = {
}

export const CycleContextProvider: FC<CycleProviderProps> = ({ children }) => {
const timestamp = BigInt(DateTime.now().toUnixInteger())
const [timestamp, setTimestamp] = useState(BigInt(DateTime.now().toUnixInteger()))

useEffect(() => {
const interval = setInterval(() => {
setTimestamp(BigInt(DateTime.now().toUnixInteger()))
}, 30000) // Update every 30 seconds

return () => clearInterval(interval) // Cleanup interval on component unmount
}, [])

const {
data: cycleStartAndDuration,
isLoading: cycleStartAndDurationLoading,
error: cycleStartAndDurationError,
} = useGetCycleStartAndDuration()
const [fistCycleStart, cycleDuration] = cycleStartAndDuration || []

const [firstCycleStart, cycleDuration] = cycleStartAndDuration || []

const {
data: cycleStart,
isLoading: cycleStartLoading,
error: cycleStartError,
} = useGetCycleStart(timestamp)

const {
data: endDistributionWindow,
isLoading: endDistributionWindowLoading,
error: endDistributionWindowError,
} = useGetEndDistributionWindow(timestamp)

const { data: cycleNext, isLoading: cycleNextLoading, error: cycleNextError } = useGetCycleNext(timestamp)

const isLoading =
cycleStartAndDurationLoading || cycleStartLoading || endDistributionWindowLoading || cycleNextLoading
const error = cycleStartAndDurationError ?? cycleStartError ?? endDistributionWindowError ?? cycleNextError

const error = cycleStartAndDurationError || cycleStartError || endDistributionWindowError || cycleNextError

const data = useMemo(
() => ({
cycleStart: DateTime.fromSeconds(Number(cycleStart ?? BigInt(0))),
cycleNext: DateTime.fromSeconds(Number(cycleNext ?? BigInt(0))),
cycleDuration: Duration.fromObject({ seconds: Number(cycleDuration ?? BigInt(0)) }),
fistCycleStart: DateTime.fromSeconds(Number(firstCycleStart ?? BigInt(0))),
endDistributionWindow: DateTime.fromSeconds(Number(endDistributionWindow ?? BigInt(0))),
}),
[firstCycleStart, cycleDuration, cycleStart, endDistributionWindow, cycleNext],
)

const valueOfContext: CycleContextValue = {
data: {
cycleStart: DateTime.fromSeconds(Number(cycleStart ?? 0n)),
cycleNext: DateTime.fromSeconds(Number(cycleNext ?? 0n)),
cycleDuration: Duration.fromObject({ seconds: Number(cycleDuration ?? 0n) }),
fistCycleStart: DateTime.fromSeconds(Number(fistCycleStart ?? 0n)),
endDistributionWindow: DateTime.fromSeconds(Number(endDistributionWindow ?? 0n)),
},
data,
isLoading,
error,
}
Expand Down
22 changes: 14 additions & 8 deletions src/app/collective-rewards/metrics/hooks/useGetCycleNext.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { CycleTimeKeeperAbi } from '@/lib/abis/v2/CycleTimeKeeperAbi'
import { BackersManagerAddress } from '@/lib/contracts'
import { useReadContract } from 'wagmi'
import { AVERAGE_BLOCKTIME } from '@/lib/constants'
import { useQuery } from '@tanstack/react-query'
import { readContract } from 'wagmi/actions'
import { config } from '@/config'

export const useGetCycleNext = (timestamp: bigint) => {
const { data, isLoading, error } = useReadContract({
address: BackersManagerAddress,
abi: CycleTimeKeeperAbi,
functionName: 'cycleNext',
args: [timestamp],
query: {
refetchInterval: AVERAGE_BLOCKTIME,
const { data, isLoading, error } = useQuery({
queryFn: async () => {
return readContract(config, {
address: BackersManagerAddress,
abi: CycleTimeKeeperAbi,
functionName: 'cycleNext',
args: [timestamp],
})
},
queryKey: ['cycleNext'],
refetchInterval: AVERAGE_BLOCKTIME,
initialData: 0n,
})

return {
Expand Down
22 changes: 14 additions & 8 deletions src/app/collective-rewards/metrics/hooks/useGetCycleStart.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { CycleTimeKeeperAbi } from '@/lib/abis/v2/CycleTimeKeeperAbi'
import { BackersManagerAddress } from '@/lib/contracts'
import { useReadContract } from 'wagmi'
import { AVERAGE_BLOCKTIME } from '@/lib/constants'
import { useQuery } from '@tanstack/react-query'
import { readContract } from 'wagmi/actions'
import { config } from '@/config'

export const useGetCycleStart = (timestamp: bigint) => {
const { data, isLoading, error } = useReadContract({
address: BackersManagerAddress,
abi: CycleTimeKeeperAbi,
functionName: 'cycleStart',
args: [timestamp],
query: {
refetchInterval: AVERAGE_BLOCKTIME,
const { data, isLoading, error } = useQuery({
queryFn: async () => {
return readContract(config, {
address: BackersManagerAddress,
abi: CycleTimeKeeperAbi,
functionName: 'cycleStart',
args: [timestamp],
})
},
queryKey: ['cycleStart'],
refetchInterval: AVERAGE_BLOCKTIME,
initialData: 0n,
})

return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { CycleTimeKeeperAbi } from '@/lib/abis/v2/CycleTimeKeeperAbi'
import { BackersManagerAddress } from '@/lib/contracts'
import { useReadContract } from 'wagmi'
import { AVERAGE_BLOCKTIME } from '@/lib/constants'
import { useQuery } from '@tanstack/react-query'
import { readContract } from 'wagmi/actions'
import { config } from '@/config'

export const useGetEndDistributionWindow = (timestamp: bigint) => {
const { data, isLoading, error } = useReadContract({
address: BackersManagerAddress,
abi: CycleTimeKeeperAbi,
functionName: 'endDistributionWindow',
args: [timestamp],
query: {
refetchInterval: AVERAGE_BLOCKTIME,
const { data, isLoading, error } = useQuery({
queryFn: async () => {
return readContract(config, {
address: BackersManagerAddress,
abi: CycleTimeKeeperAbi,
functionName: 'endDistributionWindow',
args: [timestamp],
})
},
queryKey: ['endDistributionWindow'],
refetchInterval: AVERAGE_BLOCKTIME,
initialData: 0n,
})

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const ClaimYourRewardsButton: FC<Pick<ButtonProps, 'onClick' | 'disabled'
<Popover
content={
<div className="text-[12px] font-bold mb-1">
<p data-testid="builderAddressTooltip">Claim your rewards</p>
<p data-testid="claimYouRewardsButtonTooltip">Claim your rewards</p>
</div>
}
size="small"
Expand Down
27 changes: 19 additions & 8 deletions src/app/collective-rewards/rewards/components/MetricsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FC, HTMLAttributes, ReactNode } from 'react'
import { Address } from 'viem'
import { withSpinner } from '@/components/LoadingSpinner/withLoadingSpinner'
import { Typography } from '@/components/Typography'
import { Tooltip, TooltipProps } from './Tooltip'

type MetricsCardRow = {
amount: string
Expand Down Expand Up @@ -81,17 +82,27 @@ export const MetricsCard: FC<MetricsCardProps> = ({
)
}

export const MetricsCardTitle: FC<{ title: string; 'data-testid': string }> = ({
type MetricsCardTitleProps = {
title: string
'data-testid': string
tooltip?: TooltipProps
}

export const MetricsCardTitle: FC<MetricsCardTitleProps> = ({
title,
'data-testid': dataTestId,
tooltip,
}) => (
<Typography
tagVariant="label"
className="text-[16px] font-normal tracking-wide overflow-hidden whitespace-nowrap text-ellipsis"
data-testid={`${dataTestId}_MetricsCardTitle`}
>
{title}
</Typography>
<div className="flex gap-1">
<Typography
tagVariant="label"
className="text-[16px] font-normal tracking-wide overflow-hidden whitespace-nowrap text-ellipsis"
data-testid={`${dataTestId}_MetricsCardTitle`}
>
{title}
</Typography>
{tooltip && <Tooltip {...tooltip} />}
</div>
)

type MetricsCardContentProps = {
Expand Down
Loading

0 comments on commit 9a542bf

Please sign in to comment.