diff --git a/centrifuge-app/src/components/LiquidityTransactionsSection.tsx b/centrifuge-app/src/components/LiquidityTransactionsSection.tsx index 288f392b2..51e439371 100644 --- a/centrifuge-app/src/components/LiquidityTransactionsSection.tsx +++ b/centrifuge-app/src/components/LiquidityTransactionsSection.tsx @@ -1,21 +1,36 @@ import { CurrencyBalance, Pool } from '@centrifuge/centrifuge-js' -import { AnchorButton, IconDownload } from '@centrifuge/fabric' +import { AnchorButton, Box, IconDownload, Shelf, Stack, Text } from '@centrifuge/fabric' import * as React from 'react' -import { formatDate } from '../utils/date' +import styled from 'styled-components' +import { daysBetween, formatDate } from '../utils/date' import { formatBalance } from '../utils/formatting' import { getCSVDownloadUrl } from '../utils/getCSVDownloadUrl' import { useDailyPoolStates } from '../utils/usePools' import { Legend, LegendProps } from './Charts/Legend' import { StackedBarChart, StackedBarChartProps } from './Charts/StackedBarChart' +import { getRangeNumber } from './Charts/utils' import { PageSection } from './PageSection' import { TooltipsProps } from './Tooltips' +const rangeFilters = [ + { value: '30d', label: '30 days' }, + { value: '90d', label: '90 days' }, + { value: 'ytd', label: 'Year to date' }, + { value: 'all', label: 'All' }, +] as const + type DataKeyType = | 'sumBorrowedAmountByPeriod' | 'sumRepaidAmountByPeriod' | 'sumInvestedAmountByPeriod' | 'sumRedeemedAmountByPeriod' +const RangeFilterButton = styled(Stack)` + &:hover { + cursor: pointer; + } +` + type LiquidityTransactionsSectionProps = { pool: Pool title: string @@ -33,9 +48,10 @@ export default function LiquidityTransactionsSection({ dataColors, tooltips, }: LiquidityTransactionsSectionProps) { - const to = new Date(pool.epoch.lastClosed) - const from = pool.createdAt ? new Date(pool.createdAt) : new Date(to.getDate() - 10) - const { poolStates: dailyPoolStates } = useDailyPoolStates(pool.id, from, to) || {} + const { poolStates: dailyPoolStates } = useDailyPoolStates(pool.id) || {} + const [range, setRange] = React.useState<(typeof rangeFilters)[number]>({ value: 'all', label: 'All' }) + const poolAge = pool.createdAt ? daysBetween(pool.createdAt, new Date()) : 0 + const rangeNumber = getRangeNumber(range.value, poolAge) ?? 100 const dataUrl: any = React.useMemo(() => { if (!dailyPoolStates || !dailyPoolStates?.length) { @@ -62,27 +78,34 @@ export default function LiquidityTransactionsSection({ return getCSVDownloadUrl(formatted) }, [dailyPoolStates, dataKeys, dataNames, pool.currency.symbol]) - const chartData: StackedBarChartProps['data'] = React.useMemo(() => { - return ( - dailyPoolStates?.map((entry) => { + const chartData = React.useMemo(() => { + return (dailyPoolStates + ?.map((entry) => { // subquery data is saved at end of the day // data timestamp is off for 24h const date = new Date(entry.timestamp) date.setDate(date.getDate() - 1) + const top = entry[dataKeys[0]] + ? new CurrencyBalance(entry[dataKeys[0]]!, pool.currency.decimals).toDecimal().toNumber() + : 0 + const bottom = entry[dataKeys[1]] + ? new CurrencyBalance(entry[dataKeys[1]]!, pool.currency.decimals).toDecimal().toNumber() + : 0 + + if (!top && !bottom) { + return undefined + } return { xAxis: date.getTime(), - top: entry[dataKeys[0]] - ? new CurrencyBalance(entry[dataKeys[0]]!, pool.currency.decimals).toDecimal().toNumber() - : 0, - bottom: entry[dataKeys[1]] - ? new CurrencyBalance(entry[dataKeys[1]]!, pool.currency.decimals).toDecimal().toNumber() - : 0, + top, + bottom, date: date.toISOString(), } - }) || [] - ) - }, [dailyPoolStates, dataKeys]) + }) + .slice(-rangeNumber) + .filter(Boolean) || []) as StackedBarChartProps['data'] + }, [dailyPoolStates, dataKeys, rangeNumber]) const legend: LegendProps['data'] = React.useMemo(() => { const topTotal = chartData.map(({ top }) => top).reduce((a, b) => a + b, 0) @@ -123,12 +146,35 @@ export default function LiquidityTransactionsSection({ icon={IconDownload} small > - Data + Download ) } > - {!!legend && !!legend.length && } + + {!!legend && !!legend.length && } + + {chartData.length > 0 && + rangeFilters.map((rangeFilter, index) => ( + + setRange(rangeFilter)}> + + {rangeFilter.label} + + + + {index !== rangeFilters.length - 1 && ( + + )} + + ))} + + + {!!chartData && !!chartData.length && ( )}