import { useEffect, useState } from 'react'
import { PublicKey } from '@solana/web3.js'
import { Disclosure } from '@headlessui/react'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import { ChevronDownIcon } from '@heroicons/react/solid'
import ButtonGroup from './ButtonGroup'
import { numberCompacter, numberFormatter } from './SwapTokenInfo'
import Button, { IconButton } from './Button'
import Input from './Input'
import { SearchIcon, XIcon } from '@heroicons/react/outline'
dayjs.extend(relativeTime)
const SwapTokenInsights = ({ formState, jupiterTokens, setOutputToken }) => {
const [tokenInsights, setTokenInsights] = useState([])
const [filteredTokenInsights, setFilteredTokenInsights] = useState([])
const [insightType, setInsightType] = useState('Best')
const [filterBy, setFilterBy] = useState('Change %')
const [timeframe, setTimeframe] = useState('24h')
const [textFilter, setTextFilter] = useState('')
const [showSearch, setShowSearch] = useState(false)
const [loading, setLoading] = useState(false)
const getTokenInsights = async () => {
setLoading(true)
const ids = jupiterTokens
.filter((token) => token?.extensions?.coingeckoId)
.map((token) => token.extensions.coingeckoId)
const response = await fetch(
`https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=${ids.toString()}&order=market_cap_desc&sparkline=false&price_change_percentage=24h,7d,30d`
)
const data = await response.json()
setLoading(false)
setTokenInsights(data)
}
useEffect(() => {
if (filterBy === 'Change %' && textFilter === '') {
setFilteredTokenInsights(
tokenInsights
.sort((a, b) =>
insightType === 'Best'
? b[`price_change_percentage_${timeframe}_in_currency`] -
a[`price_change_percentage_${timeframe}_in_currency`]
: a[`price_change_percentage_${timeframe}_in_currency`] -
b[`price_change_percentage_${timeframe}_in_currency`]
)
.slice(0, 10)
)
}
if (filterBy === '24h Volume' && textFilter === '') {
setFilteredTokenInsights(
tokenInsights
.sort((a, b) =>
insightType === 'Best'
? b.total_volume - a.total_volume
: a.total_volume - b.total_volume
)
.slice(0, 10)
)
}
if (textFilter !== '') {
setFilteredTokenInsights(
tokenInsights.filter(
(token) =>
token.name.includes(textFilter) || token.symbol.includes(textFilter)
)
)
}
}, [filterBy, insightType, textFilter, timeframe, tokenInsights])
useEffect(() => {
if (jupiterTokens) {
getTokenInsights()
}
}, [])
const handleToggleSearch = () => {
setShowSearch(!showSearch)
setTextFilter('')
}
return filteredTokenInsights ? (
{!showSearch ? (
setFilterBy(t)}
values={['Change %', '24h Volume']}
/>
{filterBy === 'Change %' ? (
setTimeframe(t)}
values={['24h', '7d', '30d']}
/>
) : null}
setInsightType(t)}
values={['Best', 'Worst']}
/>
) : (
setTextFilter(e.target.value)}
prefix={}
/>
)}
handleToggleSearch()}
>
{showSearch ? (
) : (
)}
{loading ? (
) : filteredTokenInsights.length > 0 ? (
filteredTokenInsights.map((insight) => {
const jupToken = jupiterTokens.find(
(t) => t?.extensions?.coingeckoId === insight.id
)
return (
{({ open }) => (
<>
=
0
? 'text-th-green'
: 'text-th-red'
: timeframe === '7d'
? insight.price_change_percentage_7d_in_currency >=
0
? 'text-th-green'
: 'text-th-red'
: insight.price_change_percentage_30d_in_currency >=
0
? 'text-th-green'
: 'text-th-red'
}`}
>
{timeframe === '24h'
? insight.price_change_percentage_24h_in_currency
? `${insight.price_change_percentage_24h_in_currency.toFixed(
1
)}%`
: '?'
: timeframe === '7d'
? insight.price_change_percentage_7d_in_currency
? `${insight.price_change_percentage_7d_in_currency.toFixed(
1
)}%`
: '?'
: insight.price_change_percentage_30d_in_currency
? `${insight.price_change_percentage_30d_in_currency.toFixed(
1
)}%`
: '?'}
{insight.image ? (
) : (
?
)}
{insight?.symbol?.toUpperCase()}
{insight.name}
Price
$
{insight.current_price.toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 6,
})}
24h Vol
{insight.total_volume > 0
? `$${numberCompacter.format(
insight.total_volume
)}`
: '?'}
{insight.market_cap_rank ? (
Market Cap Rank
#{insight.market_cap_rank}
) : null}
{insight?.market_cap && insight?.market_cap !== 0 ? (
Market Cap
${numberCompacter.format(insight.market_cap)}
) : null}
{insight?.circulating_supply ? (
Token Supply
{numberCompacter.format(insight.circulating_supply)}
{insight?.max_supply ? (
Max Supply:{' '}
{numberCompacter.format(insight.max_supply)}
) : null}
) : null}
{insight?.ath ? (
All-Time High
${numberFormatter.format(insight.ath)}
{insight?.ath_change_percentage ? (
= 0
? 'text-th-green'
: 'text-th-red'
}`}
>
{insight.ath_change_percentage.toFixed(2)}%
) : null}
{insight?.ath_date ? (
{dayjs(insight.ath_date).fromNow()}
) : null}
) : null}
{insight?.atl ? (
All-Time Low
${numberFormatter.format(insight.atl)}
{insight?.atl_change_percentage ? (
= 0
? 'text-th-green'
: 'text-th-red'
}`}
>
{(insight?.atl_change_percentage).toLocaleString(
undefined,
{
minimumFractionDigits: 0,
maximumFractionDigits: 2,
}
)}
%
) : null}
{insight?.atl_date ? (
{dayjs(insight.atl_date).fromNow()}
) : null}
) : null}
>
)}
)
})
) : (
No tokens found...
)}
) : (
Market insights are not available
)
}
export default SwapTokenInsights