Merge pull request #129 from blockworks-foundation/max/switch-market-mobile
make market selectable on mobile when clicking market name
This commit is contained in:
commit
813ad801e0
|
@ -1,14 +1,7 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import {
|
||||
ChartBarIcon,
|
||||
CurrencyDollarIcon,
|
||||
CalculatorIcon,
|
||||
} from '@heroicons/react/solid'
|
||||
import { ChartBarIcon, CurrencyDollarIcon } from '@heroicons/react/solid'
|
||||
import { BtcMonoIcon, TradeIcon } from '../icons'
|
||||
import useMangoGroupConfig from '../../hooks/useMangoGroupConfig'
|
||||
import MarketsModal from '../MarketsModal'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
const StyledBarItemLabel = ({ children, ...props }) => (
|
||||
|
@ -19,36 +12,25 @@ const StyledBarItemLabel = ({ children, ...props }) => (
|
|||
|
||||
const BottomBar = () => {
|
||||
const { t } = useTranslation('common')
|
||||
const [showMarketsModal, setShowMarketsModal] = useState(false)
|
||||
const [sortedMarkets, setSortedMarkets] = useState([])
|
||||
const { asPath } = useRouter()
|
||||
const groupConfig = useMangoGroupConfig()
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
setSortedMarkets(markets)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="bg-th-bkg-1 default-transition grid grid-cols-5 grid-rows-1 py-2.5">
|
||||
<div
|
||||
className="col-span-1 cursor-pointer default-transition flex flex-col items-center text-th-fgd-3 hover:text-th-primary"
|
||||
onClick={() => setShowMarketsModal(true)}
|
||||
<div className="bg-th-bkg-1 default-transition grid grid-cols-4 grid-rows-1 py-2.5">
|
||||
<Link
|
||||
href={{
|
||||
pathname: '/select',
|
||||
}}
|
||||
>
|
||||
<BtcMonoIcon className="h-4 mb-1 w-4" />
|
||||
<StyledBarItemLabel>{t('markets')}</StyledBarItemLabel>
|
||||
</div>
|
||||
<div
|
||||
className={`${
|
||||
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
|
||||
href={{
|
||||
pathname: '/market',
|
||||
|
@ -58,7 +40,7 @@ const BottomBar = () => {
|
|||
>
|
||||
<div
|
||||
className={`${
|
||||
asPath === '/' || asPath.includes('market')
|
||||
asPath === '/' || asPath.startsWith('/market')
|
||||
? 'text-th-primary'
|
||||
: 'text-th-fgd-3'
|
||||
} col-span-1 cursor-pointer default-transition flex flex-col items-center hover:text-th-primary`}
|
||||
|
@ -87,26 +69,7 @@ const BottomBar = () => {
|
|||
<StyledBarItemLabel>{t('stats')}</StyledBarItemLabel>
|
||||
</div>
|
||||
</Link>
|
||||
<Link href="/risk-calculator">
|
||||
<div
|
||||
className={`${
|
||||
asPath === '/risk-calculator'
|
||||
? 'text-th-primary'
|
||||
: 'text-th-fgd-3'
|
||||
} col-span-1 cursor-pointer default-transition flex flex-col items-center hover:text-th-primary`}
|
||||
>
|
||||
<CalculatorIcon className="h-4 mb-1 w-4" />
|
||||
<StyledBarItemLabel>{t('calculator')}</StyledBarItemLabel>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
{showMarketsModal ? (
|
||||
<MarketsModal
|
||||
isOpen={showMarketsModal}
|
||||
onClose={() => setShowMarketsModal(false)}
|
||||
markets={sortedMarkets}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import RecentMarketTrades from '../RecentMarketTrades'
|
|||
import FloatingElement from '../FloatingElement'
|
||||
import Swipeable from './Swipeable'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Link from 'next/link'
|
||||
|
||||
const TVChartContainer = dynamic(
|
||||
() => import('../../components/TradingView/index'),
|
||||
|
@ -54,27 +55,29 @@ const MobileTradePage = () => {
|
|||
return (
|
||||
<div className="pb-14 pt-4 px-2">
|
||||
<div className="relative">
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
alt=""
|
||||
width="30"
|
||||
height="30"
|
||||
src={`/assets/icons/${baseSymbol.toLowerCase()}.svg`}
|
||||
className="mr-2"
|
||||
/>
|
||||
<Link href="/select">
|
||||
<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}
|
||||
<img
|
||||
alt=""
|
||||
width="30"
|
||||
height="30"
|
||||
src={`/assets/icons/${baseSymbol.toLowerCase()}.svg`}
|
||||
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>
|
||||
<span className="border border-th-primary ml-2 px-1 py-0.5 rounded text-xs text-th-primary">
|
||||
{initLeverage}x
|
||||
</span>
|
||||
</div>
|
||||
<span className="border border-th-primary ml-2 px-1 py-0.5 rounded text-xs text-th-primary">
|
||||
{initLeverage}x
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
<Disclosure>
|
||||
{({ open }) => (
|
||||
<>
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { ChevronRightIcon } from '@heroicons/react/solid'
|
||||
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([])
|
||||
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)
|
||||
}, [])
|
||||
|
||||
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>
|
||||
</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>
|
||||
<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
|
Loading…
Reference in New Issue