import { useEffect, useMemo, useState } from 'react' import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, Text, } from 'recharts' import FlipNumbers from 'react-flip-numbers' import LineChartIcon from '../icons/LineChartIcon' import ContentBox from '../shared/ContentBox' import { formatFixedDecimals } from '../../utils/numbers' import SheenLoader from '../shared/SheenLoader' import { COLORS } from '../../styles/colors' import { useTheme } from 'next-themes' import Change from '../shared/Change' import ChartRangeButtons from '../shared/ChartRangeButtons' import { useViewport } from 'hooks/useViewport' import { formatTokenSymbol } from 'utils/tokens' import { useQuery } from '@tanstack/react-query' import { fetchChartData } from 'apis/coingecko' import mangoStore from '@store/mangoStore' import useJupiterSwapData from './useJupiterSwapData' import useLocalStorageState from 'hooks/useLocalStorageState' import { ANIMATION_SETTINGS_KEY } from 'utils/constants' import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettings' dayjs.extend(relativeTime) const CustomizedLabel = ({ chartData, x, y, value, }: { chartData: any[] x?: number y?: string | number value?: number }) => { const { width } = useViewport() const [min, max] = useMemo(() => { if (chartData.length) { const prices = chartData.map((d: any) => d.price) return [Math.min(...prices), Math.max(...prices)] } return ['', ''] }, [chartData]) if (value === min || value === max) { return ( width / 3 ? 'end' : 'start'} className="font-mono" > {formatFixedDecimals(value)} ) } else return
} const SwapTokenChart = () => { const { inputBank, outputBank } = mangoStore((s) => s.swap) const { inputCoingeckoId, outputCoingeckoId } = useJupiterSwapData() const [baseTokenId, setBaseTokenId] = useState(inputCoingeckoId) const [quoteTokenId, setQuoteTokenId] = useState(outputCoingeckoId) const [mouseData, setMouseData] = useState(null) const [daysToShow, setDaysToShow] = useState('1') const { theme } = useTheme() const [animationSettings] = useLocalStorageState( ANIMATION_SETTINGS_KEY, INITIAL_ANIMATION_SETTINGS ) const chartDataQuery = useQuery( ['chart-data', baseTokenId, quoteTokenId, daysToShow], () => fetchChartData(baseTokenId, quoteTokenId, daysToShow), { cacheTime: 1000 * 60 * 1, staleTime: 1000 * 60 * 1, enabled: !!baseTokenId && !!quoteTokenId, } ) const chartData = chartDataQuery.data const handleMouseMove = (coords: any) => { if (coords.activePayload) { setMouseData(coords.activePayload[0].payload) } } const handleMouseLeave = () => { setMouseData(null) } useEffect(() => { if (!inputCoingeckoId || !outputCoingeckoId) return if (['usd-coin', 'tether'].includes(outputCoingeckoId)) { setBaseTokenId(inputCoingeckoId) setQuoteTokenId(outputCoingeckoId) } else { setBaseTokenId(outputCoingeckoId) setQuoteTokenId(inputCoingeckoId) } }, [inputCoingeckoId, outputCoingeckoId]) // const handleFlipChart = useCallback(() => { // if (!baseTokenId || !quoteTokenId) return // setBaseTokenId(quoteTokenId) // setQuoteTokenId(baseTokenId) // }, [baseTokenId, quoteTokenId]) const calculateChartChange = () => { if (chartData.length) { if (mouseData) { const index = chartData.findIndex((d: any) => d.time === mouseData.time) return ( ((chartData[index]['price'] - chartData[0]['price']) / chartData[0]['price']) * 100 ) } else return ( ((chartData[chartData.length - 1]['price'] - chartData[0]['price']) / chartData[0]['price']) * 100 ) } return 0 } return ( {chartDataQuery?.isLoading || chartDataQuery.isFetching ? ( <>
) : chartData?.length && baseTokenId && quoteTokenId ? (
{inputBank && outputBank ? (

{['usd-coin', 'tether'].includes(inputCoingeckoId || '') ? `${formatTokenSymbol( outputBank?.name?.toUpperCase() )}/${inputBank?.name?.toUpperCase()}` : `${formatTokenSymbol( inputBank?.name?.toUpperCase() )}/${formatTokenSymbol( outputBank?.name?.toUpperCase() )}`}

{/*
*/}
) : null} {mouseData ? ( <>
{animationSettings['number-scroll'] ? ( ) : ( {formatFixedDecimals(mouseData['price'])} )}

{dayjs(mouseData['time']).format('DD MMM YY, h:mma')}

) : ( <>
{animationSettings['number-scroll'] ? ( ) : ( {formatFixedDecimals( chartData[chartData.length - 1]['price'] )} )}

{dayjs(chartData[chartData.length - 1]['time']).format( 'DD MMM YY, h:mma' )}

)}
setDaysToShow(v)} />
} /> = 0 ? COLORS.UP[theme] : COLORS.DOWN[theme] } stopOpacity={0.25} /> = 0 ? COLORS.UP[theme] : COLORS.DOWN[theme] } stopOpacity={0} /> = 0 ? COLORS.UP[theme] : COLORS.DOWN[theme] } strokeWidth={1.5} fill="url(#gradientArea)" label={} />
) : (

Chart not available

)} ) } export default SwapTokenChart