mango-ui-v3/components/SwapTokenInfo.tsx

710 lines
29 KiB
TypeScript
Raw Normal View History

import { FunctionComponent, useEffect, useMemo, useState } from 'react'
2021-12-31 04:17:48 -08:00
import { EyeOffIcon } from '@heroicons/react/outline'
import { ChevronDownIcon } from '@heroicons/react/solid'
import { Disclosure } from '@headlessui/react'
2021-12-30 03:44:14 -08:00
import dayjs from 'dayjs'
2022-01-02 16:52:03 -08:00
import relativeTime from 'dayjs/plugin/relativeTime'
2021-12-30 03:44:14 -08:00
import { AreaChart, Area, XAxis, YAxis, Tooltip } from 'recharts'
import useDimensions from 'react-cool-dimensions'
2021-12-31 04:17:48 -08:00
import { IconButton } from './Button'
2021-12-31 19:07:14 -08:00
import { LineChartIcon } from './icons'
dayjs.extend(relativeTime)
2021-12-30 03:44:14 -08:00
interface SwapTokenInfoProps {
inputTokenId?: string
outputTokenId?: string
}
2022-01-02 04:20:42 -08:00
export const numberFormatter = Intl.NumberFormat('en', {
minimumSignificantDigits: 1,
maximumSignificantDigits: 5,
notation: 'compact',
})
2021-12-30 03:44:14 -08:00
const SwapTokenInfo: FunctionComponent<SwapTokenInfoProps> = ({
inputTokenId,
outputTokenId,
}) => {
2021-12-31 04:17:48 -08:00
const [chartData, setChartData] = useState([])
const [hideChart, setHideChart] = useState(false)
2022-01-04 13:46:38 -08:00
const [baseTokenId, setBaseTokenId] = useState('mango-markets')
const [quoteTokenId, setQuoteTokenId] = useState('usd-coin')
2021-12-31 19:07:14 -08:00
const [inputTokenInfo, setInputTokenInfo] = useState(null)
2021-12-30 03:44:14 -08:00
const [outputTokenInfo, setOutputTokenInfo] = useState(null)
const [mouseData, setMouseData] = useState<string | null>(null)
2022-01-02 04:20:42 -08:00
const [daysToShow, setDaysToShow] = useState(1)
2021-12-30 03:44:14 -08:00
const { observe, width, height } = useDimensions()
const handleMouseMove = (coords) => {
if (coords.activePayload) {
setMouseData(coords.activePayload[0].payload)
}
}
const handleMouseLeave = () => {
setMouseData(null)
}
useEffect(() => {
if (['usd-coin', 'tether'].includes(inputTokenId)) {
setBaseTokenId(outputTokenId)
setQuoteTokenId(inputTokenId)
} else {
setBaseTokenId(inputTokenId)
setQuoteTokenId(outputTokenId)
}
}, [inputTokenId, outputTokenId])
2022-01-02 04:20:42 -08:00
// Use ohlc data
2021-12-31 04:17:48 -08:00
2021-12-30 03:44:14 -08:00
const getChartData = async () => {
const inputResponse = await fetch(
`https://api.coingecko.com/api/v3/coins/${baseTokenId}/ohlc?vs_currency=usd&days=${daysToShow}`
2021-12-30 03:44:14 -08:00
)
const outputResponse = await fetch(
`https://api.coingecko.com/api/v3/coins/${quoteTokenId}/ohlc?vs_currency=usd&days=${daysToShow}`
2021-12-30 03:44:14 -08:00
)
const inputData = await inputResponse.json()
const outputData = await outputResponse.json()
2022-01-02 04:20:42 -08:00
const data = inputData.concat(outputData)
2021-12-30 03:44:14 -08:00
const formattedData = data.reduce((a, c) => {
2022-01-02 04:20:42 -08:00
const found = a.find((price) => price.time === c[0])
2021-12-30 03:44:14 -08:00
if (found) {
2022-01-02 04:20:42 -08:00
found.price = found.inputPrice / c[4]
2021-12-30 03:44:14 -08:00
} else {
2022-01-02 04:20:42 -08:00
a.push({ time: c[0], inputPrice: c[4] })
2021-12-30 03:44:14 -08:00
}
return a
}, [])
2022-01-02 04:20:42 -08:00
formattedData[formattedData.length - 1].time = Date.now()
2021-12-30 03:44:14 -08:00
setChartData(formattedData.filter((d) => d.price))
}
2022-01-02 04:20:42 -08:00
// Alternative chart data. Needs a timestamp tolerance to get data points for each asset
// const getChartData = async () => {
// const now = Date.now() / 1000
// const inputResponse = await fetch(
// `https://api.coingecko.com/api/v3/coins/${inputTokenId}/market_chart/range?vs_currency=usd&from=${
// now - 1 * 86400
// }&to=${now}`
// )
// const outputResponse = await fetch(
// `https://api.coingecko.com/api/v3/coins/${outputTokenId}/market_chart/range?vs_currency=usd&from=${
// now - 1 * 86400
// }&to=${now}`
// )
// const inputData = await inputResponse.json()
// const outputData = await outputResponse.json()
// const data = inputData?.prices.concat(outputData?.prices)
// const formattedData = data.reduce((a, c) => {
// const found = a.find(
// (price) => c[0] >= price.time - 120000 && c[0] <= price.time + 120000
// )
// if (found) {
// found.price = found.inputPrice / c[1]
// } else {
// a.push({ time: c[0], inputPrice: c[1] })
// }
// return a
// }, [])
// setChartData(formattedData.filter((d) => d.price))
// }
2021-12-31 19:07:14 -08:00
const getInputTokenInfo = async () => {
const response = await fetch(
`https://api.coingecko.com/api/v3/coins/${baseTokenId}?localization=false&tickers=false&developer_data=false&sparkline=false
2021-12-31 19:07:14 -08:00
`
)
const data = await response.json()
setInputTokenInfo(data)
}
2021-12-30 03:44:14 -08:00
const getOutputTokenInfo = async () => {
const response = await fetch(
`https://api.coingecko.com/api/v3/coins/${quoteTokenId}?localization=false&tickers=false&developer_data=false&sparkline=false
2021-12-30 03:44:14 -08:00
`
)
const data = await response.json()
setOutputTokenInfo(data)
}
useMemo(() => {
if (baseTokenId && quoteTokenId) {
2021-12-30 03:44:14 -08:00
getChartData()
}
}, [daysToShow, baseTokenId, quoteTokenId])
2021-12-30 03:44:14 -08:00
useMemo(() => {
if (baseTokenId) {
2021-12-31 19:07:14 -08:00
getInputTokenInfo()
}
if (quoteTokenId) {
2021-12-30 03:44:14 -08:00
getOutputTokenInfo()
}
}, [baseTokenId, quoteTokenId])
2021-12-30 03:44:14 -08:00
2021-12-31 04:17:48 -08:00
const chartChange = chartData.length
? ((chartData[chartData.length - 1]['price'] - chartData[0]['price']) /
chartData[0]['price']) *
100
: 0
2021-12-30 03:44:14 -08:00
return (
<div>
{chartData.length && baseTokenId && quoteTokenId ? (
2022-01-01 04:34:46 -08:00
<div className="py-6">
2022-01-02 04:20:42 -08:00
<div className="flex items-start justify-between">
2021-12-30 03:44:14 -08:00
<div>
{inputTokenInfo && outputTokenInfo ? (
<div className="text-th-fgd-3 text-sm">{`${inputTokenInfo.symbol.toUpperCase()}/${outputTokenInfo.symbol.toUpperCase()}`}</div>
2021-12-30 03:44:14 -08:00
) : null}
{mouseData ? (
<>
<div className="font-bold text-lg text-th-fgd-1">
2021-12-31 19:07:14 -08:00
{numberFormatter.format(mouseData['price'])}
2021-12-31 04:17:48 -08:00
<span
2022-01-02 04:20:42 -08:00
className={`ml-2 text-xs ${
2021-12-31 04:17:48 -08:00
chartChange >= 0 ? 'text-th-green' : 'text-th-red'
}`}
>
{chartChange.toFixed(2)}%
</span>
2021-12-30 03:44:14 -08:00
</div>
2022-01-02 04:20:42 -08:00
<div className="text-xs font-normal text-th-fgd-3">
2021-12-30 03:44:14 -08:00
{dayjs(mouseData['time']).format('DD MMM YY, h:mma')}
</div>
</>
) : (
<>
<div className="font-bold text-lg text-th-fgd-1">
2021-12-31 19:07:14 -08:00
{numberFormatter.format(
chartData[chartData.length - 1]['price']
2021-12-30 03:44:14 -08:00
)}
2021-12-31 04:17:48 -08:00
<span
2022-01-01 04:34:46 -08:00
className={`ml-2 text-xs ${
2021-12-31 04:17:48 -08:00
chartChange >= 0 ? 'text-th-green' : 'text-th-red'
}`}
>
{chartChange.toFixed(2)}%
</span>
2021-12-30 03:44:14 -08:00
</div>
2022-01-01 04:34:46 -08:00
<div className="text-xs font-normal text-th-fgd-3">
2021-12-30 03:44:14 -08:00
{dayjs(chartData[chartData.length - 1]['time']).format(
'DD MMM YY, h:mma'
)}
</div>
</>
)}
</div>
2021-12-31 04:17:48 -08:00
<IconButton onClick={() => setHideChart(!hideChart)}>
{hideChart ? (
2021-12-31 19:07:14 -08:00
<LineChartIcon className="w-4 h-4" />
2021-12-31 04:17:48 -08:00
) : (
<EyeOffIcon className="w-4 h-4" />
)}
</IconButton>
2021-12-30 03:44:14 -08:00
</div>
2021-12-31 04:17:48 -08:00
{!hideChart ? (
<div className="h-52 mt-4 w-full" ref={observe}>
<AreaChart
width={width}
height={height}
data={chartData}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
>
<Tooltip
cursor={{
strokeOpacity: 0,
}}
content={<></>}
/>
<defs>
<linearGradient id="gradientArea" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="#FF9C24" stopOpacity={0.5} />
<stop offset="100%" stopColor="#FF9C24" stopOpacity={0} />
</linearGradient>
</defs>
<Area
isAnimationActive={true}
type="monotone"
dataKey="price"
stroke="#FF9C24"
fill="url(#gradientArea)"
/>
<XAxis dataKey="time" hide />
<YAxis
dataKey="price"
type="number"
domain={['dataMin', 'dataMax']}
hide
/>
</AreaChart>
2022-01-02 04:20:42 -08:00
<div className="flex justify-end">
<button
className={`default-transition font-bold px-3 py-2 text-th-fgd-1 text-xs hover:text-th-primary focus:outline-none ${
daysToShow === 1 && 'text-th-primary'
}`}
onClick={() => setDaysToShow(1)}
>
24H
</button>
<button
className={`default-transition font-bold px-3 py-2 text-th-fgd-1 text-xs hover:text-th-primary focus:outline-none ${
daysToShow === 7 && 'text-th-primary'
}`}
onClick={() => setDaysToShow(7)}
>
7D
</button>
<button
className={`default-transition font-bold px-3 py-2 text-th-fgd-1 text-xs hover:text-th-primary focus:outline-none ${
daysToShow === 30 && 'text-th-primary'
}`}
onClick={() => setDaysToShow(30)}
>
30D
</button>
</div>
2021-12-31 04:17:48 -08:00
</div>
) : null}
2021-12-30 03:44:14 -08:00
</div>
) : (
2022-01-02 04:20:42 -08:00
<div className="bg-th-bkg-3 mt-4 md:mt-0 p-4 rounded-md text-center text-th-fgd-3">
<LineChartIcon className="h-6 mx-auto text-th-primary w-6" />
2021-12-30 03:44:14 -08:00
Chart not available
</div>
)}
2021-12-31 04:17:48 -08:00
2022-01-02 04:20:42 -08:00
{inputTokenInfo && inputTokenId ? (
2022-01-01 04:34:46 -08:00
<div className="w-full">
2021-12-31 04:17:48 -08:00
<Disclosure>
{({ open }) => (
<>
<Disclosure.Button
2022-01-02 04:20:42 -08:00
className={`border border-th-bkg-4 default-transition flex items-center justify-between mt-6 p-3 rounded-md w-full hover:bg-th-bkg-2 ${
2021-12-31 04:17:48 -08:00
open
? 'border-b-transparent rounded-b-none'
: 'transform rotate-360'
}`}
>
2021-12-31 19:07:14 -08:00
<div className="flex items-center">
{inputTokenInfo.image?.small ? (
<img
src={inputTokenInfo.image?.small}
width="32"
height="32"
alt={inputTokenInfo.name}
/>
) : null}
<div className="ml-2.5 text-left">
<h2 className="font-bold text-base text-th-fgd-1">
{inputTokenInfo.symbol.toUpperCase()}
</h2>
<div className="font-normal text-th-fgd-3 text-xs">
{inputTokenInfo.name}
</div>
</div>
</div>
<div className="flex items-center">
2022-01-01 04:34:46 -08:00
<div className="flex items-center space-x-3">
2021-12-31 19:07:14 -08:00
{inputTokenInfo.market_data?.current_price?.usd ? (
<div className="font-normal text-th-fgd-1">
$
{numberFormatter.format(
inputTokenInfo.market_data.current_price.usd
)}
</div>
) : null}
{inputTokenInfo.market_data
?.price_change_percentage_24h ? (
<div
className={`font-normal text-th-fgd-1 ${
inputTokenInfo.market_data
.price_change_percentage_24h >= 0
? 'text-th-green'
: 'text-th-red'
}`}
>
{inputTokenInfo.market_data.price_change_percentage_24h.toFixed(
2
)}
%
</div>
) : null}
</div>
<ChevronDownIcon
className={`default-transition h-6 ml-2 w-6 text-th-fgd-3 ${
open ? 'transform rotate-180' : 'transform rotate-360'
}`}
/>
</div>
2021-12-31 04:17:48 -08:00
</Disclosure.Button>
<Disclosure.Panel>
2021-12-31 19:07:14 -08:00
<div className="border border-th-bkg-4 border-t-0 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-2 xl:grid-cols-3 grid-flow-row p-3 rounded-b-md">
{inputTokenInfo.market_cap_rank ? (
2021-12-31 04:17:48 -08:00
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
2021-12-31 19:07:14 -08:00
<div className="text-th-fgd-3 text-xs">
2021-12-31 04:17:48 -08:00
Market Cap Rank
</div>
<div className="font-bold text-th-fgd-1 text-lg">
2021-12-31 19:07:14 -08:00
#{inputTokenInfo.market_cap_rank}
2021-12-31 04:17:48 -08:00
</div>
</div>
) : null}
2021-12-31 19:07:14 -08:00
{inputTokenInfo.market_data?.market_cap ? (
2021-12-31 04:17:48 -08:00
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
2021-12-31 19:07:14 -08:00
<div className="text-th-fgd-3 text-xs">Market Cap</div>
2021-12-31 04:17:48 -08:00
<div className="font-bold text-th-fgd-1 text-lg">
$
2021-12-31 19:07:14 -08:00
{numberFormatter.format(
inputTokenInfo.market_data?.market_cap?.usd
)}
2021-12-31 04:17:48 -08:00
</div>
</div>
) : null}
2021-12-31 19:07:14 -08:00
{inputTokenInfo.market_data.total_volume?.usd ? (
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
<div className="text-th-fgd-3 text-xs">24h Volume</div>
<div className="font-bold text-th-fgd-1 text-lg">
$
{numberFormatter.format(
inputTokenInfo.market_data.total_volume?.usd
)}
</div>
</div>
) : null}
{inputTokenInfo.market_data?.circulating_supply ? (
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
<div className="text-th-fgd-3 text-xs">
Token Supply
</div>
<div className="font-bold text-th-fgd-1 text-lg">
{numberFormatter.format(
inputTokenInfo.market_data.circulating_supply
)}
</div>
{inputTokenInfo.market_data?.max_supply ? (
<div className="text-th-fgd-2 text-xs">
Max Supply:{' '}
{numberFormatter.format(
inputTokenInfo.market_data.max_supply
)}
</div>
) : null}
</div>
) : null}
{inputTokenInfo.market_data?.ath?.usd ? (
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
<div className="text-th-fgd-3 text-xs">
All-Time High
</div>
<div className="flex">
<div className="font-bold text-th-fgd-1 text-lg">
$
{numberFormatter.format(
inputTokenInfo.market_data.ath.usd
)}
</div>
{inputTokenInfo.market_data?.ath_change_percentage
?.usd ? (
<div
className={`ml-1.5 mt-2 text-xs ${
inputTokenInfo.market_data
?.ath_change_percentage?.usd >= 0
? 'text-th-green'
: 'text-th-red'
}`}
>
{(inputTokenInfo.market_data?.ath_change_percentage?.usd).toFixed(
2
)}
%
</div>
) : null}
</div>
{inputTokenInfo.market_data?.ath_date?.usd ? (
<div className="text-th-fgd-2 text-xs">
{dayjs(
inputTokenInfo.market_data.ath_date.usd
).fromNow()}
</div>
) : null}
</div>
) : null}
{inputTokenInfo.market_data?.atl?.usd ? (
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
<div className="text-th-fgd-3 text-xs">
All-Time Low
</div>
<div className="flex">
<div className="font-bold text-th-fgd-1 text-lg">
$
{numberFormatter.format(
inputTokenInfo.market_data.atl.usd
)}
</div>
{inputTokenInfo.market_data?.atl_change_percentage
?.usd ? (
<div
className={`ml-1.5 mt-2 text-xs ${
inputTokenInfo.market_data
?.atl_change_percentage?.usd >= 0
? 'text-th-green'
: 'text-th-red'
}`}
>
{(inputTokenInfo.market_data?.atl_change_percentage?.usd).toLocaleString(
undefined,
{
minimumFractionDigits: 0,
maximumFractionDigits: 2,
}
)}
%
</div>
) : null}
</div>
{inputTokenInfo.market_data?.atl_date?.usd ? (
<div className="text-th-fgd-2 text-xs">
{dayjs(
inputTokenInfo.market_data.atl_date.usd
).fromNow()}
</div>
) : null}
</div>
) : null}
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
</div>
) : (
2022-01-02 04:20:42 -08:00
<div className="bg-th-bkg-3 mt-3 p-4 rounded-md text-center text-th-fgd-3">
Input token information is not available.
2021-12-31 19:07:14 -08:00
</div>
)}
2022-01-02 04:20:42 -08:00
{outputTokenInfo && outputTokenId ? (
2022-01-01 04:34:46 -08:00
<div className="w-full">
2021-12-31 19:07:14 -08:00
<Disclosure>
{({ open }) => (
<>
<Disclosure.Button
2022-01-01 04:34:46 -08:00
className={`border border-th-bkg-4 default-transition flex items-center justify-between mt-3 p-3 rounded-md w-full hover:bg-th-bkg-2 ${
2021-12-31 19:07:14 -08:00
open
? 'border-b-transparent rounded-b-none'
: 'transform rotate-360'
}`}
>
<div className="flex items-center">
{outputTokenInfo.image?.small ? (
<img
src={outputTokenInfo.image?.small}
width="32"
height="32"
alt={outputTokenInfo.name}
/>
) : null}
<div className="ml-2.5 text-left">
<h2 className="font-bold text-base text-th-fgd-1">
{outputTokenInfo.symbol.toUpperCase()}
</h2>
<div className="font-normal text-th-fgd-3 text-xs">
{outputTokenInfo.name}
</div>
</div>
</div>
<div className="flex items-center">
2022-01-01 04:34:46 -08:00
<div className="flex items-center space-x-3">
2021-12-31 19:07:14 -08:00
{outputTokenInfo.market_data?.current_price?.usd ? (
<div className="font-normal text-th-fgd-1">
$
{numberFormatter.format(
outputTokenInfo.market_data.current_price.usd
)}
</div>
) : null}
{outputTokenInfo.market_data
?.price_change_percentage_24h ? (
<div
className={`font-normal text-th-fgd-1 ${
outputTokenInfo.market_data
.price_change_percentage_24h >= 0
? 'text-th-green'
: 'text-th-red'
}`}
>
{outputTokenInfo.market_data.price_change_percentage_24h.toFixed(
2
)}
%
</div>
) : null}
</div>
<ChevronDownIcon
className={`default-transition h-6 ml-2 w-6 text-th-fgd-3 ${
open ? 'transform rotate-180' : 'transform rotate-360'
}`}
/>
</div>
</Disclosure.Button>
<Disclosure.Panel>
<div className="border border-th-bkg-4 border-t-0 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-2 xl:grid-cols-3 grid-flow-row p-3 rounded-b-md">
2021-12-31 04:17:48 -08:00
{outputTokenInfo.market_cap_rank ? (
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
2021-12-31 19:07:14 -08:00
<div className="text-th-fgd-3 text-xs">
2021-12-31 04:17:48 -08:00
Market Cap Rank
</div>
<div className="font-bold text-th-fgd-1 text-lg">
#{outputTokenInfo.market_cap_rank}
</div>
</div>
) : null}
{outputTokenInfo.market_data?.market_cap ? (
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
2021-12-31 19:07:14 -08:00
<div className="text-th-fgd-3 text-xs">Market Cap</div>
<div className="font-bold text-th-fgd-1 text-lg">
$
{numberFormatter.format(
outputTokenInfo.market_data?.market_cap?.usd
)}
</div>
</div>
) : null}
{outputTokenInfo.market_data.total_volume?.usd ? (
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
<div className="text-th-fgd-3 text-xs">24h Volume</div>
2021-12-31 04:17:48 -08:00
<div className="font-bold text-th-fgd-1 text-lg">
$
2021-12-31 19:07:14 -08:00
{numberFormatter.format(
outputTokenInfo.market_data.total_volume?.usd
)}
2021-12-31 04:17:48 -08:00
</div>
</div>
) : null}
2021-12-31 19:07:14 -08:00
{outputTokenInfo.market_data?.circulating_supply ? (
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
<div className="text-th-fgd-3 text-xs">
Token Supply
</div>
<div className="font-bold text-th-fgd-1 text-lg">
{numberFormatter.format(
outputTokenInfo.market_data.circulating_supply
)}
</div>
{outputTokenInfo.market_data?.max_supply ? (
<div className="text-th-fgd-2 text-xs">
Max Supply:{' '}
{numberFormatter.format(
outputTokenInfo.market_data.max_supply
)}
</div>
) : null}
</div>
) : null}
{outputTokenInfo.market_data?.ath?.usd ? (
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
<div className="text-th-fgd-3 text-xs">
All-Time High
</div>
<div className="flex">
<div className="font-bold text-th-fgd-1 text-lg">
$
{numberFormatter.format(
outputTokenInfo.market_data.ath.usd
)}
</div>
{outputTokenInfo.market_data?.ath_change_percentage
?.usd ? (
<div
className={`ml-1.5 mt-2 text-xs ${
outputTokenInfo.market_data
?.ath_change_percentage?.usd >= 0
? 'text-th-green'
: 'text-th-red'
}`}
>
{(outputTokenInfo.market_data?.ath_change_percentage?.usd).toFixed(
2
)}
%
</div>
) : null}
</div>
{outputTokenInfo.market_data?.ath_date?.usd ? (
<div className="text-th-fgd-2 text-xs">
{dayjs(
outputTokenInfo.market_data.ath_date.usd
).fromNow()}
</div>
) : null}
</div>
) : null}
{outputTokenInfo.market_data?.atl?.usd ? (
<div className="border border-th-bkg-4 m-1 p-3 rounded-md">
<div className="text-th-fgd-3 text-xs">
All-Time Low
</div>
<div className="flex">
<div className="font-bold text-th-fgd-1 text-lg">
$
{numberFormatter.format(
outputTokenInfo.market_data.atl.usd
)}
</div>
{outputTokenInfo.market_data?.atl_change_percentage
?.usd ? (
<div
className={`ml-1.5 mt-2 text-xs ${
outputTokenInfo.market_data
?.atl_change_percentage?.usd >= 0
? 'text-th-green'
: 'text-th-red'
}`}
>
{(outputTokenInfo.market_data?.atl_change_percentage?.usd).toLocaleString(
undefined,
{
minimumFractionDigits: 0,
maximumFractionDigits: 2,
}
)}
%
</div>
) : null}
</div>
{outputTokenInfo.market_data?.atl_date?.usd ? (
<div className="text-th-fgd-2 text-xs">
{dayjs(
outputTokenInfo.market_data.atl_date.usd
).fromNow()}
</div>
) : null}
</div>
) : null}
2021-12-31 04:17:48 -08:00
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
2021-12-30 03:44:14 -08:00
</div>
2021-12-31 19:07:14 -08:00
) : (
2022-01-02 04:20:42 -08:00
<div className="bg-th-bkg-3 mt-3 p-4 rounded-md text-center text-th-fgd-3">
Output token information is not available.
2021-12-31 19:07:14 -08:00
</div>
)}
2021-12-30 03:44:14 -08:00
</div>
)
}
export default SwapTokenInfo