2023-07-21 05:03:44 -07:00
|
|
|
import { PerpMarket } from '@blockworks-foundation/mango-v4'
|
2023-03-28 19:01:53 -07:00
|
|
|
import { IconButton, LinkButton } from '@components/shared/Button'
|
|
|
|
import { ChartBarIcon, InformationCircleIcon } from '@heroicons/react/20/solid'
|
2023-02-09 19:20:46 -08:00
|
|
|
import mangoStore from '@store/mangoStore'
|
2022-11-20 12:20:27 -08:00
|
|
|
import useSelectedMarket from 'hooks/useSelectedMarket'
|
2022-09-13 23:24:26 -07:00
|
|
|
import { useTranslation } from 'next-i18next'
|
2023-07-21 05:03:44 -07:00
|
|
|
import { useMemo, useState } from 'react'
|
2023-04-25 13:21:32 -07:00
|
|
|
import { numberCompacter } from 'utils/numbers'
|
2022-11-30 07:46:20 -08:00
|
|
|
import MarketSelectDropdown from './MarketSelectDropdown'
|
|
|
|
import PerpFundingRate from './PerpFundingRate'
|
2023-04-03 16:20:59 -07:00
|
|
|
import SheenLoader from '@components/shared/SheenLoader'
|
2023-04-26 19:36:00 -07:00
|
|
|
import PerpMarketDetailsModal from '@components/modals/PerpMarketDetailsModal'
|
2023-04-25 13:21:32 -07:00
|
|
|
import OraclePrice from './OraclePrice'
|
2023-04-26 20:39:49 -07:00
|
|
|
import SpotMarketDetailsModal from '@components/modals/SpotMarketDetailsModal'
|
2023-07-21 05:03:44 -07:00
|
|
|
import { MarketData } from 'types'
|
2023-07-13 22:47:05 -07:00
|
|
|
import MarketChange from '@components/shared/MarketChange'
|
2023-07-21 05:03:44 -07:00
|
|
|
import useMarketsData from 'hooks/useMarketsData'
|
2023-03-04 21:47:29 -08:00
|
|
|
|
2023-01-18 18:42:29 -08:00
|
|
|
const AdvancedMarketHeader = ({
|
|
|
|
showChart,
|
|
|
|
setShowChart,
|
|
|
|
}: {
|
|
|
|
showChart?: boolean
|
|
|
|
setShowChart?: (x: boolean) => void
|
|
|
|
}) => {
|
2022-10-03 03:38:05 -07:00
|
|
|
const { t } = useTranslation(['common', 'trade'])
|
2023-07-13 22:47:05 -07:00
|
|
|
const { serumOrPerpMarket, selectedMarket } = useSelectedMarket()
|
2023-02-09 19:20:46 -08:00
|
|
|
const selectedMarketName = mangoStore((s) => s.selectedMarket.name)
|
2023-03-28 19:01:53 -07:00
|
|
|
const [showMarketDetails, setShowMarketDetails] = useState(false)
|
2023-07-21 05:03:44 -07:00
|
|
|
const { data: marketsData, isLoading, isFetching } = useMarketsData()
|
2023-03-25 11:19:57 -07:00
|
|
|
|
2023-07-21 05:03:44 -07:00
|
|
|
const volume = useMemo(() => {
|
|
|
|
if (!selectedMarketName || !serumOrPerpMarket || !marketsData) return 0
|
|
|
|
if (serumOrPerpMarket instanceof PerpMarket) {
|
|
|
|
const perpData: MarketData = marketsData?.perpData
|
|
|
|
const perpEntries = Object.entries(perpData).find(
|
2023-07-23 15:15:46 -07:00
|
|
|
(e) => e[0].toLowerCase() === selectedMarketName.toLowerCase(),
|
2023-07-21 05:03:44 -07:00
|
|
|
)
|
|
|
|
return perpEntries ? perpEntries[1][0]?.quote_volume_24h : 0
|
|
|
|
} else {
|
|
|
|
const spotData: MarketData = marketsData?.spotData
|
|
|
|
const spotEntries = Object.entries(spotData).find(
|
2023-07-23 15:15:46 -07:00
|
|
|
(e) => e[0].toLowerCase() === selectedMarketName.toLowerCase(),
|
2023-07-21 05:03:44 -07:00
|
|
|
)
|
|
|
|
return spotEntries ? spotEntries[1][0]?.quote_volume_24h : 0
|
2023-02-09 19:20:46 -08:00
|
|
|
}
|
2023-07-21 05:03:44 -07:00
|
|
|
}, [marketsData, selectedMarketName, serumOrPerpMarket])
|
2023-02-09 19:20:46 -08:00
|
|
|
|
2023-07-21 05:03:44 -07:00
|
|
|
const loadingVolume = isLoading || isFetching
|
2023-05-31 17:17:31 -07:00
|
|
|
|
2022-09-13 23:24:26 -07:00
|
|
|
return (
|
2023-03-28 19:01:53 -07:00
|
|
|
<>
|
2023-06-01 23:05:08 -07:00
|
|
|
<div
|
2023-06-06 22:00:59 -07:00
|
|
|
className={`flex flex-col bg-th-bkg-1 md:h-12 md:flex-row md:items-center`}
|
2023-06-01 23:05:08 -07:00
|
|
|
>
|
2023-04-24 04:45:30 -07:00
|
|
|
<div className="w-full pl-4 md:w-auto md:py-0 md:pl-6 lg:pb-0">
|
2023-03-28 19:01:53 -07:00
|
|
|
<MarketSelectDropdown />
|
|
|
|
</div>
|
2023-08-17 16:47:11 -07:00
|
|
|
<div className="hide-scroll flex w-full items-center justify-between overflow-x-auto border-t border-th-bkg-3 px-5 py-2 md:border-t-0 md:px-0 md:py-0 md:pr-6">
|
2023-03-28 19:01:53 -07:00
|
|
|
<div className="flex items-center">
|
2023-04-25 13:21:32 -07:00
|
|
|
<>
|
2023-07-13 22:47:05 -07:00
|
|
|
<OraclePrice />
|
2023-04-25 13:21:32 -07:00
|
|
|
</>
|
2023-03-28 19:01:53 -07:00
|
|
|
<div className="ml-6 flex-col whitespace-nowrap">
|
2023-05-11 21:08:06 -07:00
|
|
|
<div className="mb-0.5 text-xs text-th-fgd-4">
|
|
|
|
{t('rolling-change')}
|
|
|
|
</div>
|
2023-07-13 22:47:05 -07:00
|
|
|
<MarketChange market={selectedMarket} size="small" />
|
2023-01-18 18:42:29 -08:00
|
|
|
</div>
|
2023-03-28 19:01:53 -07:00
|
|
|
{serumOrPerpMarket instanceof PerpMarket ? (
|
|
|
|
<>
|
2023-06-04 18:06:03 -07:00
|
|
|
<div className="ml-6 flex-col whitespace-nowrap text-xs">
|
2023-05-31 17:17:31 -07:00
|
|
|
<div className="mb-0.5 text-th-fgd-4 ">
|
|
|
|
{t('trade:24h-volume')}
|
|
|
|
</div>
|
2023-07-21 05:03:44 -07:00
|
|
|
{loadingVolume ? (
|
|
|
|
<SheenLoader className="mt-0.5">
|
|
|
|
<div className="h-3.5 w-12 bg-th-bkg-2" />
|
|
|
|
</SheenLoader>
|
|
|
|
) : volume ? (
|
2023-05-31 17:17:31 -07:00
|
|
|
<span className="font-mono">
|
2023-07-21 05:20:12 -07:00
|
|
|
${numberCompacter.format(volume)}
|
2023-05-31 17:17:31 -07:00
|
|
|
</span>
|
|
|
|
) : (
|
2023-07-21 05:20:12 -07:00
|
|
|
<span className="font-mono">$0</span>
|
2023-05-31 17:17:31 -07:00
|
|
|
)}
|
2023-06-04 18:06:03 -07:00
|
|
|
</div>
|
2023-04-17 09:25:59 -07:00
|
|
|
<PerpFundingRate />
|
2023-03-28 19:01:53 -07:00
|
|
|
<div className="ml-6 flex-col whitespace-nowrap text-xs">
|
2023-05-11 21:08:06 -07:00
|
|
|
<div className="mb-0.5 text-th-fgd-4 ">
|
2023-03-28 19:01:53 -07:00
|
|
|
{t('trade:open-interest')}
|
|
|
|
</div>
|
|
|
|
<span className="font-mono">
|
|
|
|
$
|
|
|
|
{numberCompacter.format(
|
|
|
|
serumOrPerpMarket.baseLotsToUi(
|
2023-07-21 11:47:53 -07:00
|
|
|
serumOrPerpMarket.openInterest,
|
|
|
|
) * serumOrPerpMarket.uiPrice,
|
2023-03-28 19:01:53 -07:00
|
|
|
)}
|
|
|
|
<span className="mx-1">|</span>
|
|
|
|
{numberCompacter.format(
|
|
|
|
serumOrPerpMarket.baseLotsToUi(
|
2023-07-21 11:47:53 -07:00
|
|
|
serumOrPerpMarket.openInterest,
|
|
|
|
),
|
2023-03-28 19:01:53 -07:00
|
|
|
)}{' '}
|
|
|
|
<span className="font-body text-th-fgd-3">
|
|
|
|
{serumOrPerpMarket.name.split('-')[0]}
|
|
|
|
</span>
|
2023-03-28 16:57:59 -07:00
|
|
|
</span>
|
2023-03-28 19:01:53 -07:00
|
|
|
</div>
|
|
|
|
</>
|
2023-05-30 17:05:02 -07:00
|
|
|
) : (
|
|
|
|
<div className="ml-6 flex-col whitespace-nowrap text-xs">
|
|
|
|
<div className="mb-0.5 text-th-fgd-4 ">
|
|
|
|
{t('trade:24h-volume')}
|
|
|
|
</div>
|
2023-07-21 05:03:44 -07:00
|
|
|
{loadingVolume ? (
|
2023-05-30 17:05:02 -07:00
|
|
|
<SheenLoader className="mt-0.5">
|
|
|
|
<div className="h-3.5 w-12 bg-th-bkg-2" />
|
|
|
|
</SheenLoader>
|
2023-07-21 05:03:44 -07:00
|
|
|
) : volume ? (
|
|
|
|
<span className="font-mono">
|
|
|
|
{numberCompacter.format(volume)}{' '}
|
|
|
|
<span className="font-body text-th-fgd-3">
|
|
|
|
{selectedMarketName?.split('/')[1]}
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
) : (
|
2023-07-21 05:20:12 -07:00
|
|
|
<span className="font-mono">
|
|
|
|
0{' '}
|
|
|
|
<span className="font-body text-th-fgd-3">
|
|
|
|
{selectedMarketName?.split('/')[1]}
|
|
|
|
</span>
|
|
|
|
</span>
|
2023-05-30 17:05:02 -07:00
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
)}
|
2023-03-28 19:01:53 -07:00
|
|
|
</div>
|
|
|
|
<div className="ml-6 flex items-center space-x-4">
|
2023-04-26 20:39:49 -07:00
|
|
|
<LinkButton
|
|
|
|
className="flex items-center whitespace-nowrap text-th-fgd-3"
|
|
|
|
onClick={() => setShowMarketDetails(true)}
|
|
|
|
>
|
|
|
|
<InformationCircleIcon className="h-5 w-5 flex-shrink-0 md:mr-1.5 md:h-4 md:w-4" />
|
|
|
|
<span className="hidden text-xs md:inline">
|
|
|
|
{t('trade:market-details', { market: '' })}
|
|
|
|
</span>
|
|
|
|
</LinkButton>
|
2023-03-28 19:01:53 -07:00
|
|
|
{setShowChart ? (
|
|
|
|
<IconButton
|
|
|
|
className={showChart ? 'text-th-active' : 'text-th-fgd-2'}
|
|
|
|
onClick={() => setShowChart(!showChart)}
|
|
|
|
hideBg
|
|
|
|
>
|
|
|
|
<ChartBarIcon className="h-5 w-5" />
|
|
|
|
</IconButton>
|
|
|
|
) : null}
|
2023-03-28 16:57:59 -07:00
|
|
|
</div>
|
2023-03-28 19:01:53 -07:00
|
|
|
</div>
|
2022-12-06 21:25:37 -08:00
|
|
|
</div>
|
2023-03-28 19:01:53 -07:00
|
|
|
{showMarketDetails ? (
|
2023-04-26 20:39:49 -07:00
|
|
|
selectedMarket instanceof PerpMarket ? (
|
|
|
|
<PerpMarketDetailsModal
|
|
|
|
isOpen={showMarketDetails}
|
|
|
|
onClose={() => setShowMarketDetails(false)}
|
|
|
|
market={selectedMarket}
|
|
|
|
/>
|
|
|
|
) : (
|
|
|
|
<SpotMarketDetailsModal
|
|
|
|
isOpen={showMarketDetails}
|
|
|
|
onClose={() => setShowMarketDetails(false)}
|
|
|
|
market={selectedMarket}
|
|
|
|
/>
|
|
|
|
)
|
2023-03-28 19:01:53 -07:00
|
|
|
) : null}
|
|
|
|
</>
|
2022-09-13 23:24:26 -07:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default AdvancedMarketHeader
|