diff --git a/src/components/Forms/TokenAmountForm.tsx b/src/components/Forms/TokenAmountForm.tsx index 7b6e5b4ec..bcc8a9404 100644 --- a/src/components/Forms/TokenAmountForm.tsx +++ b/src/components/Forms/TokenAmountForm.tsx @@ -1,16 +1,16 @@ +import { BodySm, Box, ButtonProps, Icon } from "@threshold-network/components" +import { FormikErrors, FormikProps, withFormik } from "formik" import { FC, Ref } from "react" -import { Icon, Box, ButtonProps, BodySm } from "@threshold-network/components" -import { withFormik, FormikProps, FormikErrors } from "formik" import ThresholdCircleBrand from "../../static/icons/ThresholdCircleBrand" -import { FormikTokenBalanceInput } from "./FormikTokenBalanceInput" -import SubmitTxButton from "../SubmitTxButton" -import { Form } from "./Form" +import { formatTokenAmount } from "../../utils/formatAmount" import { DEFAULT_MIN_VALUE, getErrorsObj, validateAmountInRange, } from "../../utils/forms" -import { formatTokenAmount } from "../../utils/formatAmount" +import SubmitTxButton from "../SubmitTxButton" +import { Form } from "./Form" +import { FormikTokenBalanceInput } from "./FormikTokenBalanceInput" export type FormValues = { tokenAmount: string @@ -71,7 +71,7 @@ export const TokenAmountFormBase: FC< max={maxTokenAmount} helperText={helperText} isDisabled={isDisabled} - _disabled={{ bg: "gray.50", border: "none" }} + _disabled={{ bg: "gray.50", border: "none", cursor: "not-allowed" }} /> = ({ onClick={() => openModal(ModalType.SelectWallet)} {...buttonProps} type="button" + isDisabled={false} > Connect Wallet diff --git a/src/pages/Staking/NewStakeCard.tsx b/src/pages/Staking/NewStakeCard.tsx index 8784b9993..41079048d 100644 --- a/src/pages/Staking/NewStakeCard.tsx +++ b/src/pages/Staking/NewStakeCard.tsx @@ -7,11 +7,13 @@ import { useMinStakeAmount } from "../../hooks/useMinStakeAmount" import { useModal } from "../../hooks/useModal" import { useTokenBalance } from "../../hooks/useTokenBalance" import { formatTokenAmount } from "../../utils/formatAmount" +import { useWeb3React } from "@web3-react/core" const NewStakeCard: FC> = () => { const { openModal } = useModal() const tBalance = useTokenBalance(Token.T) const { minStakeAmount, isLoading, hasError } = useMinStakeAmount() + const { active } = useWeb3React() const openStakingModal = async (stakeAmount: string) => { openModal(ModalType.StakingChecklist, { stakeAmount }) @@ -39,6 +41,7 @@ const NewStakeCard: FC> = () => { maxTokenAmount={tBalance} placeholder={placeholder} minTokenAmount={minStakeAmount} + isDisabled={!active} /> diff --git a/src/utils/forms.ts b/src/utils/forms.ts index cb6780105..85c95ffa8 100644 --- a/src/utils/forms.ts +++ b/src/utils/forms.ts @@ -10,57 +10,79 @@ import { isAddress, isAddressZero } from "../web3/utils" import { formatTokenAmount } from "./formatAmount" import { getBridgeBTCSupportedAddressPrefixesText } from "./tBTC" -type ValidationMsg = string | ((amount: string) => string) -type ValidationOptions = { - greaterThanValidationMsg: ValidationMsg - lessThanValidationMsg: ValidationMsg - requiredMsg: string +type AmountValidationMessage = string | ((amount: string) => string) +type AmountValidationOptions = { + greaterThanValidationMessage: AmountValidationMessage + lessThanValidationMessage: AmountValidationMessage + requiredMessage: string + insufficientBalanceMessage: string } export const DEFAULT_MIN_VALUE = WeiPerEther.toString() -export const defaultLessThanMsg: (minAmount: string) => string = ( - minAmount +export const defaultLessThanMessage: (maxAmount: string) => string = ( + maxAmount ) => { return `The value should be less than or equal ${formatTokenAmount( - minAmount + maxAmount )}` } -export const defaultGreaterThanMsg: (minAmount: string) => string = ( - maxAmount +export const defaultGreaterThanMessage: (minAmount: string) => string = ( + minAmount ) => { return `The value should be greater than or equal ${formatTokenAmount( - maxAmount + minAmount )}` } -export const defaultValidationOptions: ValidationOptions = { - greaterThanValidationMsg: defaultGreaterThanMsg, - lessThanValidationMsg: defaultLessThanMsg, - requiredMsg: "Required", +export const defaultAmountValidationOptions: AmountValidationOptions = { + greaterThanValidationMessage: defaultGreaterThanMessage, + lessThanValidationMessage: defaultLessThanMessage, + requiredMessage: "Required.", + insufficientBalanceMessage: "Your wallet balance is insufficient.", +} + +const getAmountInRangeValidationMessage = ( + validationMessage: AmountValidationMessage, + value: string +) => { + return typeof validationMessage === "function" + ? validationMessage(value) + : validationMessage } export const validateAmountInRange = ( value: string, maxValue: string, minValue = DEFAULT_MIN_VALUE, - options: ValidationOptions = defaultValidationOptions + options: AmountValidationOptions = defaultAmountValidationOptions ) => { if (!value) { - return options.requiredMsg + return options.requiredMessage } const valueInBN = BigNumber.from(value) const maxValueInBN = BigNumber.from(maxValue) const minValueInBN = BigNumber.from(minValue) - if (valueInBN.gt(maxValueInBN)) { - return typeof options.lessThanValidationMsg === "function" - ? options.lessThanValidationMsg(maxValue) - : options.lessThanValidationMsg - } else if (valueInBN.lt(minValueInBN)) { - return typeof options.greaterThanValidationMsg === "function" - ? options.greaterThanValidationMsg(minValue) - : options.greaterThanValidationMsg + const isBalanceInsufficient = maxValueInBN.isZero() + const isMaximumValueExceeded = valueInBN.gt(maxValueInBN) + const isMinimumValueFulfilled = valueInBN.gte(minValueInBN) + + if (!isMinimumValueFulfilled) { + return getAmountInRangeValidationMessage( + options.greaterThanValidationMessage, + minValue + ) + } + if (isBalanceInsufficient) { + return options.insufficientBalanceMessage + } + + if (isMaximumValueExceeded) { + return getAmountInRangeValidationMessage( + options.lessThanValidationMessage, + maxValue + ) } }