diff --git a/src/app/earn/components/chart-tabs.tsx b/src/app/earn/components/chart-tabs.tsx index 53608878a..caa5e60bd 100644 --- a/src/app/earn/components/chart-tabs.tsx +++ b/src/app/earn/components/chart-tabs.tsx @@ -7,7 +7,8 @@ import { cn } from '@/lib/utils/tailwind' type Tab = { name: ChartTab; label: string } const tabs: Tab[] = [ - { name: 'price', label: 'Token Price' }, + // { name: 'apy', label: 'APY' }, + { name: 'price', label: 'NAV' }, { name: 'tvl', label: 'TVL' }, ] diff --git a/src/app/earn/page.tsx b/src/app/earn/page.tsx index a03f621c2..9874a9816 100644 --- a/src/app/earn/page.tsx +++ b/src/app/earn/page.tsx @@ -6,6 +6,7 @@ import { ChartTabs } from '@/app/earn/components/chart-tabs' import { FaqSection } from '@/app/earn/components/faq-section' import { useEarnContext } from '@/app/earn/provider' import { ChartTab } from '@/app/earn/types' +import { ApyChart } from '@/components/charts/apy-chart' import { PriceChart } from '@/components/charts/price-chart' import { TvlChart } from '@/components/charts/tvl-chart' @@ -13,7 +14,7 @@ import { EarnWidget } from './components/earn-widget' import { QuickStats } from './components/quick-stats' export default function Page() { - const { indexToken, isFetchingStats, nav, tvl } = useEarnContext() + const { indexToken, isFetchingStats, apy, nav, tvl } = useEarnContext() const [currentTab, setCurrentTab] = useState('price') return ( @@ -31,6 +32,13 @@ export default function Page() { nav={nav} /> )} + {currentTab === 'apy' && ( + + )} {currentTab === 'tvl' && ( +
+
+ {formatPercentage(apy)} +
+ +
+
+ +
+
+ +
+ + ) +} diff --git a/src/components/charts/apy-xy-chart.tsx b/src/components/charts/apy-xy-chart.tsx new file mode 100644 index 000000000..6c8362e64 --- /dev/null +++ b/src/components/charts/apy-xy-chart.tsx @@ -0,0 +1,110 @@ +import { withParentSize } from '@visx/responsive' +import { + AnimatedAreaSeries, + AnimatedLineSeries, + Axis, + Tooltip, + XYChart, +} from '@visx/xychart' +import dayjs from 'dayjs' +import { useMemo } from 'react' + +import { formatPercentage } from '@/app/products/utils/formatters' +import { ChartTooltip } from '@/components/charts/chart-tooltip' +import { LinearGradientFill } from '@/components/charts/linear-gradient-fill' +import { darkTheme, lightTheme } from '@/components/charts/themes' +import { ChartPeriod } from '@/components/charts/types' +import { tooltipTimestampFormat } from '@/constants/charts' +import { IndexData } from '@/lib/utils/api/index-data-provider' + +type ApyChartIndexData = Pick + +type Props = { + data: ApyChartIndexData[] + isDark?: boolean + parentWidth: number + parentHeight: number + selectedPeriod: ChartPeriod +} + +function TvlXYChart({ + data, + isDark = false, + parentWidth, + parentHeight, + selectedPeriod, +}: Props) { + const { minDomainY, maxDomainY } = useMemo(() => { + const apys = data.map(({ APY }) => APY!) + const minApy = Math.min(...apys) + const maxApy = Math.max(...apys) + const diff = maxApy - minApy + return { + minDomainY: minApy - diff * 0.05, + maxDomainY: maxApy + diff * 0.05, + } + }, [data]) + + const seriesAccessors = { + xAccessor: (d: ApyChartIndexData) => new Date(d.CreatedTimestamp), + yAccessor: (d: ApyChartIndexData) => d.APY, + } + + const tooltipAccessors = { + xAccessor: (d: ApyChartIndexData) => + dayjs(d.CreatedTimestamp).format(tooltipTimestampFormat[selectedPeriod]), + yAccessor: (d: ApyChartIndexData) => formatPercentage(d.APY), + } + + if (parentHeight === 0 || parentWidth === 0) return null + + return ( + + formatPercentage(d)} + /> + + + + + ( + + )} + /> + + ) +} + +export default withParentSize(TvlXYChart) diff --git a/src/components/charts/period-selector.tsx b/src/components/charts/period-selector.tsx index d7416b754..354a42359 100644 --- a/src/components/charts/period-selector.tsx +++ b/src/components/charts/period-selector.tsx @@ -4,7 +4,7 @@ import { ChartPeriod } from '@/components/charts/types' import { useAnalytics } from '@/lib/hooks/use-analytics' import { cn } from '@/lib/utils/tailwind' -const periods = [ +const defaultPeriods = [ ChartPeriod.Hour, ChartPeriod.Day, ChartPeriod.Week, @@ -13,11 +13,16 @@ const periods = [ ] type Props = { + periods?: ChartPeriod[] selectedPeriod: ChartPeriod setSelectedPeriod: Dispatch> } -export function PeriodSelector({ selectedPeriod, setSelectedPeriod }: Props) { +export function PeriodSelector({ + periods = defaultPeriods, + selectedPeriod, + setSelectedPeriod, +}: Props) { const { logEvent } = useAnalytics() const handleClick = (period: ChartPeriod) => { diff --git a/src/components/charts/price-xy-chart.tsx b/src/components/charts/price-xy-chart.tsx index 5c4c9b8f1..f917af24e 100644 --- a/src/components/charts/price-xy-chart.tsx +++ b/src/components/charts/price-xy-chart.tsx @@ -13,6 +13,7 @@ import { ChartTooltip } from '@/components/charts/chart-tooltip' import { LinearGradientFill } from '@/components/charts/linear-gradient-fill' import { darkTheme, lightTheme } from '@/components/charts/themes' import { ChartPeriod } from '@/components/charts/types' +import { tooltipTimestampFormat } from '@/constants/charts' import { formatDollarAmount } from '@/lib/utils' import { IndexData } from '@/lib/utils/api/index-data-provider' @@ -27,14 +28,6 @@ type Props = { selectedPeriod: ChartPeriod } -const tooltipTimestampFormatByPeriod: { [k in ChartPeriod]: string } = { - [ChartPeriod.Hour]: 'DD MMM YYYY HH:mm', - [ChartPeriod.Day]: 'DD MMM YYYY HH:mm', - [ChartPeriod.Week]: 'DD MMM YYYY HH:mm', - [ChartPeriod.Month]: 'DD MMM YYYY HH:mm', - [ChartPeriod.Year]: 'DD MMM YYYY', -} - function PriceXYChart({ data, digits = 2, @@ -61,9 +54,7 @@ function PriceXYChart({ const tooltipAccessors = { xAccessor: (d: PriceChartIndexData) => - dayjs(d.CreatedTimestamp).format( - tooltipTimestampFormatByPeriod[selectedPeriod], - ), + dayjs(d.CreatedTimestamp).format(tooltipTimestampFormat[selectedPeriod]), yAccessor: (d: PriceChartIndexData) => formatDollarAmount(d.NetAssetValue, undefined, digits), } diff --git a/src/components/charts/tvl-xy-chart.tsx b/src/components/charts/tvl-xy-chart.tsx index 97c68c4a3..faa452bd6 100644 --- a/src/components/charts/tvl-xy-chart.tsx +++ b/src/components/charts/tvl-xy-chart.tsx @@ -14,6 +14,7 @@ import { ChartTooltip } from '@/components/charts/chart-tooltip' import { LinearGradientFill } from '@/components/charts/linear-gradient-fill' import { darkTheme, lightTheme } from '@/components/charts/themes' import { ChartPeriod } from '@/components/charts/types' +import { tooltipTimestampFormat } from '@/constants/charts' import { IndexData } from '@/lib/utils/api/index-data-provider' type TvlChartIndexData = Pick< @@ -29,14 +30,6 @@ type Props = { selectedPeriod: ChartPeriod } -const tooltipTimestampFormatByPeriod: { [k in ChartPeriod]: string } = { - [ChartPeriod.Hour]: 'DD MMM YYYY HH:mm', - [ChartPeriod.Day]: 'DD MMM YYYY HH:mm', - [ChartPeriod.Week]: 'DD MMM YYYY HH:mm', - [ChartPeriod.Month]: 'DD MMM YYYY HH:mm', - [ChartPeriod.Year]: 'DD MMM YYYY', -} - function TvlXYChart({ data, isDark = false, @@ -62,9 +55,7 @@ function TvlXYChart({ const tooltipAccessors = { xAccessor: (d: TvlChartIndexData) => - dayjs(d.CreatedTimestamp).format( - tooltipTimestampFormatByPeriod[selectedPeriod], - ), + dayjs(d.CreatedTimestamp).format(tooltipTimestampFormat[selectedPeriod]), yAccessor: (d: TvlChartIndexData) => formatTvl(d.ProductAssetValue), } diff --git a/src/components/charts/use-chart-data.ts b/src/components/charts/use-chart-data.ts index 14d67d582..611538ca5 100644 --- a/src/components/charts/use-chart-data.ts +++ b/src/components/charts/use-chart-data.ts @@ -76,6 +76,13 @@ function formatData( })) } + if (metric === 'apy') { + return data.map((datum) => ({ + ...datum, + APY: Number(datum.APY?.toFixed(4)), + })) + } + return [] } @@ -83,7 +90,9 @@ export function useChartData( indexTokenAddress?: string, metric: IndexDataMetric = 'nav', ) { - const [selectedPeriod, setSelectedPeriod] = useState(ChartPeriod.Day) + const [selectedPeriod, setSelectedPeriod] = useState( + metric === 'apy' ? ChartPeriod.Week : ChartPeriod.Day, + ) const [historicalData, setHistoricalData] = useState([]) useQuery({ enabled: isAddress(indexTokenAddress ?? ''), diff --git a/src/constants/charts.ts b/src/constants/charts.ts new file mode 100644 index 000000000..4d7e9fa66 --- /dev/null +++ b/src/constants/charts.ts @@ -0,0 +1,9 @@ +import { ChartPeriod } from '@/components/charts/types' + +export const tooltipTimestampFormat: { [k in ChartPeriod]: string } = { + [ChartPeriod.Hour]: 'DD MMM YYYY HH:mm', + [ChartPeriod.Day]: 'DD MMM YYYY HH:mm', + [ChartPeriod.Week]: 'DD MMM YYYY HH:mm', + [ChartPeriod.Month]: 'DD MMM YYYY HH:mm', + [ChartPeriod.Year]: 'DD MMM YYYY', +}