2023-07-25 19:48:13 -07:00
|
|
|
|
import TokenSelect from './TokenSelect'
|
|
|
|
|
import NumberFormat, {
|
|
|
|
|
NumberFormatValues,
|
|
|
|
|
SourceInfo,
|
|
|
|
|
} from 'react-number-format'
|
|
|
|
|
import { formatCurrencyValue } from 'utils/numbers'
|
|
|
|
|
import { useTranslation } from 'react-i18next'
|
2023-08-10 17:52:42 -07:00
|
|
|
|
import { Dispatch, SetStateAction, useMemo } from 'react'
|
2023-07-25 19:48:13 -07:00
|
|
|
|
import mangoStore from '@store/mangoStore'
|
|
|
|
|
import useMangoGroup from 'hooks/useMangoGroup'
|
|
|
|
|
import { INPUT_TOKEN_DEFAULT } from 'utils/constants'
|
|
|
|
|
import { NUMBER_FORMAT_CLASSNAMES, withValueLimit } from './MarketSwapForm'
|
|
|
|
|
import MaxSwapAmount from './MaxSwapAmount'
|
|
|
|
|
import useUnownedAccount from 'hooks/useUnownedAccount'
|
2023-08-01 22:32:20 -07:00
|
|
|
|
import InlineNotification from '@components/shared/InlineNotification'
|
2023-08-10 17:52:42 -07:00
|
|
|
|
import useMangoAccount from 'hooks/useMangoAccount'
|
|
|
|
|
import { useWallet } from '@solana/wallet-adapter-react'
|
|
|
|
|
import { toUiDecimalsForQuote } from '@blockworks-foundation/mango-v4'
|
2023-07-25 19:48:13 -07:00
|
|
|
|
|
|
|
|
|
const SellTokenInput = ({
|
|
|
|
|
handleAmountInChange,
|
|
|
|
|
setShowTokenSelect,
|
2023-08-01 05:21:19 -07:00
|
|
|
|
handleMax,
|
2023-07-25 19:48:13 -07:00
|
|
|
|
className,
|
2023-08-01 22:32:20 -07:00
|
|
|
|
error,
|
2023-08-03 06:44:23 -07:00
|
|
|
|
isTriggerOrder,
|
2023-07-25 19:48:13 -07:00
|
|
|
|
}: {
|
|
|
|
|
handleAmountInChange: (e: NumberFormatValues, info: SourceInfo) => void
|
|
|
|
|
setShowTokenSelect: Dispatch<SetStateAction<'input' | 'output' | undefined>>
|
2023-08-01 05:21:19 -07:00
|
|
|
|
handleMax: (amountIn: string) => void
|
2023-07-25 19:48:13 -07:00
|
|
|
|
className?: string
|
2023-08-01 22:32:20 -07:00
|
|
|
|
error?: string
|
2023-08-03 06:44:23 -07:00
|
|
|
|
isTriggerOrder?: boolean
|
2023-07-25 19:48:13 -07:00
|
|
|
|
}) => {
|
|
|
|
|
const { t } = useTranslation('common')
|
2023-08-10 17:52:42 -07:00
|
|
|
|
const { mangoAccountAddress } = useMangoAccount()
|
|
|
|
|
const { connected } = useWallet()
|
2023-07-25 19:48:13 -07:00
|
|
|
|
const { group } = useMangoGroup()
|
|
|
|
|
const { isUnownedAccount } = useUnownedAccount()
|
|
|
|
|
const {
|
|
|
|
|
margin: useMargin,
|
|
|
|
|
inputBank,
|
|
|
|
|
amountIn: amountInFormValue,
|
|
|
|
|
} = mangoStore((s) => s.swap)
|
|
|
|
|
|
2023-08-10 17:52:42 -07:00
|
|
|
|
const freeCollateral = useMemo(() => {
|
|
|
|
|
const group = mangoStore.getState().group
|
|
|
|
|
const mangoAccount = mangoStore.getState().mangoAccount.current
|
|
|
|
|
return group && mangoAccount
|
|
|
|
|
? toUiDecimalsForQuote(mangoAccount.getCollateralValue(group))
|
|
|
|
|
: 0
|
|
|
|
|
}, [mangoAccountAddress])
|
|
|
|
|
|
2023-07-25 19:48:13 -07:00
|
|
|
|
return (
|
|
|
|
|
<div className={`grid grid-cols-2 rounded-xl bg-th-bkg-2 p-3 ${className}`}>
|
|
|
|
|
<div className="col-span-2 mb-2 flex items-center justify-between">
|
|
|
|
|
<p className="text-th-fgd-2">{t('sell')}</p>
|
|
|
|
|
{!isUnownedAccount ? (
|
|
|
|
|
<MaxSwapAmount
|
2023-08-03 06:44:23 -07:00
|
|
|
|
useMargin={isTriggerOrder ? false : useMargin}
|
2023-08-01 05:21:19 -07:00
|
|
|
|
setAmountIn={(v) => handleMax(v)}
|
2023-07-25 19:48:13 -07:00
|
|
|
|
/>
|
|
|
|
|
) : null}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="col-span-1">
|
|
|
|
|
<TokenSelect
|
|
|
|
|
bank={
|
|
|
|
|
inputBank || group?.banksMapByName.get(INPUT_TOKEN_DEFAULT)?.[0]
|
|
|
|
|
}
|
|
|
|
|
showTokenList={setShowTokenSelect}
|
|
|
|
|
type="input"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="relative col-span-1">
|
|
|
|
|
<NumberFormat
|
|
|
|
|
inputMode="decimal"
|
|
|
|
|
thousandSeparator=","
|
|
|
|
|
allowNegative={false}
|
|
|
|
|
isNumericString={true}
|
|
|
|
|
decimalScale={inputBank?.mintDecimals || 6}
|
|
|
|
|
name="amountIn"
|
|
|
|
|
id="amountIn"
|
|
|
|
|
className={NUMBER_FORMAT_CLASSNAMES}
|
|
|
|
|
placeholder="0.00"
|
|
|
|
|
value={amountInFormValue}
|
|
|
|
|
onValueChange={handleAmountInChange}
|
|
|
|
|
isAllowed={withValueLimit}
|
|
|
|
|
/>
|
2023-08-08 06:26:12 -07:00
|
|
|
|
{!isNaN(Number(amountInFormValue)) ? (
|
|
|
|
|
<span className="absolute right-3 bottom-1.5 text-xxs text-th-fgd-4">
|
|
|
|
|
{inputBank
|
|
|
|
|
? formatCurrencyValue(
|
|
|
|
|
inputBank.uiPrice * Number(amountInFormValue),
|
|
|
|
|
)
|
|
|
|
|
: '–'}
|
|
|
|
|
</span>
|
|
|
|
|
) : null}
|
2023-07-25 19:48:13 -07:00
|
|
|
|
</div>
|
2023-08-10 17:52:42 -07:00
|
|
|
|
{connected && freeCollateral <= 0 ? (
|
|
|
|
|
<div className="col-span-2 mt-1 flex justify-center">
|
|
|
|
|
<InlineNotification
|
|
|
|
|
type="warning"
|
|
|
|
|
desc={t('swap:warning-no-collateral')}
|
|
|
|
|
hideBorder
|
|
|
|
|
hidePadding
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
) : null}
|
2023-08-01 22:32:20 -07:00
|
|
|
|
{error ? (
|
2023-08-03 23:14:41 -07:00
|
|
|
|
<div className="col-span-2 mt-1 flex justify-center">
|
2023-08-01 22:32:20 -07:00
|
|
|
|
<InlineNotification
|
|
|
|
|
type="error"
|
|
|
|
|
desc={error}
|
|
|
|
|
hideBorder
|
|
|
|
|
hidePadding
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
) : null}
|
2023-07-25 19:48:13 -07:00
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default SellTokenInput
|