import { useEffect, useState } from 'react' import { PublicKey } from '@solana/web3.js' import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' 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' import { useTranslation } from 'next-i18next' import { ExpandableRow } from './TableElements' const filterByVals = ['change-percent', '24h-volume'] const timeFrameVals = ['24h', '7d', '30d'] const insightTypeVals = ['best', 'worst'] dayjs.extend(relativeTime) const SwapTokenInsights = ({ formState, jupiterTokens, setOutputToken }) => { const [tokenInsights, setTokenInsights] = useState([]) const [filteredTokenInsights, setFilteredTokenInsights] = useState([]) const [insightType, setInsightType] = useState(insightTypeVals[0]) const [filterBy, setFilterBy] = useState(filterByVals[0]) const [timeframe, setTimeframe] = useState(timeFrameVals[0]) const [textFilter, setTextFilter] = useState('') const [showSearch, setShowSearch] = useState(false) const [loading, setLoading] = useState(false) const { t } = useTranslation(['common', 'swap']) 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 === filterByVals[0] && textFilter === '') { //filter by 'change %' setFilteredTokenInsights( tokenInsights .sort((a, b) => insightType === insightTypeVals[0] //insight type '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 === filterByVals[1] && textFilter === '') { //filter by 24h vol setFilteredTokenInsights( tokenInsights .sort((a, b) => insightType === insightTypeVals[0] //insight type '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={filterByVals} names={filterByVals.map((val) => t(`swap:${val}`))} />
{filterBy === filterByVals[0] ? ( //filter by change %
setTimeframe(t)} values={timeFrameVals} />
) : null}
setInsightType(t)} values={insightTypeVals} names={insightTypeVals.map((val) => t(`swap:${val}`))} />
) : (
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 ( <>
= 0 ? 'text-th-green' : 'text-th-red' : timeframe === timeFrameVals[1] //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 === timeFrameVals[0] //timeframe 24h ? insight.price_change_percentage_24h_in_currency ? `${insight.price_change_percentage_24h_in_currency.toFixed( 1 )}%` : '?' : timeframe === timeFrameVals[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.name} ) : (
?
)}
{insight?.symbol?.toUpperCase()}
{insight.name}
{t('price')}
$ {insight.current_price.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 6, })}
{t('swap:24h-vol')}
{insight.total_volume > 0 ? `$${numberCompacter.format( insight.total_volume )}` : '?'}
} panelTemplate={
{insight.market_cap_rank ? (
{t('swap:market-cap-rank')}
#{insight.market_cap_rank}
) : null} {insight?.market_cap && insight?.market_cap !== 0 ? (
{t('swap:market-cap')}
${numberCompacter.format(insight.market_cap)}
) : null} {insight?.circulating_supply ? (
{t('swap:token-supply')}
{numberCompacter.format(insight.circulating_supply)}
{insight?.max_supply ? (
{t('swap:max-supply')} {': '} {numberCompacter.format(insight.max_supply)}
) : null}
) : null} {insight?.ath ? (
{t('swap:ath')}
${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 ? (
{t('swap:atl')}
${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}
} /> ) })}
) : (
{t('swap:no-tokens-found')}
)}
) : (
{t('swap:insights-not-available')}
) } export default SwapTokenInsights