2022-08-23 15:33:09 -07:00
import { Transition } from '@headlessui/react'
2022-09-06 21:36:35 -07:00
import {
ChevronDownIcon ,
QuestionMarkCircleIcon ,
} from '@heroicons/react/20/solid'
2022-08-23 15:33:09 -07:00
import { useTranslation } from 'next-i18next'
import Image from 'next/image'
import { Fragment , useMemo , useState } from 'react'
import { useViewport } from '../../hooks/useViewport'
2022-09-12 08:53:57 -07:00
import mangoStore from '@store/mangoStore'
2022-08-23 15:33:09 -07:00
import { formatDecimal , formatFixedDecimals } from '../../utils/numbers'
import { breakpoints } from '../../utils/theme'
import { IconButton } from '../shared/Button'
import ContentBox from '../shared/ContentBox'
2022-08-24 20:55:55 -07:00
import FlipNumbers from 'react-flip-numbers'
2022-09-24 05:28:11 -07:00
import Tooltip from '@components/shared/Tooltip'
2022-08-23 15:33:09 -07:00
const TokenList = ( ) = > {
const { t } = useTranslation ( 'common' )
const [ showTokenDetails , setShowTokenDetails ] = useState ( '' )
const group = mangoStore ( ( s ) = > s . group )
const jupiterTokens = mangoStore ( ( s ) = > s . jupiterTokens )
const { width } = useViewport ( )
const showTableView = width ? width > breakpoints.md : false
const banks = useMemo ( ( ) = > {
if ( group ) {
const rawBanks = Array . from ( group ? . banksMapByName , ( [ key , value ] ) = > ( {
key ,
value ,
} ) )
return rawBanks
}
return [ ]
} , [ group ] )
const handleShowTokenDetails = ( name : string ) = > {
showTokenDetails ? setShowTokenDetails ( '' ) : setShowTokenDetails ( name )
}
2022-08-24 20:55:55 -07:00
const [ totalDepositValue , totalBorrowValue ] = useMemo ( ( ) = > {
if ( banks . length ) {
return [
banks . reduce (
2022-08-31 13:17:17 -07:00
( a , c ) = > a + c . value [ 0 ] . uiPrice ! * c . value [ 0 ] . uiDeposits ( ) ,
2022-08-24 20:55:55 -07:00
0
) ,
banks . reduce (
2022-08-31 13:17:17 -07:00
( a , c ) = > a + c . value [ 0 ] . uiPrice ! * c . value [ 0 ] . uiBorrows ( ) ,
2022-08-24 20:55:55 -07:00
0
) ,
]
}
return [ ]
} , [ banks ] )
2022-08-23 15:33:09 -07:00
return (
2022-09-14 19:41:55 -07:00
< ContentBox hideBorder hidePadding >
2022-09-18 23:26:42 -07:00
< div className = "grid grid-cols-2 gap-x-6 border-b border-th-bkg-3 text-[40px]" >
< div className = "col-span-2 border-t border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-t-0 " >
2022-10-07 16:39:06 -07:00
< p className = "mb-2.5 text-base leading-none" >
{ t ( 'total-deposit-value' ) }
< / p >
2022-08-24 20:55:55 -07:00
< div className = "flex items-center font-bold" >
< FlipNumbers
2022-09-14 19:41:55 -07:00
height = { 40 }
width = { 24 }
2022-08-24 20:55:55 -07:00
play
delay = { 0.05 }
duration = { 1 }
numbers = { formatFixedDecimals ( totalDepositValue ! , true ) }
/ >
< / div >
< / div >
2022-09-18 23:26:42 -07:00
< div className = "col-span-2 border-t border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-l md:border-t-0 md:pl-6" >
2022-10-07 16:39:06 -07:00
< p className = "mb-2.5 text-base leading-none" >
{ t ( 'total-borrow-value' ) }
< / p >
2022-08-24 20:55:55 -07:00
< div className = "flex items-center font-bold" >
< FlipNumbers
2022-09-14 19:41:55 -07:00
height = { 40 }
width = { 24 }
2022-08-24 20:55:55 -07:00
play
delay = { 0.05 }
duration = { 1 }
numbers = { formatFixedDecimals ( totalBorrowValue ! , true ) }
/ >
< / div >
< / div >
< / div >
2022-08-23 15:33:09 -07:00
{ showTableView ? (
< table className = "-mt-1 min-w-full" >
< thead >
< tr >
< th className = "text-left" > { t ( 'token' ) } < / th >
< th className = "text-right" > { t ( 'price' ) } < / th >
2022-08-24 20:55:55 -07:00
< th className = "text-right" > { t ( 'total-deposits' ) } < / th >
< th className = "text-right" > { t ( 'total-borrows' ) } < / th >
2022-09-25 17:37:04 -07:00
< th >
< div className = "flex justify-end" >
< Tooltip content = "The deposit rate (green) will automatically be paid on positive balances and the borrow rate (red) will automatically be charged on negative balances." >
< span className = "tooltip-underline" > { t ( 'rates' ) } < / span >
< / Tooltip >
< / div >
2022-08-23 15:33:09 -07:00
< / th >
2022-09-25 17:37:04 -07:00
< th >
< div className = "flex justify-end" >
< Tooltip content = "The percentage of deposits that have been lent out." >
< span className = "tooltip-underline" >
{ t ( 'utilization' ) }
< / span >
< / Tooltip >
< / div >
2022-08-23 15:33:09 -07:00
< / th >
2022-09-25 17:37:04 -07:00
< th >
< div className = "flex justify-end" >
< Tooltip content = { t ( 'asset-weight-desc' ) } >
< span className = "tooltip-underline" >
{ t ( 'asset-weight' ) }
< / span >
< / Tooltip >
< / div >
2022-08-23 16:49:36 -07:00
< / th >
2022-08-24 20:55:55 -07:00
< th >
< div className = "flex items-center justify-end" >
2022-09-18 23:26:42 -07:00
< span className = "text-right" > { t ( 'liability-weight' ) } < / span >
2022-08-23 15:33:09 -07:00
< / div >
< / th >
< / tr >
< / thead >
< tbody >
{ banks . map ( ( { key , value } ) = > {
const bank = value [ 0 ]
const oraclePrice = bank . uiPrice
let logoURI
if ( jupiterTokens . length ) {
logoURI = jupiterTokens . find (
( t ) = > t . address === bank . mint . toString ( )
) ! . logoURI
}
return (
< tr key = { key } >
2022-08-24 20:55:55 -07:00
< td >
2022-08-23 15:33:09 -07:00
< div className = "flex items-center" >
< div className = "mr-2.5 flex flex-shrink-0 items-center" >
{ logoURI ? (
2022-09-18 23:26:42 -07:00
< Image alt = "" width = "24" height = "24" src = { logoURI } / >
2022-08-23 15:33:09 -07:00
) : (
2022-09-18 23:26:42 -07:00
< QuestionMarkCircleIcon className = "h-6 w-6 text-th-fgd-3" / >
2022-08-23 15:33:09 -07:00
) }
< / div >
2022-09-18 23:26:42 -07:00
< p className = "font-body tracking-wide" > { bank . name } < / p >
2022-08-23 15:33:09 -07:00
< / div >
< / td >
2022-08-24 20:55:55 -07:00
< td >
2022-08-23 15:33:09 -07:00
< div className = "flex flex-col text-right" >
2022-08-31 13:17:17 -07:00
< p > { formatFixedDecimals ( oraclePrice ! , true ) } < / p >
2022-08-23 15:33:09 -07:00
< / div >
< / td >
2022-08-24 20:55:55 -07:00
< td >
2022-08-23 15:33:09 -07:00
< div className = "flex flex-col text-right" >
< p > { formatFixedDecimals ( bank . uiDeposits ( ) ) } < / p >
< / div >
< / td >
2022-08-24 20:55:55 -07:00
< td >
2022-08-23 15:33:09 -07:00
< div className = "flex flex-col text-right" >
< p > { formatFixedDecimals ( bank . uiBorrows ( ) ) } < / p >
< / div >
< / td >
2022-08-24 20:55:55 -07:00
< td >
2022-09-24 05:28:11 -07:00
< div className = "flex justify-end space-x-2" >
2022-08-23 15:33:09 -07:00
< p className = "text-th-green" >
{ formatDecimal ( bank . getDepositRateUi ( ) , 2 , {
fixed : true ,
} ) }
%
< / p >
< span className = "text-th-fgd-4" > | < / span >
< p className = "text-th-red" >
{ formatDecimal ( bank . getBorrowRateUi ( ) , 2 , {
fixed : true ,
} ) }
%
< / p >
< / div >
< / td >
< td >
2022-08-24 20:55:55 -07:00
< div className = "flex flex-col text-right" >
< p >
{ bank . uiDeposits ( ) > 0
? formatDecimal (
( bank . uiBorrows ( ) / bank . uiDeposits ( ) ) * 100 ,
1 ,
{ fixed : true }
)
: '0.0' }
%
< / p >
< / div >
< / td >
< td >
< div className = "text-right" >
2022-08-23 16:49:36 -07:00
< p > { bank . initAssetWeight . toFixed ( 2 ) } < / p >
< / div >
< / td >
< td >
2022-08-24 20:55:55 -07:00
< div className = "text-right" >
2022-08-23 16:49:36 -07:00
< p > { bank . initLiabWeight . toFixed ( 2 ) } < / p >
2022-08-23 15:33:09 -07:00
< / div >
< / td >
< / tr >
)
} ) }
< / tbody >
< / table >
) : (
2022-09-18 23:26:42 -07:00
< div >
2022-08-23 15:33:09 -07:00
{ banks . map ( ( { key , value } ) = > {
const bank = value [ 0 ]
const oraclePrice = bank . uiPrice
let logoURI
if ( jupiterTokens . length ) {
logoURI = jupiterTokens . find (
( t ) = > t . address === bank . mint . toString ( )
) ! . logoURI
}
return (
2022-09-18 23:26:42 -07:00
< div key = { key } className = "border-b border-th-bkg-3 px-6 py-4" >
2022-08-23 15:33:09 -07:00
< div className = "flex items-center justify-between" >
< div className = "flex items-center" >
< div className = "mr-2.5 flex flex-shrink-0 items-center" >
{ logoURI ? (
< Image alt = "" width = "24" height = "24" src = { logoURI } / >
) : (
< QuestionMarkCircleIcon className = "h-7 w-7 text-th-fgd-3" / >
) }
< / div >
2022-09-18 23:26:42 -07:00
< p className = "text-th-fgd-1" > { bank . name } < / p >
< / div >
< div className = "flex items-center space-x-4" >
2022-08-23 15:33:09 -07:00
< div >
2022-09-18 23:26:42 -07:00
< p className = "text-right text-xs" >
{ t ( 'total-deposits' ) }
< / p >
< p className = "text-right font-mono text-th-fgd-1" >
{ formatFixedDecimals ( bank . uiDeposits ( ) ) }
< / p >
< / div >
< div >
< p className = "text-right text-xs" > { t ( 'total-borrows' ) } < / p >
< p className = "text-right font-mono text-th-fgd-1" >
{ formatFixedDecimals ( bank . uiBorrows ( ) ) }
< / p >
2022-08-23 15:33:09 -07:00
< / div >
< IconButton
onClick = { ( ) = > handleShowTokenDetails ( bank . name ) }
>
< ChevronDownIcon
className = { ` ${
showTokenDetails === bank . name
? 'rotate-180'
: 'rotate-360'
} h - 6 w - 6 flex - shrink - 0 text - th - fgd - 1 ` }
/ >
< / IconButton >
< / div >
< / div >
< Transition
appear = { true }
show = { showTokenDetails === bank . name }
as = { Fragment }
enter = "transition ease-in duration-200"
enterFrom = "opacity-0"
enterTo = "opacity-100"
leave = "transition ease-out"
leaveFrom = "opacity-100"
leaveTo = "opacity-0"
>
< div className = "mt-4 grid grid-cols-2 gap-4 border-t border-th-bkg-3 pt-4" >
< div className = "col-span-1" >
< p className = "text-xs text-th-fgd-3" > { t ( 'price' ) } < / p >
2022-09-18 23:26:42 -07:00
< p className = "font-mono text-th-fgd-1" >
2022-08-31 13:17:17 -07:00
$ { formatDecimal ( oraclePrice ! , 2 ) }
2022-08-23 15:33:09 -07:00
< / p >
< / div >
< div className = "col-span-1" >
< p className = "text-xs text-th-fgd-3" > { t ( 'rates' ) } < / p >
2022-09-18 23:26:42 -07:00
< p className = "space-x-2" >
< span className = "font-mono text-th-green" >
2022-08-23 15:33:09 -07:00
{ formatDecimal ( bank . getDepositRate ( ) . toNumber ( ) , 2 ) } %
< / span >
< span className = "font-normal text-th-fgd-4" > | < / span >
2022-09-18 23:26:42 -07:00
< span className = "font-mono text-th-red" >
2022-08-23 15:33:09 -07:00
{ formatDecimal ( bank . getBorrowRate ( ) . toNumber ( ) , 2 ) } %
< / span >
< / p >
< / div >
< div className = "col-span-1" >
2022-09-18 23:26:42 -07:00
< p className = "text-xs text-th-fgd-3" >
{ t ( 'utilization' ) }
< / p >
< p className = "font-mono text-th-fgd-1" >
{ bank . uiDeposits ( ) > 0
? formatDecimal (
( bank . uiBorrows ( ) / bank . uiDeposits ( ) ) * 100 ,
1 ,
{ fixed : true }
)
: '0.0' }
%
< / p >
< / div >
< div className = "col-span-1" >
< p className = "text-xs text-th-fgd-3" >
{ t ( 'asset-weight' ) }
< / p >
< p className = "font-mono text-th-fgd-1" >
{ bank . initAssetWeight . toFixed ( 2 ) }
< / p >
< / div >
< div className = "col-span-1" >
< p className = "text-xs text-th-fgd-3" >
{ t ( 'liability-weight' ) }
< / p >
< p className = "font-mono text-th-fgd-1" >
{ bank . initLiabWeight . toFixed ( 2 ) }
2022-08-23 15:33:09 -07:00
< / p >
< / div >
< / div >
< / Transition >
< / div >
)
} ) }
< / div >
) }
< / ContentBox >
)
}
export default TokenList