mango-v4-ui/components/swap/SellTokenInput.tsx

127 lines
4.0 KiB
TypeScript
Raw Normal View History

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'
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'
import useMangoAccount from 'hooks/useMangoAccount'
import { toUiDecimalsForQuote } from '@blockworks-foundation/mango-v4'
2023-09-06 06:06:57 -07:00
import { SwapFormTokenListType } from './SwapFormTokenList'
import { useTokenMax } from './useTokenMax'
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
2023-09-06 06:06:57 -07:00
setShowTokenSelect: Dispatch<SetStateAction<SwapFormTokenListType>>
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')
const { mangoAccountAddress } = useMangoAccount()
2023-07-25 19:48:13 -07:00
const { group } = useMangoGroup()
const { isUnownedAccount } = useUnownedAccount()
const {
margin: useMargin,
inputBank,
amountIn: amountInFormValue,
} = mangoStore((s) => s.swap)
const freeCollateral = useMemo(() => {
const group = mangoStore.getState().group
const mangoAccount = mangoStore.getState().mangoAccount.current
return group && mangoAccount
? toUiDecimalsForQuote(mangoAccount.getCollateralValue(group))
: 10
}, [mangoAccountAddress])
2023-07-25 19:48:13 -07:00
return (
2023-08-23 15:17:04 -07:00
<div
className={`grid grid-cols-2 rounded-t-xl bg-th-bkg-2 p-3 pb-2 ${className}`}
>
2023-07-25 19:48:13 -07:00
<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-09-06 06:06:57 -07:00
maxAmount={useTokenMax}
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 bottom-1.5 right-3 text-xxs text-th-fgd-4">
2023-08-08 06:26:12 -07:00
{inputBank
? formatCurrencyValue(
inputBank.uiPrice * Number(amountInFormValue),
)
: ''}
</span>
) : null}
2023-07-25 19:48:13 -07:00
</div>
{mangoAccountAddress && 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