mango-v4-ui/components/trade/AdvancedMarketHeader.tsx

183 lines
6.0 KiB
TypeScript
Raw Normal View History

2022-09-13 23:24:26 -07:00
import { Serum3Market } from '@blockworks-foundation/mango-v4'
import PercentageChange from '@components/shared/PercentageChange'
import { Popover } from '@headlessui/react'
2022-09-26 04:53:49 -07:00
import { ChevronDownIcon } from '@heroicons/react/20/solid'
2022-09-13 23:24:26 -07:00
import mangoStore from '@store/mangoStore'
import { useTranslation } from 'next-i18next'
import { useCallback, useMemo } from 'react'
import { DEFAULT_MARKET_NAME } from 'utils/constants'
import { formatFixedDecimals } from 'utils/numbers'
2022-09-26 04:53:49 -07:00
import MarketLogos from './MarketLogos'
2022-09-13 23:24:26 -07:00
const MarketSelectDropdown = () => {
const selectedMarket = mangoStore((s) => s.selectedMarket.current)
const serumMarkets = mangoStore((s) => s.serumMarkets)
2022-09-25 20:12:37 -07:00
const jupiterTokens = mangoStore((s) => s.jupiterTokens)
2022-09-26 04:53:49 -07:00
const group = mangoStore((s) => s.group)
2022-09-13 23:24:26 -07:00
const set = mangoStore((s) => s.set)
const handleSelectMarket = useCallback(
(market: Serum3Market, close: any) => {
set((s) => {
s.selectedMarket.current = market
})
close()
},
[set]
)
2022-09-25 20:12:37 -07:00
const [baseLogoURI, quoteLogoURI] = useMemo(() => {
2022-09-26 04:53:49 -07:00
if (jupiterTokens.length && selectedMarket && group) {
const baseSymbol = group.getFirstBankByTokenIndex(
selectedMarket.baseTokenIndex
).name
const quoteSymbol = group.getFirstBankByTokenIndex(
selectedMarket.quoteTokenIndex
).name
2022-09-25 20:12:37 -07:00
const baseURI = jupiterTokens.find(
2022-09-26 04:53:49 -07:00
(t) => t.symbol === baseSymbol
2022-09-25 20:12:37 -07:00
)!.logoURI
const quoteURI = jupiterTokens.find(
2022-09-26 04:53:49 -07:00
(t) => t.symbol === quoteSymbol
2022-09-25 20:12:37 -07:00
)!.logoURI
return [baseURI, quoteURI]
} else {
return ['', '']
}
}, [jupiterTokens, selectedMarket])
2022-09-13 23:24:26 -07:00
return (
<Popover>
{({ close, open }) => (
<div className="relative flex flex-col overflow-visible">
2022-09-25 20:12:37 -07:00
<Popover.Button className="default-transition flex w-full items-center justify-between hover:text-th-primary">
<MarketLogos baseURI={baseLogoURI} quoteURI={quoteLogoURI} />
2022-09-16 03:49:10 -07:00
<div className="text-xl font-bold md:text-base">
2022-09-14 21:12:00 -07:00
{selectedMarket?.name || DEFAULT_MARKET_NAME}
2022-09-13 23:24:26 -07:00
</div>
<ChevronDownIcon
className={`${
open ? 'rotate-180' : 'rotate-360'
2022-09-14 21:12:00 -07:00
} mt-0.5 ml-2 h-6 w-6 flex-shrink-0 text-th-fgd-3`}
2022-09-13 23:24:26 -07:00
/>
</Popover.Button>
2022-09-25 23:18:33 -07:00
<Popover.Panel className="absolute -left-5 top-[46px] z-50 mr-4 w-screen border border-l-0 border-th-bkg-3 bg-th-bkg-1 py-2 sm:w-56 md:top-[37px]">
2022-09-13 23:24:26 -07:00
{serumMarkets?.length
2022-09-25 20:12:37 -07:00
? serumMarkets.map((m) => {
let baseLogoURI = ''
let quoteLogoURI = ''
2022-09-26 04:53:49 -07:00
const baseSymbol = group?.getFirstBankByTokenIndex(
m.baseTokenIndex
).name
const quoteSymbol = group?.getFirstBankByTokenIndex(
m.quoteTokenIndex
).name
2022-09-25 20:12:37 -07:00
if (jupiterTokens.length) {
baseLogoURI = jupiterTokens.find(
2022-09-26 04:53:49 -07:00
(t) => t.symbol === baseSymbol
2022-09-25 20:12:37 -07:00
)!.logoURI
quoteLogoURI = jupiterTokens.find(
2022-09-26 04:53:49 -07:00
(t) => t.symbol === quoteSymbol
2022-09-25 20:12:37 -07:00
)!.logoURI
}
return (
<div
key={m.publicKey.toString()}
className="flex items-center bg-th-bkg-1 py-2 px-4 hover:cursor-pointer hover:bg-th-bkg-2"
onClick={() => handleSelectMarket(m, close)}
>
<MarketLogos
baseURI={baseLogoURI}
quoteURI={quoteLogoURI}
/>
2022-09-25 23:18:33 -07:00
<span
className={
m.name === selectedMarket?.name
? 'text-th-primary'
: ''
}
>
{m.name}
</span>
2022-09-25 20:12:37 -07:00
</div>
)
})
2022-09-13 23:24:26 -07:00
: null}
</Popover.Panel>
</div>
)}
</Popover>
)
}
const OraclePrice = () => {
const group = mangoStore((s) => s.group)
const selectedMarket = mangoStore((s) => s.selectedMarket.current)
if (!group || !selectedMarket) return null
const baseTokenBank = group.getFirstBankByTokenIndex(
selectedMarket?.baseTokenIndex
)
return (
2022-09-16 03:49:10 -07:00
<div className="font-mono text-xs text-th-fgd-1">
2022-09-13 23:24:26 -07:00
$
{baseTokenBank.uiPrice
? formatFixedDecimals(baseTokenBank.uiPrice)
: null}
</div>
)
}
const AdvancedMarketHeader = () => {
const { t } = useTranslation('common')
const selectedMarket = mangoStore((s) => s.selectedMarket.current)
const coingeckoPrices = mangoStore((s) => s.coingeckoPrices.data)
const baseSymbol = useMemo(() => {
return selectedMarket?.name.split('/')[0]
}, [selectedMarket])
const coingeckoData = coingeckoPrices.find((asset) =>
baseSymbol === 'soETH'
? asset.symbol === 'ETH'
: asset.symbol === baseSymbol
)
const change = coingeckoData
? ((coingeckoData.prices[coingeckoData.prices.length - 1][1] -
coingeckoData.prices[0][1]) /
coingeckoData.prices[0][1]) *
100
: 0
return (
2022-09-16 03:49:10 -07:00
<div className="flex h-16 items-center bg-th-bkg-1 px-5 md:h-12">
<div className="md:pr-6 lg:pb-0">
2022-09-13 23:24:26 -07:00
<div className="flex items-center">
<MarketSelectDropdown />
</div>
</div>
<div className="ml-6 flex-col">
2022-09-16 03:49:10 -07:00
<div className="text-xs text-th-fgd-4">{t('oracle-price')}</div>
2022-09-13 23:24:26 -07:00
<OraclePrice />
</div>
<div className="ml-6 flex-col">
2022-09-16 03:49:10 -07:00
<div className="text-xs text-th-fgd-4">{t('rolling-change')}</div>
<PercentageChange change={change} size="small" />
{/* <div
2022-09-14 21:12:00 -07:00
className={`font-mono text-xs ${
change < 0 ? 'text-th-red' : 'text-th-gree'
}`}
2022-09-13 23:24:26 -07:00
>
{isNaN(change) ? '0.00' : change.toFixed(2)}%
</div> */}
2022-09-13 23:24:26 -07:00
</div>
</div>
)
}
export default AdvancedMarketHeader