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:
tjshipe 2022-01-11 20:34:51 -05:00 committed by GitHub
commit 813ad801e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 129 additions and 71 deletions

View File

@ -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}
</>
)
}

View File

@ -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 }) => (
<>

92
pages/select.tsx Normal file
View File

@ -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