make market selectable on mobile when clicking market name

This commit is contained in:
Maximilian Schneider 2022-01-08 21:00:35 -08:00
parent 320cd06d76
commit 2393b2426a
3 changed files with 188 additions and 36 deletions

View File

@ -1,10 +1,9 @@
import { useEffect, useState } from 'react' import { useEffect } from 'react'
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { ChartBarIcon, CurrencyDollarIcon } from '@heroicons/react/solid' import { ChartBarIcon, CurrencyDollarIcon } from '@heroicons/react/solid'
import { BtcMonoIcon, TradeIcon } from '../icons' import { BtcMonoIcon, TradeIcon } from '../icons'
import useMangoGroupConfig from '../../hooks/useMangoGroupConfig' import useMangoGroupConfig from '../../hooks/useMangoGroupConfig'
import MarketsModal from '../MarketsModal'
import { useTranslation } from 'next-i18next' import { useTranslation } from 'next-i18next'
const StyledBarItemLabel = ({ children, ...props }) => ( const StyledBarItemLabel = ({ children, ...props }) => (
@ -15,8 +14,6 @@ const StyledBarItemLabel = ({ children, ...props }) => (
const BottomBar = () => { const BottomBar = () => {
const { t } = useTranslation('common') const { t } = useTranslation('common')
const [showMarketsModal, setShowMarketsModal] = useState(false)
const [sortedMarkets, setSortedMarkets] = useState([])
const { asPath } = useRouter() const { asPath } = useRouter()
const groupConfig = useMangoGroupConfig() const groupConfig = useMangoGroupConfig()
@ -38,13 +35,20 @@ const BottomBar = () => {
return ( return (
<> <>
<div className="bg-th-bkg-1 default-transition grid grid-cols-4 grid-rows-1 py-2.5"> <div className="bg-th-bkg-1 default-transition grid grid-cols-4 grid-rows-1 py-2.5">
<div <Link
className="col-span-1 cursor-pointer default-transition flex flex-col items-center text-th-fgd-3 hover:text-th-primary" href={{
onClick={() => setShowMarketsModal(true)} pathname: '/select',
}}
> >
<BtcMonoIcon className="h-4 mb-1 w-4" /> <div
<StyledBarItemLabel>{t('markets')}</StyledBarItemLabel> className={`${
</div> asPath === '/select' ? 'text-th-primary' : 'text-th-fgd-3'
} col-span-1 cursor-pointer default-transition flex flex-col items-center hover:text-th-primary`}
>
<BtcMonoIcon className="h-4 mb-1 w-4" />
<StyledBarItemLabel>{t('markets')}</StyledBarItemLabel>
</div>
</Link>
<Link <Link
href={{ href={{
pathname: '/market', pathname: '/market',
@ -54,7 +58,7 @@ const BottomBar = () => {
> >
<div <div
className={`${ className={`${
asPath === '/' || asPath.includes('market') asPath === '/' || asPath.startsWith('/market')
? 'text-th-primary' ? 'text-th-primary'
: 'text-th-fgd-3' : 'text-th-fgd-3'
} col-span-1 cursor-pointer default-transition flex flex-col items-center hover:text-th-primary`} } col-span-1 cursor-pointer default-transition flex flex-col items-center hover:text-th-primary`}
@ -84,13 +88,6 @@ const BottomBar = () => {
</div> </div>
</Link> </Link>
</div> </div>
{showMarketsModal ? (
<MarketsModal
isOpen={showMarketsModal}
onClose={() => setShowMarketsModal(false)}
markets={sortedMarkets}
/>
) : null}
</> </>
) )
} }

View File

@ -16,6 +16,7 @@ import RecentMarketTrades from '../RecentMarketTrades'
import FloatingElement from '../FloatingElement' import FloatingElement from '../FloatingElement'
import Swipeable from './Swipeable' import Swipeable from './Swipeable'
import { useTranslation } from 'next-i18next' import { useTranslation } from 'next-i18next'
import Link from 'next/link'
const TVChartContainer = dynamic( const TVChartContainer = dynamic(
() => import('../../components/TradingView/index'), () => import('../../components/TradingView/index'),
@ -54,27 +55,29 @@ const MobileTradePage = () => {
return ( return (
<div className="pb-14 pt-4 px-2"> <div className="pb-14 pt-4 px-2">
<div className="relative"> <div className="relative">
<div className="flex items-center"> <Link href="/select">
<img
alt=""
width="30"
height="30"
src={`/assets/icons/${baseSymbol.toLowerCase()}.svg`}
className="mr-2"
/>
<div className="flex items-center"> <div className="flex items-center">
<div className="font-semibold pr-0.5 text-xl">{baseSymbol}</div> <img
<span className="text-th-fgd-4 text-xl"> alt=""
{isPerpMarket ? '-' : '/'} width="30"
</span> height="30"
<div className="font-semibold pl-0.5 text-xl"> src={`/assets/icons/${baseSymbol.toLowerCase()}.svg`}
{isPerpMarket ? 'PERP' : groupConfig.quoteSymbol} className="mr-2"
/>
<div className="flex items-center">
<div className="font-semibold pr-0.5 text-xl">{baseSymbol}</div>
<span className="text-th-fgd-4 text-xl">
{isPerpMarket ? '-' : '/'}
</span>
<div className="font-semibold pl-0.5 text-xl">
{isPerpMarket ? 'PERP' : groupConfig.quoteSymbol}
</div>
</div> </div>
<span className="border border-th-primary ml-2 px-1 py-0.5 rounded text-xs text-th-primary">
{initLeverage}x
</span>
</div> </div>
<span className="border border-th-primary ml-2 px-1 py-0.5 rounded text-xs text-th-primary"> </Link>
{initLeverage}x
</span>
</div>
<Disclosure> <Disclosure>
{({ open }) => ( {({ open }) => (
<> <>

152
pages/select.tsx Normal file
View File

@ -0,0 +1,152 @@
import { useTranslation } from 'next-i18next'
import { useEffect, useState } from 'react'
import { EyeIcon, EyeOffIcon } from '@heroicons/react/outline'
import { ChevronRightIcon } from '@heroicons/react/solid'
import useLocalStorageState from '../hooks/useLocalStorageState'
import useMangoGroupConfig from '../hooks/useMangoGroupConfig'
import useMangoStore from '../stores/useMangoStore'
import Link from 'next/link'
import { formatUsdValue } from '../utils'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
export async function getStaticProps({ locale }) {
return {
props: {
...(await serverSideTranslations(locale, ['common', 'tv-chart'])),
// Will be passed to the page component as props
},
}
}
const SelectMarket = () => {
const { t } = useTranslation('common')
const groupConfig = useMangoGroupConfig()
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache)
const [markets, setMarkets] = useState([])
const [hiddenMarkets, setHiddenMarkets] = useLocalStorageState(
'hiddenMarkets',
[]
)
useEffect(() => {
const markets = []
const allMarkets = [...groupConfig.spotMarkets, ...groupConfig.perpMarkets]
allMarkets.forEach((market) => {
const base = market.name.slice(0, -5)
const found = markets.find((b) => b.baseAsset === base)
if (!found) {
markets.push({ baseAsset: base, markets: [market] })
} else {
found.markets.push(market)
}
})
setMarkets(markets)
}, [])
const handleHideShowMarket = (asset) => {
if (hiddenMarkets.includes(asset)) {
setHiddenMarkets(hiddenMarkets.filter((m) => m !== asset))
} else {
setHiddenMarkets(hiddenMarkets.concat(asset))
}
}
return (
<div>
<div className="flex items-end justify-between pb-3 pt-2">
<div className="font-bold text-lg text-th-fgd-1">{t('markets')}</div>
{/*hiddenMarkets.length === 0 ? (
<LinkButton
className="font-normal hidden md:block mb-0.5 text-th-fgd-3 text-xs disabled:cursor-not-allowed disabled:no-underline disabled:text-th-fgd-4"
onClick={() =>
setHiddenMarkets(markets.map((mkt) => mkt.baseAsset))
}
>
{t('hide-all')}
</LinkButton>
) : (
<LinkButton
className="font-normal hidden md:block mb-0.5 text-th-fgd-3 text-xs disabled:cursor-not-allowed disabled:no-underline disabled:text-th-fgd-4"
onClick={() => setHiddenMarkets([])}
>
{t('show-all')}
</LinkButton>
)*/}
</div>
{markets.map((mkt) => (
<div key={mkt.baseAsset}>
<div className="bg-th-bkg-3 flex items-center justify-between px-2.5 py-2">
<div className="flex items-center">
<img
alt=""
src={`/assets/icons/${mkt.baseAsset.toLowerCase()}.svg`}
className={`h-5 mr-2.5 w-auto`}
/>
<span className="text-th-fgd-2">{mkt.baseAsset}</span>
</div>
<div className="hidden md:flex">
{hiddenMarkets.includes(mkt.baseAsset) ? (
<EyeOffIcon
className="cursor-pointer default-transition h-4 text-th-fgd-4 w-4 hover:text-th-fgd-3"
onClick={() => handleHideShowMarket(mkt.baseAsset)}
/>
) : (
<EyeIcon
className="cursor-pointer default-transition h-4 text-th-primary w-4 hover:text-th-primary-dark"
onClick={() => handleHideShowMarket(mkt.baseAsset)}
/>
)}
</div>
</div>
{/* <div className="bg-[rgba(255,255,255,0.1)] flex items-center justify-between px-2.5 py-0.5 text-th-fgd-3">
<StyledColumnHeader>Markets</StyledColumnHeader>
<div className="flex justify-between">
<StyledColumnHeader className="pr-5 text-right w-20">
Price
</StyledColumnHeader>
<StyledColumnHeader className="text-right w-20">
24h Change
</StyledColumnHeader>
<StyledColumnHeader className="text-right w-20">
24h Vol
</StyledColumnHeader>
</div>
</div> */}
<div className="divide-y divide-th-bkg-4">
{mangoGroup
? mkt.markets.map((m) => (
<div
className={`flex items-center justify-between px-2.5 text-xs`}
key={m.name}
>
<Link href={`/market?name=${m.name}`} key={m.name}>
<a className="cursor-pointer default-transition flex h-12 items-center justify-between text-th-fgd-2 hover:text-th-primary w-full">
{m.name}
<div className="flex items-center">
<span className="text-right w-20">
{formatUsdValue(
mangoGroup
.getPrice(m.marketIndex, mangoCache)
.toNumber()
)}
</span>
<ChevronRightIcon className="h-4 ml-1 w-5 text-th-fgd-2" />
</div>
</a>
</Link>
</div>
))
: null}
</div>
</div>
))}
{/* spacer so last market can be selected albeit bottom bar overlay */}
<p className="flex h-12 md:hidden"></p>
</div>
)
}
export default SelectMarket