Skip to content
This repository has been archived by the owner on Oct 10, 2023. It is now read-only.

Display APY/APR depending on days #2477

Merged
merged 6 commits into from
Dec 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions src/renderer/components/pool/PoolCards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import { ZERO_ASSET_AMOUNT, ZERO_BN } from '../../const'
import { sequenceTRD } from '../../helpers/fpHelpers'
import { abbreviateNumber } from '../../helpers/numberHelper'
import { PoolDetailRD, PoolStatsDetailRD } from '../../services/midgard/types'
import { GetPoolsPeriodEnum } from '../../types/generated/midgard'
import { ErrorView } from '../shared/error'
import { Button } from '../uielements/button'
import { PoolsPeriodSelector } from '../uielements/pools/PoolsPeriodSelector'
import { PoolStatus } from '../uielements/poolStatus'
import * as Styled from './PoolCards.styles'
import * as H from './PoolDetails.helpers'
Expand All @@ -22,10 +24,20 @@ export type Props = {
reloadData: FP.Lazy<void>
priceSymbol: string
priceRatio: BigNumber
poolsPeriod: GetPoolsPeriodEnum
setPoolsPeriod: (v: GetPoolsPeriodEnum) => void
}

export const PoolCards: React.FC<Props> = (props) => {
const { poolStatsDetail: poolStatsDetailRD, priceSymbol, poolDetail: poolDetailRD, priceRatio, reloadData } = props
const {
poolStatsDetail: poolStatsDetailRD,
priceSymbol,
poolDetail: poolDetailRD,
priceRatio,
reloadData,
poolsPeriod,
setPoolsPeriod
} = props
const intl = useIntl()

const getFullValue = useCallback(
Expand Down Expand Up @@ -112,6 +124,7 @@ export const PoolCards: React.FC<Props> = (props) => {
<PoolStatus
isLoading={isLoading}
label={intl.formatMessage({ id: 'deposit.poolDetails.apy' })}
extraLabel={<PoolsPeriodSelector selectedValue={poolsPeriod} onChange={setPoolsPeriod} />}
displayValue={`${abbreviateNumber(apy.toNumber(), 2)} %`}
/>
</Styled.Col>
Expand All @@ -126,7 +139,7 @@ export const PoolCards: React.FC<Props> = (props) => {
</Styled.Col>
</Styled.Container>
),
[getFullValue, intl, priceSymbol]
[getFullValue, intl, poolsPeriod, priceSymbol, setPoolsPeriod]
)

return FP.pipe(
Expand Down
14 changes: 8 additions & 6 deletions src/renderer/components/pool/PoolDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as FP from 'fp-ts/lib/function'

import { Network } from '../../../shared/api/types'
import { PoolDetailRD, PoolStatsDetailRD } from '../../services/midgard/types'
import { GetPoolsStatusEnum } from '../../types/generated/midgard'
import { GetPoolsPeriodEnum, GetPoolsStatusEnum } from '../../types/generated/midgard'
import { PoolHistoryActions } from '../../views/pool/PoolHistoryView.types'
import { PoolCards } from './PoolCards'
import * as H from './PoolDetails.helpers'
Expand All @@ -26,7 +26,6 @@ export type Props = {
reloadPoolDetail: FP.Lazy<void>
priceRatio: BigNumber
priceSymbol: string
isLoading?: boolean
HistoryView: React.ComponentType<{
poolAsset: Asset
historyActions: PoolHistoryActions
Expand All @@ -37,6 +36,8 @@ export type Props = {
disablePoolActions: boolean
walletLocked: boolean
network: Network
poolsPeriod: GetPoolsPeriodEnum
setPoolsPeriod: (v: GetPoolsPeriodEnum) => void
}

export const PoolDetails: React.FC<Props> = ({
Expand All @@ -51,14 +52,15 @@ export const PoolDetails: React.FC<Props> = ({
reloadPoolDetail,
poolStatsDetail: poolStatsDetailRD,
reloadPoolStatsDetail,
isLoading,
HistoryView,
ChartView,
disableTradingPoolAction,
disableAllPoolActions,
disablePoolActions,
walletLocked,
network
network,
poolsPeriod,
setPoolsPeriod
}) => {
const renderTitle = useMemo(() => {
const price = FP.pipe(
Expand Down Expand Up @@ -87,7 +89,6 @@ export const PoolDetails: React.FC<Props> = ({
watch={watch}
unwatch={unwatch}
price={price}
isLoading={isLoading}
isAvailablePool={isAvailablePool}
/>
)
Expand All @@ -96,7 +97,6 @@ export const PoolDetails: React.FC<Props> = ({
disableAllPoolActions,
disablePoolActions,
disableTradingPoolAction,
isLoading,
network,
poolDetailRD,
priceRatio,
Expand All @@ -122,6 +122,8 @@ export const PoolDetails: React.FC<Props> = ({
poolDetail={poolDetailRD}
priceSymbol={priceSymbol}
reloadData={reloadPoolCardsData}
poolsPeriod={poolsPeriod}
setPoolsPeriod={setPoolsPeriod}
/>
</A.Col>
<A.Col xs={24} md={16}>
Expand Down
1 change: 0 additions & 1 deletion src/renderer/components/pool/PoolTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export type Props = {
watch: FP.Lazy<void>
unwatch: FP.Lazy<void>
price: RD.RemoteData<Error, { amount: AssetAmount; symbol: string }>
isLoading?: boolean
disableTradingPoolAction: boolean
disableAllPoolActions: boolean
disablePoolActions: boolean
Expand Down
41 changes: 30 additions & 11 deletions src/renderer/components/uielements/chart/PoolDetailsChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,6 @@ const Chart: React.FC<ChartProps> = (props): JSX.Element => {
return renderChart
}

// Definition for time range buttons
const TIME_RANGE_BUTTONS: Record<ChartTimeFrame, { labelId: string; tooltipId: string }> = {
week: { labelId: 'common.time.days7.short', tooltipId: 'common.time.days7' },
month: { labelId: 'common.time.month1.short', tooltipId: 'common.time.month1' },
threeMonths: { labelId: 'common.time.months3.short', tooltipId: 'common.time.months3' },
year: { labelId: 'common.time.year1.short', tooltipId: 'common.time.year1' },
all: { labelId: 'common.time.all.short', tooltipId: 'common.time.all' }
}
type Props = {
chartDetails: ChartDetailsRD
reloadData: FP.Lazy<void>
Expand Down Expand Up @@ -132,6 +124,33 @@ export const PoolDetailsChart: React.FC<Props> = (props: Props): JSX.Element =>
[intl, reloadData]
)

// Labels/toolTips of time range buttons
const timeRangeButtons: Record<ChartTimeFrame, { label: string; tooltip: string }> = useMemo(
() => ({
week: {
label: intl.formatMessage({ id: 'common.time.days.short' }, { days: '7' }),
tooltip: intl.formatMessage({ id: 'common.time.days' }, { days: '7' })
},
month: {
label: intl.formatMessage({ id: 'common.time.month1.short' }),
tooltip: intl.formatMessage({ id: 'common.time.month1' })
},
threeMonths: {
label: intl.formatMessage({ id: 'common.time.months3.short' }),
tooltip: intl.formatMessage({ id: 'common.time.months3' })
},
year: {
label: intl.formatMessage({ id: 'common.time.year1.short' }),
tooltip: intl.formatMessage({ id: 'common.time.year1' })
},
all: {
label: intl.formatMessage({ id: 'common.time.all.short' }),
tooltip: intl.formatMessage({ id: 'common.time.all' })
}
}),
[intl]
)

return (
<Styled.ChartContainer>
<Styled.HeaderContainer>
Expand All @@ -147,13 +166,13 @@ export const PoolDetailsChart: React.FC<Props> = (props: Props): JSX.Element =>
))}
</Styled.TypeContainer>
<Styled.TimeContainer>
{Object.entries(TIME_RANGE_BUTTONS).map(([key, { labelId, tooltipId }]) => (
<Tooltip title={intl.formatMessage({ id: tooltipId })} key={key}>
{Object.entries(timeRangeButtons).map(([key, { label, tooltip }]) => (
<Tooltip title={tooltip} key={key}>
<Styled.HeaderToggle
primary={selectedTimeFrame === key}
onClick={!isLoading ? () => setTimeFrame(key as ChartTimeFrame) : undefined}
disabled={isLoading}>
{intl.formatMessage({ id: labelId })}
{label}
</Styled.HeaderToggle>
</Tooltip>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export const Value = styled(Label).attrs({
weight: 'bold',
size: 'big'
})`
margin-top: 8px;
text-transform: uppercase;
overflow: hidden;
white-space: nowrap;
Expand Down
10 changes: 6 additions & 4 deletions src/renderer/components/uielements/poolStatus/PoolStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import * as Styled from './PoolStatus.styles'

export type Props = {
label: string
extraLabel?: React.ReactNode
displayValue: string
fullValue?: string
isLoading?: boolean
}

export const PoolStatus: React.FC<Props> = (props): JSX.Element => {
const { label, displayValue, fullValue, isLoading } = props
const { label, extraLabel = <></>, displayValue, fullValue, isLoading } = props
const [showTooltip, setShowTooltip] = useState(false)
const amountRef = useRef<HTMLDivElement>(null)
const containerRef = useRef<HTMLDivElement>(null)
Expand Down Expand Up @@ -45,9 +46,10 @@ export const PoolStatus: React.FC<Props> = (props): JSX.Element => {

return (
<Styled.PoolStatusWrapper ref={containerRef} {...props}>
<Styled.Title textTransform="uppercase" color="light">
{label}
</Styled.Title>
<div className="flex items-center">
<Styled.Title textTransform="uppercase">{label}</Styled.Title>
{extraLabel}
</div>
<Styled.Value loading={isLoading} ref={amountRef} className="amount">
<TooltipContainer>{displayValue}</TooltipContainer>
</Styled.Value>
Expand Down
143 changes: 143 additions & 0 deletions src/renderer/components/uielements/pools/PoolsPeriodSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React, { useMemo } from 'react'

import { Listbox } from '@headlessui/react'
import { CheckIcon, ChevronDownIcon } from '@heroicons/react/24/outline'
import * as A from 'fp-ts/lib/Array'
import * as FP from 'fp-ts/lib/function'
import * as O from 'fp-ts/lib/Option'
import { useIntl } from 'react-intl'

import { GetPoolsPeriodEnum } from '../../../types/generated/midgard'

type PeriodItem = { value: GetPoolsPeriodEnum; label: string }

const DEFAULT_ITEM: PeriodItem = { value: GetPoolsPeriodEnum._30d, label: '30 days' }

export type Props = {
selectedValue: GetPoolsPeriodEnum
onChange: (value: GetPoolsPeriodEnum) => void
className?: string
disabled?: boolean
}

export const PoolsPeriodSelector: React.FC<Props> = (props): JSX.Element => {
const { selectedValue, onChange, disabled = false, className = '' } = props

const intl = useIntl()

const defaultItem: PeriodItem = useMemo(
() => ({ value: GetPoolsPeriodEnum._30d, label: intl.formatMessage({ id: 'common.time.days' }, { days: '30' }) }),
[intl]
)

const listItems: PeriodItem[] = useMemo(
() => [
{ value: GetPoolsPeriodEnum._7d, label: intl.formatMessage({ id: 'common.time.days' }, { days: '7' }) },
defaultItem, // 30 days
{ value: GetPoolsPeriodEnum._90d, label: intl.formatMessage({ id: 'common.time.days' }, { days: '90' }) },
{ value: GetPoolsPeriodEnum._180d, label: intl.formatMessage({ id: 'common.time.days' }, { days: '180' }) },
{ value: GetPoolsPeriodEnum._365d, label: intl.formatMessage({ id: 'common.time.days' }, { days: '365' }) }
],
[defaultItem, intl]
)

const selectedItem: PeriodItem = FP.pipe(
listItems,
// get selected wallet
A.findFirst(({ value }) => value === selectedValue),
// use first if no wallet is selected
O.getOrElse(() => DEFAULT_ITEM)
)

return (
<Listbox
value={selectedItem}
disabled={disabled}
onChange={({ value }) => {
onChange(value)
}}>
<div
className={`relative ${className}`}
onClick={(event: React.MouseEvent<HTMLElement, MouseEvent>) => {
event.preventDefault()
event.stopPropagation()
}}>
<Listbox.Button
as="div"
className={() => `text-12
group
flex cursor-pointer
items-center
bg-bg0
py-5px
pl-20px
pr-10px font-main
text-text0
transition
duration-300
ease-in-out hover:shadow-full
hover:dark:shadow-fulld
${disabled && 'opacity-70'}
whitespace-nowrap
dark:bg-bg0d
dark:text-text0d
`}>
{({ open }) => (
<>
<span className="w-full">{selectedItem.label}</span>
<ChevronDownIcon
className={`
${open && 'rotate-180'}
ease
h-20px w-20px
group-hover:rotate-180

`}
/>
</>
)}
</Listbox.Button>
<Listbox.Options
className="
absolute z-[2000]
mt-[0px]
max-h-60 w-full overflow-auto
border
border-gray0 bg-bg0 focus:outline-none
dark:border-gray0d dark:bg-bg0d

">
{FP.pipe(
listItems,
A.map((item) => {
const selected = item.value === selectedItem.value
return (
<Listbox.Option
disabled={item.value === selectedItem.value}
className={({ selected }) =>
`flex w-full
select-none
justify-center whitespace-nowrap
py-[10px] pl-20px pr-10px
${selected && 'text-gray2 dark:text-gray2d'}
${selected ? 'cursor-disabled' : 'cursor-pointer'}
text-12 font-main
text-text0
dark:text-text0d
${!selected && 'hover:bg-gray0 hover:text-gray2'}
${!selected && 'hover:dark:bg-gray0d hover:dark:text-gray2d'}
`
}
key={item.value}
value={item}>
{item.label}
<CheckIcon className={`ml-5px h-20px w-20px text-turquoise ${selected ? 'visible' : 'invisible'}`} />
</Listbox.Option>
)
})
)}
</Listbox.Options>
</div>
</Listbox>
)
}
3 changes: 3 additions & 0 deletions src/renderer/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
} from '@xchainjs/xchain-util'

import { Network } from '../shared/api/types'
import { GetPoolsPeriodEnum } from './types/generated/midgard'
import { PricePoolCurrencyWeights, PricePoolAssets } from './views/pools/Pools.types'

//
Expand Down Expand Up @@ -206,3 +207,5 @@ export const SUPPORTED_LEDGER_APPS: Chain[] = [
ETHChain,
CosmosChain
]

export const DEFAULT_GET_POOLS_PERIOD = GetPoolsPeriodEnum._30d
4 changes: 2 additions & 2 deletions src/renderer/i18n/de/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ const common: CommonMessages = {
'common.details': 'Details',
'common.filter': 'Filter',
'common.all': 'Alle',
'common.time.days7': '7 Tage',
'common.time.days7.short': '7D',
'common.time.days': '{days} Tage',
'common.time.days.short': '{days}d',
'common.time.month1': '1 Monat',
'common.time.month1.short': '1M',
'common.time.months3': '3 Monate',
Expand Down
Loading