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

118 lines
3.9 KiB
TypeScript
Raw Normal View History

2023-07-25 19:48:13 -07:00
import MaxAmountButton from '@components/shared/MaxAmountButton'
import TokenSelect from './TokenSelect'
import Loading from '@components/shared/Loading'
import NumberFormat, {
NumberFormatValues,
SourceInfo,
} from 'react-number-format'
2023-08-08 19:53:59 -07:00
import { floorToDecimal, formatCurrencyValue } from 'utils/numbers'
2023-07-25 19:48:13 -07:00
import { useTranslation } from 'react-i18next'
2023-08-01 05:21:19 -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 { OUTPUT_TOKEN_DEFAULT } from 'utils/constants'
import { NUMBER_FORMAT_CLASSNAMES } from './MarketSwapForm'
2023-08-03 23:14:41 -07:00
import InlineNotification from '@components/shared/InlineNotification'
2023-08-08 19:53:59 -07:00
import useMangoAccount from 'hooks/useMangoAccount'
2023-07-25 19:48:13 -07:00
const BuyTokenInput = ({
2023-08-03 23:14:41 -07:00
error,
2023-07-25 19:48:13 -07:00
handleAmountOutChange,
loading,
setShowTokenSelect,
2023-08-01 05:21:19 -07:00
handleRepay,
2023-07-25 19:48:13 -07:00
}: {
2023-08-03 23:14:41 -07:00
error?: string
2023-07-25 19:48:13 -07:00
handleAmountOutChange: (e: NumberFormatValues, info: SourceInfo) => void
loading?: boolean
setShowTokenSelect: Dispatch<SetStateAction<'input' | 'output' | undefined>>
2023-08-08 21:31:49 -07:00
handleRepay?: (amountOut: string) => void
2023-07-25 19:48:13 -07:00
}) => {
const { t } = useTranslation('common')
2023-08-08 19:53:59 -07:00
const { mangoAccount } = useMangoAccount()
2023-07-25 19:48:13 -07:00
const { group } = useMangoGroup()
2023-08-01 05:21:19 -07:00
const { outputBank, amountOut: amountOutFormValue } = mangoStore(
(s) => s.swap,
)
2023-07-25 19:48:13 -07:00
const outputTokenBalanceBorrow = useMemo(() => {
2023-08-08 19:53:59 -07:00
if (!outputBank || !mangoAccount) return 0
const balance = mangoAccount.getTokenBalanceUi(outputBank)
const roundedBalance = floorToDecimal(
balance,
outputBank.mintDecimals,
).toNumber()
return balance && balance < 0 ? Math.abs(roundedBalance).toString() : 0
}, [mangoAccount, outputBank])
2023-07-25 19:48:13 -07:00
return (
<div className="mb-2 grid grid-cols-2 rounded-xl bg-th-bkg-2 p-3">
<div className="col-span-2 mb-2 flex items-end justify-between">
<p className="text-th-fgd-2">{t('buy')}</p>
2023-08-08 21:31:49 -07:00
{handleRepay && outputTokenBalanceBorrow ? (
2023-07-25 19:48:13 -07:00
<MaxAmountButton
className="mb-0.5 text-xs"
decimals={outputBank?.mintDecimals || 9}
label={t('repay')}
2023-08-08 19:53:59 -07:00
onClick={() => handleRepay(outputTokenBalanceBorrow)}
2023-07-25 19:48:13 -07:00
value={outputTokenBalanceBorrow}
/>
) : null}
</div>
<div className="col-span-1">
<TokenSelect
bank={
outputBank || group?.banksMapByName.get(OUTPUT_TOKEN_DEFAULT)?.[0]
}
showTokenList={setShowTokenSelect}
type="output"
/>
</div>
<div className="relative col-span-1">
{loading ? (
<div className="flex h-[56px] w-full items-center justify-center rounded-l-none rounded-r-lg bg-th-input-bkg">
<Loading />
</div>
) : (
<>
<NumberFormat
inputMode="decimal"
thousandSeparator=","
allowNegative={false}
isNumericString={true}
decimalScale={outputBank?.mintDecimals || 6}
name="amountOut"
id="amountOut"
className={NUMBER_FORMAT_CLASSNAMES}
placeholder="0.00"
value={amountOutFormValue}
onValueChange={handleAmountOutChange}
/>
2023-08-08 06:26:12 -07:00
{!isNaN(Number(amountOutFormValue)) ? (
<span className="absolute bottom-1.5 right-3 text-xxs text-th-fgd-4">
2023-08-08 06:26:12 -07:00
{outputBank
? formatCurrencyValue(
outputBank.uiPrice * Number(amountOutFormValue),
)
: ''}
</span>
) : null}
2023-07-25 19:48:13 -07:00
</>
)}
</div>
2023-08-03 23:14:41 -07:00
{error ? (
<div className="col-span-2 mt-1 flex justify-center">
<InlineNotification
type="error"
desc={error}
hideBorder
hidePadding
/>
</div>
) : null}
2023-07-25 19:48:13 -07:00
</div>
)
}
export default BuyTokenInput