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 Link from 'next/link'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import {
|
import { ChartBarIcon, CurrencyDollarIcon } from '@heroicons/react/solid'
|
||||||
ChartBarIcon,
|
|
||||||
CurrencyDollarIcon,
|
|
||||||
CalculatorIcon,
|
|
||||||
} from '@heroicons/react/solid'
|
|
||||||
import { BtcMonoIcon, TradeIcon } from '../icons'
|
import { BtcMonoIcon, TradeIcon } from '../icons'
|
||||||
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 }) => (
|
||||||
|
@ -19,36 +12,25 @@ 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()
|
|
||||||
|
|
||||||
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="bg-th-bkg-1 default-transition grid grid-cols-5 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',
|
||||||
|
@ -58,7 +40,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`}
|
||||||
|
@ -87,26 +69,7 @@ const BottomBar = () => {
|
||||||
<StyledBarItemLabel>{t('stats')}</StyledBarItemLabel>
|
<StyledBarItemLabel>{t('stats')}</StyledBarItemLabel>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</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>
|
</div>
|
||||||
{showMarketsModal ? (
|
|
||||||
<MarketsModal
|
|
||||||
isOpen={showMarketsModal}
|
|
||||||
onClose={() => setShowMarketsModal(false)}
|
|
||||||
markets={sortedMarkets}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 }) => (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -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