mango-v4-ui/components/explore/SpotCards.tsx

173 lines
6.6 KiB
TypeScript
Raw Normal View History

2023-10-04 04:52:39 -07:00
import { ActionsMenu } from '@components/TokenList'
import Button from '@components/shared/Button'
import Change from '@components/shared/Change'
import FormatNumericValue from '@components/shared/FormatNumericValue'
import TokenLogo from '@components/shared/TokenLogo'
import { goToTokenPage } from '@components/stats/tokens/TokenOverviewTable'
import Decimal from 'decimal.js'
import useMangoGroup from 'hooks/useMangoGroup'
import { useRouter } from 'next/router'
import { useTranslation } from 'react-i18next'
import { numberCompacter } from 'utils/numbers'
import { BankWithMarketData } from './Spot'
2023-10-04 16:04:51 -07:00
import Tooltip from '@components/shared/Tooltip'
import SimpleAreaChart from '@components/shared/SimpleAreaChart'
import { COLORS } from 'styles/colors'
import useThemeWrapper from 'hooks/useThemeWrapper'
import TokenReduceOnlyDesc from '@components/shared/TokenReduceOnlyDesc'
import CollateralWeightDisplay from '@components/shared/CollateralWeightDisplay'
2024-03-14 21:24:18 -07:00
import WatchlistButton from './WatchlistButton'
2024-03-17 17:46:52 -07:00
import TableRatesDisplay from '@components/shared/TableRatesDisplay'
2023-10-04 04:52:39 -07:00
const SpotCards = ({ tokens }: { tokens: BankWithMarketData[] }) => {
const { t } = useTranslation(['common', 'explore', 'trade'])
const { group } = useMangoGroup()
2023-10-04 16:04:51 -07:00
const { theme } = useThemeWrapper()
2023-10-04 04:52:39 -07:00
const router = useRouter()
return (
<div className="grid grid-cols-12 gap-4 px-4 py-6 md:px-6 2xl:px-12">
{tokens.map((token) => {
const { bank } = token
const availableVaultBalance = group
? group.getTokenVaultBalanceByMintUi(bank.mint) -
bank.uiDeposits() * bank.minVaultToDepositsRatio
: 0
const available = Decimal.max(
0,
availableVaultBalance.toFixed(bank.mintDecimals),
2023-11-07 15:27:12 -08:00
).mul(bank.uiPrice)
2023-10-04 04:52:39 -07:00
const depositRate = bank.getDepositRateUi()
const borrowRate = bank.getBorrowRateUi()
2023-12-18 20:10:21 -08:00
const chartData = token?.market?.priceHistory?.length
? token.market.priceHistory
?.sort((a, b) => a.time - b.time)
.concat([{ price: bank.uiPrice, time: Date.now() }])
: []
2023-10-06 03:33:15 -07:00
const volume = token.market?.marketData?.quote_volume_24h || 0
2023-12-18 20:10:21 -08:00
const change = token.market?.rollingChange || 0
2023-10-06 03:33:15 -07:00
2023-10-04 04:52:39 -07:00
return (
<div
className="col-span-12 rounded-lg border border-th-bkg-3 p-6 md:col-span-6 xl:col-span-4 2xl:col-span-3"
key={bank.tokenIndex}
>
2023-10-04 16:04:51 -07:00
<div className="mb-4 flex items-center justify-between border-b border-th-bkg-3 pb-4">
<div className="flex items-center space-x-3">
<TokenLogo bank={bank} size={32} showRewardsLogo />
2023-10-04 16:04:51 -07:00
<div>
<h3 className="mb-1 text-base leading-none">
{bank.name}
<span className="ml-1.5">
<TokenReduceOnlyDesc bank={bank} />
</span>
</h3>
2023-12-18 20:10:21 -08:00
{bank.uiPrice ? (
<div className="flex items-center space-x-3">
<span className="font-mono">
<FormatNumericValue value={bank.uiPrice} isUsd />
</span>
{token.market ? (
<Change change={change} suffix="%" />
) : null}
</div>
) : null}
2023-10-04 04:52:39 -07:00
</div>
</div>
2024-03-14 21:24:18 -07:00
<div className="flex items-center space-x-3">
{chartData.length ? (
<div className="h-10 w-20">
<SimpleAreaChart
color={
chartData[0].price <= bank.uiPrice
? COLORS.UP[theme]
: COLORS.DOWN[theme]
}
data={chartData}
name={bank.name}
xKey="time"
yKey="price"
/>
</div>
) : null}
<WatchlistButton tokenIndex={bank.tokenIndex} />
</div>
2023-10-04 04:52:39 -07:00
</div>
<div className="grid grid-cols-2 gap-4">
<div>
2023-10-04 16:04:51 -07:00
<p className="mb-1">{t('trade:24h-volume')}</p>
2023-10-04 04:52:39 -07:00
<p className="font-mono text-th-fgd-2">
{!token.market ? (
''
2023-12-18 20:10:21 -08:00
) : volume ? (
2023-10-04 04:52:39 -07:00
<span>
2023-12-18 20:10:21 -08:00
{numberCompacter.format(volume)}{' '}
2023-10-04 04:52:39 -07:00
<span className="font-body text-th-fgd-4">USDC</span>
</span>
) : (
<span>
0 <span className="font-body text-th-fgd-4">USDC</span>
</span>
)}
</p>
</div>
<div>
2023-10-04 16:04:51 -07:00
<Tooltip
content={t('tooltip-available', { token: bank.name })}
placement="top-start"
>
<p className="tooltip-underline mb-1">{t('available')}</p>
</Tooltip>
2023-10-04 04:52:39 -07:00
<span className="font-mono text-th-fgd-2">
2023-11-07 15:27:12 -08:00
<FormatNumericValue value={available} isUsd />
2023-10-04 04:52:39 -07:00
</span>
</div>
<div>
2023-10-04 16:04:51 -07:00
<Tooltip
2023-10-10 19:39:06 -07:00
content={t('tooltip-collateral-weight', { token: bank.name })}
2023-10-04 16:04:51 -07:00
placement="top-start"
>
<p className="tooltip-underline mb-1">
{t('explore:collateral-weight')}
</p>
</Tooltip>
<span className="font-mono text-th-fgd-2">
<CollateralWeightDisplay bank={bank} />
</span>
2023-10-04 04:52:39 -07:00
</div>
<div>
2023-10-04 16:04:51 -07:00
<Tooltip
content={t('tooltip-interest-rates')}
placement="top-start"
>
<p className="tooltip-underline mb-1">{t('rates')}</p>
</Tooltip>
2023-10-04 04:52:39 -07:00
<div className="flex space-x-1.5 font-mono">
2024-03-17 17:46:52 -07:00
<TableRatesDisplay
borrowRate={borrowRate}
depositRate={depositRate}
/>
2023-10-04 04:52:39 -07:00
</div>
</div>
<Button
className="mt-3"
onClick={() => goToTokenPage(bank.name.split(' ')[0], router)}
secondary
>
{t('details')}
</Button>
<div className="relative mt-3">
<ActionsMenu bank={bank} showText />
</div>
</div>
</div>
)
})}
</div>
)
}
export default SpotCards