mobile styles for new features
This commit is contained in:
parent
76859b83dc
commit
659e48c99f
|
@ -1,5 +1,3 @@
|
|||
// import { useViewport } from '../hooks/useViewport'
|
||||
// import { breakpoints } from './TradePageGrid'
|
||||
import { FunctionComponent } from 'react'
|
||||
|
||||
interface ButtonGroupProps {
|
||||
|
@ -15,8 +13,6 @@ const ButtonGroup: FunctionComponent<ButtonGroupProps> = ({
|
|||
values,
|
||||
onChange,
|
||||
}) => {
|
||||
// const { width } = useViewport()
|
||||
// const isMobile = width ? width < breakpoints.sm : false
|
||||
return (
|
||||
<div className="bg-th-bkg-3 rounded-md">
|
||||
<div className="flex relative">
|
||||
|
@ -37,7 +33,7 @@ const ButtonGroup: FunctionComponent<ButtonGroupProps> = ({
|
|||
${
|
||||
v === activeValue
|
||||
? `text-th-primary`
|
||||
: `text-th-fgd-1 opacity-50 hover:opacity-100`
|
||||
: `text-th-fgd-1 opacity-70 hover:opacity-100`
|
||||
}
|
||||
`}
|
||||
key={`${v}${i}`}
|
||||
|
|
|
@ -15,8 +15,8 @@ const HiddenCheckbox = styled.input`
|
|||
width: 1px;
|
||||
`
|
||||
|
||||
const Checkbox = ({ checked, ...props }) => (
|
||||
<>
|
||||
const Checkbox = ({ checked, children, ...props }) => (
|
||||
<label className="cursor-pointer flex items-center">
|
||||
<HiddenCheckbox checked={checked} {...props} type="checkbox" />
|
||||
<div
|
||||
className={`${
|
||||
|
@ -27,7 +27,8 @@ const Checkbox = ({ checked, ...props }) => (
|
|||
className={`${checked ? 'block' : 'hidden'} h-4 w-4 text-th-primary`}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
<span className="ml-2 text-xs text-th-fgd-3">{children}</span>
|
||||
</label>
|
||||
)
|
||||
|
||||
export default Checkbox
|
||||
|
|
|
@ -29,9 +29,11 @@ export const FlipCardInner = styled.div<any>`
|
|||
`
|
||||
|
||||
export const FlipCardFront = styled.div`
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@media screen and (min-width: 768px) {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
`
|
||||
|
||||
export const FlipCardBack = styled.div`
|
||||
|
@ -45,5 +47,4 @@ export const StyledFloatingElement = styled(FloatingElement)`
|
|||
animation: ${css`
|
||||
${fadeIn} 1s linear
|
||||
`};
|
||||
overflow: auto;
|
||||
`
|
||||
|
|
|
@ -41,7 +41,7 @@ const FloatingElement: FunctionComponent<FloatingElementProps> = ({
|
|||
const wallet = useMangoStore((s) => s.wallet.current)
|
||||
return (
|
||||
<div
|
||||
className={`thin-scroll bg-th-bkg-2 rounded-lg p-2.5 sm:p-4 overflow-auto overflow-x-hidden relative ${className}`}
|
||||
className={`thin-scroll bg-th-bkg-2 rounded-lg p-2.5 md:p-4 overflow-auto overflow-x-hidden relative ${className}`}
|
||||
>
|
||||
{!connected && showConnect ? (
|
||||
<div className="absolute top-0 left-0 w-full h-full z-10">
|
||||
|
|
|
@ -30,8 +30,7 @@ const Input = ({
|
|||
<div className={`flex relative ${wrapperClassName}`}>
|
||||
{prefix ? (
|
||||
<div
|
||||
className={`flex items-center justify-end p-2 border border-r-0
|
||||
border-th-fgd-4 bg-th-bkg-2 text-xs rounded-md rounded-r-none text-right ${prefixClassName}`}
|
||||
className={`absolute left-2 top-1/2 transform -translate-y-1/2 ${prefixClassName}`}
|
||||
>
|
||||
{prefix}
|
||||
</div>
|
||||
|
@ -40,7 +39,7 @@ const Input = ({
|
|||
type={type}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
className={`${className} pb-px px-2 flex-1 bg-th-bkg-1 rounded-md h-10 text-th-fgd-1 w-full
|
||||
className={`${className} bg-th-bkg-1 pb-px px-2 flex-1 rounded-md h-10 text-th-fgd-1 w-full
|
||||
border ${
|
||||
error ? 'border-th-red' : 'border-th-fgd-4'
|
||||
} default-transition hover:border-th-primary
|
||||
|
@ -50,7 +49,7 @@ const Input = ({
|
|||
? 'bg-th-bkg-3 cursor-not-allowed hover:border-th-fgd-4 text-th-fgd-3'
|
||||
: ''
|
||||
}
|
||||
${prefix ? 'rounded-l-none' : ''}`}
|
||||
${prefix ? 'pl-7' : ''}`}
|
||||
disabled={disabled}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
@ -12,7 +12,7 @@ import FloatingElement from '../components/FloatingElement'
|
|||
import Orderbook from '../components/Orderbook'
|
||||
import AccountInfo from './AccountInfo'
|
||||
import UserMarketInfo from './UserMarketInfo'
|
||||
import TradeForm from './TradeForm'
|
||||
import TradeForm from './trade_form/TradeForm'
|
||||
import UserInfo from './UserInfo'
|
||||
import RecentMarketTrades from './RecentMarketTrades'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
import { Listbox } from '@headlessui/react'
|
||||
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/solid'
|
||||
import { useViewport } from '../hooks/useViewport'
|
||||
import { breakpoints } from './TradePageGrid'
|
||||
|
||||
const TradeType = ({
|
||||
value,
|
||||
onChange,
|
||||
offerTriggers = false,
|
||||
className = '',
|
||||
}) => {
|
||||
const { width } = useViewport()
|
||||
const isMobile = width ? width < breakpoints.sm : false
|
||||
|
||||
const TRADE_TYPES = ['Limit', 'Market']
|
||||
if (offerTriggers)
|
||||
TRADE_TYPES.push(
|
||||
'Stop Loss',
|
||||
'Stop Limit',
|
||||
'Take Profit',
|
||||
'Take Profit Limit'
|
||||
)
|
||||
|
||||
return (
|
||||
<div className={`relative ${className}`}>
|
||||
{!isMobile ? (
|
||||
<Listbox value={value} onChange={onChange}>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Listbox.Button
|
||||
className={`font-normal h-full w-full bg-th-bkg-1 border border-th-fgd-4 p-2 hover:border-th-primary rounded-md focus:outline-none focus:border-th-primary`}
|
||||
>
|
||||
<div className={`flex items-center justify-between space-x-4`}>
|
||||
<span>{value}</span>
|
||||
{open ? (
|
||||
<ChevronUpIcon className={`h-5 w-5 mr-1 text-th-primary`} />
|
||||
) : (
|
||||
<ChevronDownIcon
|
||||
className={`h-5 w-5 mr-1 text-th-primary`}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Listbox.Button>
|
||||
{open ? (
|
||||
<Listbox.Options
|
||||
static
|
||||
className={`z-20 w-full p-1 absolute left-0 mt-1 bg-th-bkg-1 origin-top-left divide-y divide-th-bkg-3 shadow-lg outline-none rounded-md text-left`}
|
||||
>
|
||||
{TRADE_TYPES.map((type) => (
|
||||
<Listbox.Option key={type} value={type}>
|
||||
{({ selected }) => (
|
||||
<div
|
||||
className={`p-2 hover:bg-th-bkg-2 hover:cursor-pointer tracking-wider ${
|
||||
selected && `text-th-primary`
|
||||
}`}
|
||||
>
|
||||
{type}
|
||||
</div>
|
||||
)}
|
||||
</Listbox.Option>
|
||||
))}
|
||||
</Listbox.Options>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</Listbox>
|
||||
) : (
|
||||
<div className="flex">
|
||||
{TRADE_TYPES.slice(0, 2).map((tradeType) => (
|
||||
<div
|
||||
key={tradeType}
|
||||
className={`px-2 py-2 ml-2 rounded-md cursor-pointer default-transition bg-th-bkg-4
|
||||
${
|
||||
value === tradeType
|
||||
? `ring-1 ring-inset ring-th-primary text-th-primary`
|
||||
: `text-th-fgd-1 opacity-50 hover:opacity-100`
|
||||
}
|
||||
`}
|
||||
onClick={() => onChange(tradeType)}
|
||||
>
|
||||
{tradeType}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TradeType
|
|
@ -1,12 +1,12 @@
|
|||
import { useState } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { Disclosure } from '@headlessui/react'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { XIcon } from '@heroicons/react/outline'
|
||||
import useMangoStore from '../../stores/useMangoStore'
|
||||
import { PerpMarket } from '@blockworks-foundation/mango-client'
|
||||
import { getWeights, PerpMarket } from '@blockworks-foundation/mango-client'
|
||||
import { CandlesIcon } from '../icons'
|
||||
import SwipeableTabs from './SwipeableTabs'
|
||||
import TradeForm from '../TradeForm'
|
||||
import AdvancedTradeForm from '../trade_form/AdvancedTradeForm'
|
||||
import Orderbook from '../Orderbook'
|
||||
import MarketBalances from '../MarketBalances'
|
||||
import MarketDetails from '../MarketDetails'
|
||||
|
@ -25,6 +25,7 @@ const MobileTradePage = () => {
|
|||
const [viewIndex, setViewIndex] = useState(0)
|
||||
const selectedMarket = useMangoStore((s) => s.selectedMarket.current)
|
||||
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
|
||||
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
||||
const connected = useMangoStore((s) => s.wallet.connected)
|
||||
const groupConfig = useMangoStore((s) => s.selectedMangoGroup.config)
|
||||
const baseSymbol = marketConfig.baseSymbol
|
||||
|
@ -34,6 +35,15 @@ const MobileTradePage = () => {
|
|||
setViewIndex(index)
|
||||
}
|
||||
|
||||
const initLeverage = useMemo(() => {
|
||||
if (!mangoGroup || !marketConfig) return 1
|
||||
|
||||
const ws = getWeights(mangoGroup, marketConfig.marketIndex, 'Init')
|
||||
const w =
|
||||
marketConfig.kind === 'perp' ? ws.perpAssetWeight : ws.spotAssetWeight
|
||||
return Math.round((100 * -1) / (w.toNumber() - 1)) / 100
|
||||
}, [mangoGroup, marketConfig])
|
||||
|
||||
const TABS =
|
||||
selectedMarket instanceof PerpMarket
|
||||
? ['Trade', 'Details', 'Position', 'Orders']
|
||||
|
@ -59,6 +69,9 @@ const MobileTradePage = () => {
|
|||
{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>
|
||||
<Disclosure>
|
||||
{({ open }) => (
|
||||
|
@ -72,7 +85,7 @@ const MobileTradePage = () => {
|
|||
)}
|
||||
</div>
|
||||
</Disclosure.Button>
|
||||
<Disclosure.Panel className="pt-3">
|
||||
<Disclosure.Panel>
|
||||
<div className="bg-th-bkg-2 h-96 mb-2 p-2 rounded-lg">
|
||||
<TVChartContainer />
|
||||
</div>
|
||||
|
@ -90,7 +103,7 @@ const MobileTradePage = () => {
|
|||
<div>
|
||||
<div className="bg-th-bkg-2 grid grid-cols-12 grid-rows-1 gap-4 mb-2 px-2 py-3 rounded-lg">
|
||||
<div className="col-span-7">
|
||||
<TradeForm />
|
||||
<AdvancedTradeForm />
|
||||
</div>
|
||||
<div className="col-span-5">
|
||||
<Orderbook depth={8} />
|
||||
|
|
|
@ -1,33 +1,38 @@
|
|||
import { useMemo, useState, useEffect, useRef } from 'react'
|
||||
import useIpAddress from '../hooks/useIpAddress'
|
||||
import useIpAddress from '../../hooks/useIpAddress'
|
||||
import {
|
||||
getMarketIndexBySymbol,
|
||||
getTokenBySymbol,
|
||||
I80F48,
|
||||
PerpMarket,
|
||||
} from '@blockworks-foundation/mango-client'
|
||||
import { notify } from '../utils/notifications'
|
||||
import { calculateTradePrice, getDecimalCount } from '../utils'
|
||||
import { floorToDecimal } from '../utils/index'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import Button from './Button'
|
||||
import { notify } from '../../utils/notifications'
|
||||
import { calculateTradePrice, getDecimalCount } from '../../utils'
|
||||
import { floorToDecimal } from '../../utils/index'
|
||||
import useMangoStore from '../../stores/useMangoStore'
|
||||
import Button from '../Button'
|
||||
import TradeType from './TradeType'
|
||||
import Input from './Input'
|
||||
import Switch from './Switch'
|
||||
import Input from '../Input'
|
||||
import { Market } from '@project-serum/serum'
|
||||
import Big from 'big.js'
|
||||
import MarketFee from './MarketFee'
|
||||
import LeverageSlider from './LeverageSlider'
|
||||
import Loading from './Loading'
|
||||
import Tooltip from './Tooltip'
|
||||
import { useViewport } from '../hooks/useViewport'
|
||||
import { breakpoints } from './TradePageGrid'
|
||||
import MarketFee from '../MarketFee'
|
||||
import Loading from '../Loading'
|
||||
import Tooltip from '../Tooltip'
|
||||
import OrderSideTabs from './OrderSideTabs'
|
||||
import { ElementTitle } from './styles'
|
||||
import ButtonGroup from './ButtonGroup'
|
||||
import { ElementTitle } from '../styles'
|
||||
import ButtonGroup from '../ButtonGroup'
|
||||
import SlippageWarning from './SlippageWarning'
|
||||
import Checkbox from '../Checkbox'
|
||||
import { useViewport } from '../../hooks/useViewport'
|
||||
import { breakpoints } from '../TradePageGrid'
|
||||
|
||||
export default function AdvancedTradeForm({ initLeverage }) {
|
||||
interface AdvancedTradeFormProps {
|
||||
initLeverage?: number
|
||||
}
|
||||
|
||||
export default function AdvancedTradeForm({
|
||||
initLeverage,
|
||||
}: AdvancedTradeFormProps) {
|
||||
const set = useMangoStore((s) => s.set)
|
||||
const { ipAllowed } = useIpAddress()
|
||||
const connected = useMangoStore((s) => s.wallet.connected)
|
||||
|
@ -47,6 +52,8 @@ export default function AdvancedTradeForm({ initLeverage }) {
|
|||
groupConfig,
|
||||
marketConfig.baseSymbol
|
||||
)
|
||||
const { width } = useViewport()
|
||||
const isMobile = width ? width < breakpoints.sm : false
|
||||
|
||||
const {
|
||||
side,
|
||||
|
@ -70,9 +77,6 @@ export default function AdvancedTradeForm({ initLeverage }) {
|
|||
'Take Profit Limit',
|
||||
].includes(tradeType)
|
||||
|
||||
const { width } = useViewport()
|
||||
const isMobile = width ? width < breakpoints.sm : false
|
||||
|
||||
const [postOnly, setPostOnly] = useState(false)
|
||||
const [ioc, setIoc] = useState(false)
|
||||
const [submitting, setSubmitting] = useState(false)
|
||||
|
@ -478,30 +482,30 @@ export default function AdvancedTradeForm({ initLeverage }) {
|
|||
submitting ||
|
||||
!mangoAccount
|
||||
|
||||
return !isMobile ? (
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
<ElementTitle>
|
||||
<ElementTitle className="hidden md:flex">
|
||||
{marketConfig.name}
|
||||
<span className="border border-th-primary ml-2 px-1 py-0.5 rounded text-xs text-th-primary">
|
||||
{initLeverage}x
|
||||
</span>
|
||||
</ElementTitle>
|
||||
<OrderSideTabs onChange={setSide} side={side} />
|
||||
<div className="grid grid-cols-12 gap-2 text-left">
|
||||
<div className="col-span-2 flex items-center">
|
||||
<label className="text-xs text-th-fgd-3">Type</label>
|
||||
<div className="grid grid-cols-12 md:gap-2 text-left">
|
||||
<div className="col-span-12 md:col-span-2 flex items-center">
|
||||
<label className="text-xxs md:text-xs text-th-fgd-3">Type</label>
|
||||
</div>
|
||||
<div className="col-span-10">
|
||||
<div className="col-span-12 md:col-span-10 pb-2 md:pb-0">
|
||||
<TradeType
|
||||
onChange={onTradeTypeChange}
|
||||
value={tradeType}
|
||||
offerTriggers={isPerpMarket}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-2 flex items-center">
|
||||
<label className="text-xs text-th-fgd-3">Price</label>
|
||||
<div className="col-span-12 md:col-span-2 flex items-center">
|
||||
<label className="text-xxs md:text-xs text-th-fgd-3">Price</label>
|
||||
</div>
|
||||
<div className="col-span-10">
|
||||
<div className="col-span-12 md:col-span-10 pb-2 md:pb-0">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
|
@ -509,7 +513,7 @@ export default function AdvancedTradeForm({ initLeverage }) {
|
|||
onChange={(e) => onSetPrice(e.target.value)}
|
||||
value={price}
|
||||
disabled={isMarketOrder}
|
||||
placeholder={tradeType === 'Market' ? 'Market Price' : null}
|
||||
placeholder={tradeType === 'Market' ? markPrice : null}
|
||||
prefix={
|
||||
<img
|
||||
src={`/assets/icons/${groupConfig.quoteSymbol.toLowerCase()}.svg`}
|
||||
|
@ -521,10 +525,12 @@ export default function AdvancedTradeForm({ initLeverage }) {
|
|||
</div>
|
||||
{isTriggerOrder && (
|
||||
<>
|
||||
<div className="col-span-2 flex items-center">
|
||||
<label className="text-xs text-th-fgd-3">Trigger Price</label>
|
||||
<div className="col-span-12 md:col-span-2 flex items-center">
|
||||
<label className="text-xxs md:text-xs text-th-fgd-3">
|
||||
Trigger Price
|
||||
</label>
|
||||
</div>
|
||||
<div className="col-span-10">
|
||||
<div className="col-span-12 md:col-span-10 pb-2 md:pb-0">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
|
@ -542,10 +548,10 @@ export default function AdvancedTradeForm({ initLeverage }) {
|
|||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="col-span-2 flex items-center">
|
||||
<label className="text-xs text-th-fgd-3">Size</label>
|
||||
<div className="col-span-12 md:col-span-2 flex items-center">
|
||||
<label className="text-xxs md:text-xs text-th-fgd-3">Size</label>
|
||||
</div>
|
||||
<div className="col-span-10">
|
||||
<div className="col-span-12 md:col-span-10 pb-2 md:pb-0">
|
||||
<Input.Group className="-mb-1">
|
||||
<Input
|
||||
type="number"
|
||||
|
@ -579,87 +585,81 @@ export default function AdvancedTradeForm({ initLeverage }) {
|
|||
/>
|
||||
</Input.Group>
|
||||
</div>
|
||||
<div className="col-span-10 col-start-3">
|
||||
<div className="col-span-12 md:col-span-10 md:col-start-3">
|
||||
<ButtonGroup
|
||||
activeValue={positionSizePercent}
|
||||
onChange={(p) => handleSetPositionSize(p)}
|
||||
unit="%"
|
||||
values={['10', '25', '50', '75', '100']}
|
||||
values={
|
||||
isMobile
|
||||
? ['10', '25', '50', '75']
|
||||
: ['10', '25', '50', '75', '100']
|
||||
}
|
||||
/>
|
||||
{side === 'sell' ? (
|
||||
roundedDeposits > 0 ? (
|
||||
<div className="text-th-fgd-3 text-xs tracking-normal mt-2">
|
||||
<span>{closeDepositString}</span>
|
||||
</div>
|
||||
) : null
|
||||
) : roundedBorrows > 0 ? (
|
||||
<div className="text-th-fgd-3 text-xs tracking-normal mt-2">
|
||||
<span>{roundedDeposits > 0 ? closeDepositString : null}</span>
|
||||
<span>{closeBorrowString}</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-th-fgd-3 text-xs tracking-normal mt-2">
|
||||
<span>{roundedBorrows > 0 ? closeBorrowString : null}</span>
|
||||
</div>
|
||||
)}
|
||||
{/* <LeverageSlider
|
||||
onChange={(e) => onSetBaseSize(e)}
|
||||
value={baseSize ? baseSize : 0}
|
||||
step={parseFloat(minOrderSize)}
|
||||
disabled={false}
|
||||
side={side}
|
||||
decimalCount={sizeDecimalCount}
|
||||
price={calculateTradePrice(
|
||||
tradeType,
|
||||
orderbook,
|
||||
baseSize ? baseSize : 0,
|
||||
side,
|
||||
price,
|
||||
triggerPrice
|
||||
)}
|
||||
/> */}
|
||||
<div className="flex">
|
||||
) : null}
|
||||
<div className="sm:flex">
|
||||
{isLimitOrder ? (
|
||||
<>
|
||||
<div className="mr-4 mt-2">
|
||||
<div className="flex">
|
||||
<div className="mr-4 mt-4">
|
||||
<Tooltip
|
||||
className="hidden md:block"
|
||||
delay={250}
|
||||
placement="left"
|
||||
content="Post only orders are guaranteed to be the maker order or else it will be canceled."
|
||||
>
|
||||
<Switch
|
||||
className="text-th-fgd-3 text-xs"
|
||||
<Checkbox
|
||||
checked={postOnly}
|
||||
onChange={postOnChange}
|
||||
onChange={(e) => postOnChange(e.target.checked)}
|
||||
>
|
||||
POST
|
||||
</Switch>
|
||||
</Checkbox>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="mr-4 mt-2">
|
||||
<div className="mr-4 mt-4">
|
||||
<Tooltip
|
||||
className="hidden md:block"
|
||||
delay={250}
|
||||
placement="left"
|
||||
content="Immediate or cancel orders are guaranteed to be the taker or it will be canceled."
|
||||
>
|
||||
<Switch
|
||||
className="text-th-fgd-3 text-xs"
|
||||
checked={ioc}
|
||||
onChange={iocOnChange}
|
||||
>
|
||||
IOC
|
||||
</Switch>
|
||||
<div className="flex items-center text-th-fgd-3 text-xs">
|
||||
<Checkbox
|
||||
checked={ioc}
|
||||
onChange={(e) => iocOnChange(e.target.checked)}
|
||||
>
|
||||
IOC
|
||||
</Checkbox>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
) : null}
|
||||
{marketConfig.kind === 'perp' && !isTriggerOrder ? (
|
||||
<Tooltip
|
||||
delay={250}
|
||||
placement="left"
|
||||
content="Reduce only orders will only reduce your overall position."
|
||||
>
|
||||
<Switch
|
||||
className="mt-2 text-th-fgd-3 text-xs"
|
||||
checked={reduceOnly}
|
||||
onChange={reduceOnChange}
|
||||
<div className="mt-4">
|
||||
<Tooltip
|
||||
className="hidden md:block"
|
||||
delay={250}
|
||||
placement="left"
|
||||
content="Reduce only orders will only reduce your overall position."
|
||||
>
|
||||
Reduce Only
|
||||
</Switch>
|
||||
</Tooltip>
|
||||
<Checkbox
|
||||
checked={reduceOnly}
|
||||
onChange={(e) => reduceOnChange(e.target.checked)}
|
||||
>
|
||||
Reduce Only
|
||||
</Checkbox>
|
||||
</Tooltip>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className={`flex pt-4`}>
|
||||
|
@ -679,18 +679,24 @@ export default function AdvancedTradeForm({ initLeverage }) {
|
|||
</div>
|
||||
) : side.toLowerCase() === 'buy' ? (
|
||||
market instanceof PerpMarket ? (
|
||||
`${baseSize > 0 ? 'Long ' + baseSize : 'Long '} ${
|
||||
marketConfig.name
|
||||
}`
|
||||
<>
|
||||
{baseSize > 0 ? 'Long ' + baseSize : 'Long '}{' '}
|
||||
<span className="whitespace-nowrap">
|
||||
{marketConfig.name}
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
`${baseSize > 0 ? 'Buy ' + baseSize : 'Buy '} ${
|
||||
marketConfig.baseSymbol
|
||||
}`
|
||||
)
|
||||
) : market instanceof PerpMarket ? (
|
||||
`${baseSize > 0 ? 'Short ' + baseSize : 'Short '} ${
|
||||
marketConfig.name
|
||||
}`
|
||||
<>
|
||||
{baseSize > 0 ? 'Short ' + baseSize : 'Short '}{' '}
|
||||
<span className="whitespace-nowrap">
|
||||
{marketConfig.name}
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
`${baseSize > 0 ? 'Sell ' + baseSize : 'Sell '} ${
|
||||
marketConfig.baseSymbol
|
||||
|
@ -704,7 +710,7 @@ export default function AdvancedTradeForm({ initLeverage }) {
|
|||
)}
|
||||
</div>
|
||||
{tradeType === 'Market' ? (
|
||||
<div className="col-span-10 col-start-3 pt-2">
|
||||
<div className="col-span-12 md:col-span-10 md:col-start-3 pt-2">
|
||||
<SlippageWarning slippage={0.2} />
|
||||
</div>
|
||||
) : null}
|
||||
|
@ -714,187 +720,5 @@ export default function AdvancedTradeForm({ initLeverage }) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col h-full">
|
||||
<div className={`flex pb-3 text-base text-th-fgd-4`}>
|
||||
<button
|
||||
onClick={() => setSide('buy')}
|
||||
className={`flex-1 outline-none focus:outline-none`}
|
||||
>
|
||||
<div
|
||||
className={`hover:text-th-green pb-1 transition-colors duration-500
|
||||
${
|
||||
side === 'buy'
|
||||
? `text-th-green hover:text-th-green border-b-2 border-th-green`
|
||||
: undefined
|
||||
}`}
|
||||
>
|
||||
Buy
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setSide('sell')}
|
||||
className={`flex-1 outline-none focus:outline-none`}
|
||||
>
|
||||
<div
|
||||
className={`hover:text-th-red pb-1 transition-colors duration-500
|
||||
${
|
||||
side === 'sell'
|
||||
? `text-th-red hover:text-th-red border-b-2 border-th-red`
|
||||
: undefined
|
||||
}
|
||||
`}
|
||||
>
|
||||
Sell
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div className="pb-3">
|
||||
<label className="block mb-1 text-th-fgd-3 text-xs">Price</label>
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
step={tickSize}
|
||||
onChange={(e) => onSetPrice(e.target.value)}
|
||||
value={price}
|
||||
disabled={tradeType === 'Market'}
|
||||
suffix={
|
||||
<img
|
||||
src={`/assets/icons/${groupConfig.quoteSymbol.toLowerCase()}.svg`}
|
||||
width="16"
|
||||
height="16"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between pb-3">
|
||||
<label className="text-th-fgd-3 text-xs">Type</label>
|
||||
<TradeType
|
||||
onChange={onTradeTypeChange}
|
||||
value={tradeType}
|
||||
className=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label className="block mb-1 text-th-fgd-3 text-xs">Size</label>
|
||||
<div className="grid grid-cols-2 grid-rows-1 gap-2">
|
||||
<div className="col-span-1">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
step={minOrderSize}
|
||||
onChange={(e) => onSetBaseSize(e.target.value)}
|
||||
value={baseSize}
|
||||
suffix={
|
||||
<img
|
||||
src={`/assets/icons/${marketConfig.baseSymbol.toLowerCase()}.svg`}
|
||||
width="16"
|
||||
height="16"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-1">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
step={minOrderSize}
|
||||
onChange={(e) => onSetQuoteSize(e.target.value)}
|
||||
value={quoteSize}
|
||||
suffix={
|
||||
<img
|
||||
src={`/assets/icons/${groupConfig.quoteSymbol.toLowerCase()}.svg`}
|
||||
width="16"
|
||||
height="16"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<LeverageSlider
|
||||
onChange={(e) => onSetBaseSize(e)}
|
||||
value={baseSize ? baseSize : 0}
|
||||
step={parseFloat(minOrderSize)}
|
||||
disabled={false}
|
||||
side={side}
|
||||
decimalCount={sizeDecimalCount}
|
||||
price={calculateTradePrice(
|
||||
tradeType,
|
||||
orderbook,
|
||||
baseSize ? baseSize : 0,
|
||||
side,
|
||||
price,
|
||||
triggerPrice
|
||||
)}
|
||||
/>
|
||||
{tradeType !== 'Market' ? (
|
||||
<div className="flex mt-2">
|
||||
<Switch checked={postOnly} onChange={postOnChange}>
|
||||
POST
|
||||
</Switch>
|
||||
<div className="ml-4">
|
||||
<Switch checked={ioc} onChange={iocOnChange}>
|
||||
IOC
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
<div className={`flex py-4`}>
|
||||
{ipAllowed ? (
|
||||
side === 'buy' ? (
|
||||
<Button
|
||||
disabled={disabledTradeButton}
|
||||
onClick={onSubmit}
|
||||
className={`${
|
||||
!disabledTradeButton
|
||||
? 'bg-th-bkg-2 border border-th-green hover:border-th-green-dark'
|
||||
: 'border border-th-bkg-4'
|
||||
} text-th-green hover:text-th-fgd-1 hover:bg-th-green-dark flex-grow`}
|
||||
>
|
||||
{submitting ? (
|
||||
<div className="w-full">
|
||||
<Loading className="mx-auto" />
|
||||
</div>
|
||||
) : (
|
||||
`${baseSize > 0 ? 'Buy ' + baseSize : 'Buy '} ${
|
||||
marketConfig.name.includes('PERP')
|
||||
? marketConfig.name
|
||||
: marketConfig.baseSymbol
|
||||
}`
|
||||
)}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
disabled={disabledTradeButton}
|
||||
onClick={onSubmit}
|
||||
className={`${
|
||||
!disabledTradeButton
|
||||
? 'bg-th-bkg-2 border border-th-red hover:border-th-red-dark'
|
||||
: 'border border-th-bkg-4'
|
||||
} text-th-red hover:text-th-fgd-1 hover:bg-th-red-dark flex-grow`}
|
||||
>
|
||||
{submitting ? (
|
||||
<div className="w-full">
|
||||
<Loading className="mx-auto" />
|
||||
</div>
|
||||
) : (
|
||||
`${baseSize > 0 ? 'Sell ' + baseSize : 'Sell '} ${
|
||||
marketConfig.name.includes('PERP')
|
||||
? marketConfig.name
|
||||
: marketConfig.baseSymbol
|
||||
}`
|
||||
)}
|
||||
</Button>
|
||||
)
|
||||
) : (
|
||||
<Button disabled className="flex-grow">
|
||||
<span>Country Not Allowed</span>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex text-xs text-th-fgd-4 px-6 mt-2.5">
|
||||
<MarketFee />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { FunctionComponent } from 'react'
|
||||
import { PerpMarket } from '@blockworks-foundation/mango-client'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import useMangoStore from '../../stores/useMangoStore'
|
||||
|
||||
interface OrderSideTabsProps {
|
||||
onChange: (x) => void
|
||||
|
@ -13,7 +13,7 @@ const OrderSideTabs: FunctionComponent<OrderSideTabsProps> = ({
|
|||
}) => {
|
||||
const market = useMangoStore((s) => s.selectedMarket.current)
|
||||
return (
|
||||
<div className={`border-b border-th-fgd-4 mb-4 relative`}>
|
||||
<div className={`border-b border-th-fgd-4 mb-2 md:mb-4 relative`}>
|
||||
<div
|
||||
className={`absolute ${
|
||||
side === 'buy'
|
||||
|
@ -24,7 +24,7 @@ const OrderSideTabs: FunctionComponent<OrderSideTabsProps> = ({
|
|||
<nav className="-mb-px flex" aria-label="Tabs">
|
||||
<button
|
||||
onClick={() => onChange('buy')}
|
||||
className={`cursor-pointer default-transition flex font-semibold items-center justify-center p-2 relative text-base w-1/2 whitespace-nowrap hover:opacity-100
|
||||
className={`cursor-pointer default-transition flex font-semibold items-center justify-center pb-2 md:py-2 relative text-base w-1/2 whitespace-nowrap hover:opacity-100
|
||||
${
|
||||
side === 'buy'
|
||||
? `text-th-green`
|
||||
|
@ -36,7 +36,7 @@ const OrderSideTabs: FunctionComponent<OrderSideTabsProps> = ({
|
|||
</button>
|
||||
<button
|
||||
onClick={() => onChange('sell')}
|
||||
className={`cursor-pointer default-transition flex font-semibold items-center justify-center p-2 relative text-base w-1/2 whitespace-nowrap hover:opacity-100
|
||||
className={`cursor-pointer default-transition flex font-semibold items-center justify-center pb-2 relative text-base w-1/2 whitespace-nowrap hover:opacity-100
|
||||
${
|
||||
side === 'sell'
|
||||
? `text-th-red`
|
|
@ -1,31 +1,26 @@
|
|||
import { useState, useEffect, useRef, useMemo } from 'react'
|
||||
import useIpAddress from '../hooks/useIpAddress'
|
||||
import useIpAddress from '../../hooks/useIpAddress'
|
||||
import {
|
||||
getTokenBySymbol,
|
||||
getMarketIndexBySymbol,
|
||||
I80F48,
|
||||
PerpMarket,
|
||||
} from '@blockworks-foundation/mango-client'
|
||||
import { notify } from '../utils/notifications'
|
||||
import { calculateTradePrice, getDecimalCount, sleep } from '../utils'
|
||||
import { floorToDecimal } from '../utils/index'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import Button from './Button'
|
||||
import TradeType from './TradeType'
|
||||
import Input from './Input'
|
||||
import Switch from './Switch'
|
||||
import { notify } from '../../utils/notifications'
|
||||
import { calculateTradePrice, getDecimalCount, sleep } from '../../utils'
|
||||
import { floorToDecimal } from '../../utils/index'
|
||||
import useMangoStore from '../../stores/useMangoStore'
|
||||
import Button from '../Button'
|
||||
import Input from '../Input'
|
||||
import { Market } from '@project-serum/serum'
|
||||
import Big from 'big.js'
|
||||
import MarketFee from './MarketFee'
|
||||
import LeverageSlider from './LeverageSlider'
|
||||
import Loading from './Loading'
|
||||
import { useViewport } from '../hooks/useViewport'
|
||||
import { breakpoints } from './TradePageGrid'
|
||||
import { ElementTitle } from './styles'
|
||||
import ButtonGroup from './ButtonGroup'
|
||||
import Checkbox from './Checkbox'
|
||||
import MarketFee from '../MarketFee'
|
||||
import Loading from '../Loading'
|
||||
import { ElementTitle } from '../styles'
|
||||
import ButtonGroup from '../ButtonGroup'
|
||||
import Checkbox from '../Checkbox'
|
||||
import OrderSideTabs from './OrderSideTabs'
|
||||
import Tooltip from './Tooltip'
|
||||
import Tooltip from '../Tooltip'
|
||||
import SlippageWarning from './SlippageWarning'
|
||||
|
||||
export default function SimpleTradeForm({ initLeverage }) {
|
||||
|
@ -46,8 +41,6 @@ export default function SimpleTradeForm({ initLeverage }) {
|
|||
const market = useMangoStore((s) => s.selectedMarket.current)
|
||||
const { side, baseSize, quoteSize, price, triggerPrice, tradeType } =
|
||||
useMangoStore((s) => s.tradeForm)
|
||||
const { width } = useViewport()
|
||||
const isMobile = width ? width < breakpoints.sm : false
|
||||
|
||||
const [postOnly, setPostOnly] = useState(false)
|
||||
const [ioc, setIoc] = useState(false)
|
||||
|
@ -422,7 +415,7 @@ export default function SimpleTradeForm({ initLeverage }) {
|
|||
(side === 'sell' && baseSize === roundedDeposits) ||
|
||||
(side === 'buy' && baseSize === roundedBorrows)
|
||||
|
||||
return !isMobile ? (
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
<ElementTitle>
|
||||
{marketConfig.name}
|
||||
|
@ -453,7 +446,7 @@ export default function SimpleTradeForm({ initLeverage }) {
|
|||
onChange={(e) => onSetPrice(e.target.value)}
|
||||
value={price}
|
||||
disabled={tradeType === 'Market'}
|
||||
placeholder={tradeType === 'Market' ? 'Market Price' : null}
|
||||
placeholder={tradeType === 'Market' ? markPrice : null}
|
||||
prefix={
|
||||
<img
|
||||
src={`/assets/icons/${groupConfig.quoteSymbol.toLowerCase()}.svg`}
|
||||
|
@ -523,15 +516,12 @@ export default function SimpleTradeForm({ initLeverage }) {
|
|||
showStopForm ? 'bg-th-bkg-4' : 'bg-th-bkg-3'
|
||||
} mt-2 p-2 rounded-md w-1/2`}
|
||||
>
|
||||
<label className="cursor-pointer flex items-center">
|
||||
<Checkbox
|
||||
checked={showStopForm}
|
||||
onChange={(e) => setShowStopForm(e.target.checked)}
|
||||
/>
|
||||
<span className="ml-2 text-xs text-th-fgd-3">
|
||||
Set Stop Loss
|
||||
</span>
|
||||
</label>
|
||||
<Checkbox
|
||||
checked={showStopForm}
|
||||
onChange={(e) => setShowStopForm(e.target.checked)}
|
||||
>
|
||||
Set Stop Loss
|
||||
</Checkbox>
|
||||
</div>
|
||||
) : null}
|
||||
{!hideProfitStop ? (
|
||||
|
@ -540,15 +530,12 @@ export default function SimpleTradeForm({ initLeverage }) {
|
|||
showTakeProfitForm ? 'bg-th-bkg-4' : 'bg-th-bkg-3'
|
||||
} mt-2 p-2 rounded-md w-1/2`}
|
||||
>
|
||||
<label className="cursor-pointer flex items-center">
|
||||
<Checkbox
|
||||
checked={showTakeProfitForm}
|
||||
onChange={(e) => setShowTakeProfitForm(e.target.checked)}
|
||||
/>
|
||||
<span className="ml-2 text-xs text-th-fgd-3">
|
||||
Set Take Profit
|
||||
</span>
|
||||
</label>
|
||||
<Checkbox
|
||||
checked={showTakeProfitForm}
|
||||
onChange={(e) => setShowTakeProfitForm(e.target.checked)}
|
||||
>
|
||||
Set Take Profit
|
||||
</Checkbox>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
@ -618,52 +605,53 @@ export default function SimpleTradeForm({ initLeverage }) {
|
|||
<div className="col-span-10 col-start-3 flex">
|
||||
{tradeType === 'Limit' ? (
|
||||
<>
|
||||
<div className="mr-4 pt-2">
|
||||
<div className="mr-4 mt-2">
|
||||
<Tooltip
|
||||
delay={250}
|
||||
placement="left"
|
||||
content="Post only orders are guaranteed to be the maker order or else it will be canceled."
|
||||
>
|
||||
<Switch
|
||||
className="text-th-fgd-3 text-xs"
|
||||
<Checkbox
|
||||
checked={postOnly}
|
||||
onChange={postOnChange}
|
||||
onChange={(e) => postOnChange(e.target.checked)}
|
||||
>
|
||||
POST
|
||||
</Switch>
|
||||
</Checkbox>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="mr-4 pt-2">
|
||||
<div className="mr-4 mt-2">
|
||||
<Tooltip
|
||||
delay={250}
|
||||
placement="left"
|
||||
content="Immediate or cancel orders are guaranteed to be the taker or it will be canceled."
|
||||
>
|
||||
<Switch
|
||||
className="text-th-fgd-3 text-xs"
|
||||
checked={ioc}
|
||||
onChange={iocOnChange}
|
||||
>
|
||||
IOC
|
||||
</Switch>
|
||||
<div className="flex items-center text-th-fgd-3 text-xs">
|
||||
<Checkbox
|
||||
checked={ioc}
|
||||
onChange={(e) => iocOnChange(e.target.checked)}
|
||||
>
|
||||
IOC
|
||||
</Checkbox>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
{marketConfig.kind === 'perp' ? (
|
||||
<Tooltip
|
||||
delay={250}
|
||||
placement="left"
|
||||
content="Reduce only orders will only reduce your overall position."
|
||||
>
|
||||
<Switch
|
||||
className="pt-2 text-th-fgd-3 text-xs"
|
||||
checked={reduceOnly}
|
||||
onChange={reduceOnChange}
|
||||
<div className="mt-2">
|
||||
<Tooltip
|
||||
delay={250}
|
||||
placement="left"
|
||||
content="Reduce only orders will only reduce your overall position."
|
||||
>
|
||||
Reduce Only
|
||||
</Switch>
|
||||
</Tooltip>
|
||||
<Checkbox
|
||||
checked={reduceOnly}
|
||||
onChange={(e) => reduceOnChange(e.target.checked)}
|
||||
>
|
||||
Reduce Only
|
||||
</Checkbox>
|
||||
</Tooltip>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className={`col-span-10 col-start-3 flex pt-2`}>
|
||||
|
@ -717,181 +705,5 @@ export default function SimpleTradeForm({ initLeverage }) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col h-full">
|
||||
<div className={`flex pb-3 text-base text-th-fgd-4`}>
|
||||
<button
|
||||
onClick={() => setSide('buy')}
|
||||
className={`flex-1 outline-none focus:outline-none`}
|
||||
>
|
||||
<div
|
||||
className={`hover:text-th-green pb-1 transition-colors duration-500
|
||||
${
|
||||
side === 'buy'
|
||||
? `text-th-green hover:text-th-green border-b-2 border-th-green`
|
||||
: undefined
|
||||
}`}
|
||||
>
|
||||
{market instanceof PerpMarket ? 'Long' : 'Buy'}
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setSide('sell')}
|
||||
className={`flex-1 outline-none focus:outline-none`}
|
||||
>
|
||||
<div
|
||||
className={`hover:text-th-red pb-1 transition-colors duration-500
|
||||
${
|
||||
side === 'sell'
|
||||
? `text-th-red hover:text-th-red border-b-2 border-th-red`
|
||||
: undefined
|
||||
}
|
||||
`}
|
||||
>
|
||||
{market instanceof PerpMarket ? 'Short' : 'Sell'}
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div className="pb-3">
|
||||
<label className="block mb-1 text-th-fgd-3 text-xs">Price</label>
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
step={tickSize}
|
||||
onChange={(e) => onSetPrice(e.target.value)}
|
||||
value={price}
|
||||
disabled={tradeType === 'Market'}
|
||||
suffix={
|
||||
<img
|
||||
src={`/assets/icons/${groupConfig.quoteSymbol.toLowerCase()}.svg`}
|
||||
width="16"
|
||||
height="16"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between pb-3">
|
||||
<label className="text-th-fgd-3 text-xs">Type</label>
|
||||
<TradeType onChange={onTradeTypeChange} value={tradeType} />
|
||||
</div>
|
||||
<label className="block mb-1 text-th-fgd-3 text-xs">Size</label>
|
||||
<div className="grid grid-cols-2 grid-rows-1 gap-2">
|
||||
<div className="col-span-1">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
step={minOrderSize}
|
||||
onChange={(e) => onSetBaseSize(e.target.value)}
|
||||
value={baseSize}
|
||||
suffix={
|
||||
<img
|
||||
src={`/assets/icons/${marketConfig.baseSymbol.toLowerCase()}.svg`}
|
||||
width="16"
|
||||
height="16"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-1">
|
||||
<Input
|
||||
type="number"
|
||||
min="0"
|
||||
step={minOrderSize}
|
||||
onChange={(e) => onSetQuoteSize(e.target.value)}
|
||||
value={quoteSize}
|
||||
suffix={
|
||||
<img
|
||||
src={`/assets/icons/${groupConfig.quoteSymbol.toLowerCase()}.svg`}
|
||||
width="16"
|
||||
height="16"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<LeverageSlider
|
||||
onChange={(e) => onSetBaseSize(e)}
|
||||
value={baseSize ? baseSize : 0}
|
||||
step={parseFloat(minOrderSize)}
|
||||
disabled={false}
|
||||
side={side}
|
||||
decimalCount={sizeDecimalCount}
|
||||
price={calculateTradePrice(
|
||||
tradeType,
|
||||
orderbook,
|
||||
baseSize ? baseSize : 0,
|
||||
side,
|
||||
price
|
||||
)}
|
||||
/>
|
||||
{tradeType !== 'Market' ? (
|
||||
<div className="flex mt-2">
|
||||
<Switch checked={postOnly} onChange={postOnChange}>
|
||||
POST
|
||||
</Switch>
|
||||
<div className="ml-4">
|
||||
<Switch checked={ioc} onChange={iocOnChange}>
|
||||
IOC
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
<div className={`flex py-4`}>
|
||||
{ipAllowed ? (
|
||||
side === 'buy' ? (
|
||||
<Button
|
||||
disabled={disabledTradeButton}
|
||||
onClick={onSubmit}
|
||||
className={`${
|
||||
!disabledTradeButton
|
||||
? 'bg-th-bkg-2 border border-th-green hover:border-th-green-dark'
|
||||
: 'border border-th-bkg-4'
|
||||
} text-th-green hover:text-th-fgd-1 hover:bg-th-green-dark flex-grow`}
|
||||
>
|
||||
{submitting ? (
|
||||
<div className="w-full">
|
||||
<Loading className="mx-auto" />
|
||||
</div>
|
||||
) : (
|
||||
`${baseSize > 0 ? 'Buy ' + baseSize : 'Buy '} ${
|
||||
marketConfig.name.includes('PERP')
|
||||
? marketConfig.name
|
||||
: marketConfig.baseSymbol
|
||||
}`
|
||||
)}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
disabled={disabledTradeButton}
|
||||
onClick={onSubmit}
|
||||
className={`${
|
||||
!disabledTradeButton
|
||||
? 'bg-th-bkg-2 border border-th-red hover:border-th-red-dark'
|
||||
: 'border border-th-bkg-4'
|
||||
} text-th-red hover:text-th-fgd-1 hover:bg-th-red-dark flex-grow`}
|
||||
>
|
||||
{submitting ? (
|
||||
<div className="w-full">
|
||||
<Loading className="mx-auto" />
|
||||
</div>
|
||||
) : (
|
||||
`${baseSize > 0 ? 'Sell ' + baseSize : 'Sell '} ${
|
||||
marketConfig.name.includes('PERP')
|
||||
? marketConfig.name
|
||||
: marketConfig.baseSymbol
|
||||
}`
|
||||
)}
|
||||
</Button>
|
||||
)
|
||||
) : (
|
||||
<Button disabled className="flex-grow">
|
||||
<span>Country Not Allowed</span>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex text-xs text-th-fgd-4 px-6 mt-2.5">
|
||||
<MarketFee />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { useMemo, useState } from 'react'
|
||||
import { SwitchHorizontalIcon } from '@heroicons/react/outline'
|
||||
import { getWeights } from '@blockworks-foundation/mango-client'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import useMangoStore from '../../stores/useMangoStore'
|
||||
import AdvancedTradeForm from './AdvancedTradeForm'
|
||||
import SimpleTradeForm from './SimpleTradeForm'
|
||||
import {
|
||||
|
@ -10,7 +10,7 @@ import {
|
|||
FlipCardFront,
|
||||
FlipCardInner,
|
||||
StyledFloatingElement,
|
||||
} from './FlipCard'
|
||||
} from '../FlipCard'
|
||||
|
||||
export default function TradeForm() {
|
||||
const [showAdvancedFrom, setShowAdvancedForm] = useState(true)
|
||||
|
@ -36,11 +36,14 @@ export default function TradeForm() {
|
|||
<FlipCardInner flip={showAdvancedFrom}>
|
||||
{showAdvancedFrom ? (
|
||||
<FlipCardFront>
|
||||
<StyledFloatingElement className="h-full" showConnect>
|
||||
<StyledFloatingElement
|
||||
className="h-full px-1 py-0 md:px-4 md:py-4"
|
||||
showConnect
|
||||
>
|
||||
<div className={`${!connected ? 'filter blur-sm' : ''}`}>
|
||||
<button
|
||||
onClick={handleFormChange}
|
||||
className="absolute flex items-center justify-center right-4 rounded-full bg-th-bkg-3 w-8 h-8 hover:text-th-primary focus:outline-none"
|
||||
className="absolute hidden md:flex items-center justify-center right-4 rounded-full bg-th-bkg-3 w-8 h-8 hover:text-th-primary focus:outline-none"
|
||||
>
|
||||
<SwitchHorizontalIcon className="w-5 h-5" />
|
||||
</button>
|
||||
|
@ -50,7 +53,7 @@ export default function TradeForm() {
|
|||
</FlipCardFront>
|
||||
) : (
|
||||
<FlipCardBack>
|
||||
<StyledFloatingElement className="h-full" showConnect>
|
||||
<StyledFloatingElement className="h-full px-1 md:px-4" showConnect>
|
||||
<div className={`${!connected ? 'filter blur-sm' : ''}`}>
|
||||
<button
|
||||
onClick={handleFormChange}
|
|
@ -0,0 +1,68 @@
|
|||
import { Listbox } from '@headlessui/react'
|
||||
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/solid'
|
||||
import { useViewport } from '../../hooks/useViewport'
|
||||
import { breakpoints } from '../TradePageGrid'
|
||||
|
||||
const TradeType = ({
|
||||
value,
|
||||
onChange,
|
||||
offerTriggers = false,
|
||||
className = '',
|
||||
}) => {
|
||||
const { width } = useViewport()
|
||||
const isMobile = width ? width < breakpoints.sm : false
|
||||
|
||||
const TRADE_TYPES = ['Limit', 'Market']
|
||||
if (offerTriggers)
|
||||
TRADE_TYPES.push(
|
||||
'Stop Loss',
|
||||
'Stop Limit',
|
||||
'Take Profit',
|
||||
'Take Profit Limit'
|
||||
)
|
||||
|
||||
return (
|
||||
<div className={`relative ${className}`}>
|
||||
<Listbox value={value} onChange={onChange}>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Listbox.Button
|
||||
className={`font-normal h-full w-full bg-th-bkg-1 border border-th-fgd-4 p-2 hover:border-th-primary rounded-md focus:outline-none focus:border-th-primary`}
|
||||
>
|
||||
<div className={`flex items-center justify-between space-x-4`}>
|
||||
<span>{value}</span>
|
||||
{open ? (
|
||||
<ChevronUpIcon className={`h-5 w-5 mr-1 text-th-primary`} />
|
||||
) : (
|
||||
<ChevronDownIcon className={`h-5 w-5 mr-1 text-th-primary`} />
|
||||
)}
|
||||
</div>
|
||||
</Listbox.Button>
|
||||
{open ? (
|
||||
<Listbox.Options
|
||||
static
|
||||
className={`z-20 w-full p-1 absolute left-0 mt-1 bg-th-bkg-1 origin-top-left divide-y divide-th-bkg-3 shadow-lg outline-none rounded-md text-left`}
|
||||
>
|
||||
{TRADE_TYPES.map((type) => (
|
||||
<Listbox.Option key={type} value={type}>
|
||||
{({ selected }) => (
|
||||
<div
|
||||
className={`p-2 hover:bg-th-bkg-2 hover:cursor-pointer tracking-wider ${
|
||||
selected && `text-th-primary`
|
||||
}`}
|
||||
>
|
||||
{type}
|
||||
</div>
|
||||
)}
|
||||
</Listbox.Option>
|
||||
))}
|
||||
</Listbox.Options>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</Listbox>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TradeType
|
|
@ -1,8 +1,8 @@
|
|||
import { Listbox } from '@headlessui/react'
|
||||
import styled from '@emotion/styled'
|
||||
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/solid'
|
||||
import { useViewport } from '../hooks/useViewport'
|
||||
import { breakpoints } from './TradePageGrid'
|
||||
import { useViewport } from '../../hooks/useViewport'
|
||||
import { breakpoints } from '../TradePageGrid'
|
||||
|
||||
const StyledListbox = styled(Listbox.Button)`
|
||||
border-right: 1px solid transparent;
|
|
@ -10,10 +10,10 @@ import useMangoStore from '../stores/useMangoStore'
|
|||
import { copyToClipboard } from '../utils'
|
||||
import PageBodyContainer from '../components/PageBodyContainer'
|
||||
import TopBar from '../components/TopBar'
|
||||
import AccountOrders from '../components/account-page/AccountOrders'
|
||||
import AccountHistory from '../components/account-page/AccountHistory'
|
||||
import AccountOrders from '../components/account_page/AccountOrders'
|
||||
import AccountHistory from '../components/account_page/AccountHistory'
|
||||
import AccountsModal from '../components/AccountsModal'
|
||||
import AccountOverview from '../components/account-page/AccountOverview'
|
||||
import AccountOverview from '../components/account_page/AccountOverview'
|
||||
import AccountNameModal from '../components/AccountNameModal'
|
||||
import Button from '../components/Button'
|
||||
import EmptyState from '../components/EmptyState'
|
||||
|
|
|
@ -5,7 +5,7 @@ import PageBodyContainer from '../components/PageBodyContainer'
|
|||
import TopBar from '../components/TopBar'
|
||||
import EmptyState from '../components/EmptyState'
|
||||
import AccountsModal from '../components/AccountsModal'
|
||||
import AccountBorrows from '../components/account-page/AccountBorrows'
|
||||
import AccountBorrows from '../components/account_page/AccountBorrows'
|
||||
import Loading from '../components/Loading'
|
||||
|
||||
export default function Borrow() {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { useState } from 'react'
|
||||
import TopBar from '../components/TopBar'
|
||||
import PageBodyContainer from '../components/PageBodyContainer'
|
||||
import StatsTotals from '../components/stats-page/StatsTotals'
|
||||
import StatsAssets from '../components/stats-page/StatsAssets'
|
||||
import StatsPerps from '../components/stats-page/StatsPerps'
|
||||
import StatsTotals from '../components/stats_page/StatsTotals'
|
||||
import StatsAssets from '../components/stats_page/StatsAssets'
|
||||
import StatsPerps from '../components/stats_page/StatsPerps'
|
||||
import useMangoStats from '../hooks/useMangoStats'
|
||||
import Swipeable from '../components/mobile/Swipeable'
|
||||
import SwipeableTabs from '../components/mobile/SwipeableTabs'
|
||||
|
|
Loading…
Reference in New Issue