From 9f0816418656b7b1936c64787fecce08b6c5f0d2 Mon Sep 17 00:00:00 2001 From: kyranjamie Date: Tue, 28 Jul 2020 15:09:11 +0200 Subject: [PATCH] feat: add error handling when total > balance, closes #196, #197 --- app/components/error-label.tsx | 8 ++-- .../transaction-list-item-pending.tsx | 2 +- .../transaction/transaction-modal-layout.tsx | 2 +- app/modals/transaction/transaction-modal.tsx | 38 +++++++++++++++++-- app/pages/root.tsx | 4 +- 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/app/components/error-label.tsx b/app/components/error-label.tsx index 514322137..de294769c 100644 --- a/app/components/error-label.tsx +++ b/app/components/error-label.tsx @@ -3,11 +3,13 @@ import { Flex, Box, FlexProps } from '@blockstack/ui'; import { ExclamationMark } from './icons/exclamation-mark'; -type ErrorLabelProps = FlexProps; +interface ErrorLabelProps extends FlexProps { + size?: 'sm' | 'md'; +} -export const ErrorLabel: React.FC = ({ children, ...rest }) => ( +export const ErrorLabel: React.FC = ({ children, size = 'sm', ...rest }) => ( - + {children} diff --git a/app/components/home/transaction-list/transaction-list-item-pending.tsx b/app/components/home/transaction-list/transaction-list-item-pending.tsx index cfa103e21..48b9f48f6 100644 --- a/app/components/home/transaction-list/transaction-list-item-pending.tsx +++ b/app/components/home/transaction-list/transaction-list-item-pending.tsx @@ -40,7 +40,7 @@ export const TransactionListItemPending: FC = ( - {toHumanReadableStx(tx.amount)} + −{toHumanReadableStx(tx.amount)} Pending diff --git a/app/modals/transaction/transaction-modal-layout.tsx b/app/modals/transaction/transaction-modal-layout.tsx index 91eb5969a..6f51e7765 100644 --- a/app/modals/transaction/transaction-modal-layout.tsx +++ b/app/modals/transaction/transaction-modal-layout.tsx @@ -44,7 +44,7 @@ export const TxModalFooter: FC = ({ children }) => ( ); export const TxModalPreview: FC = ({ children }) => ( - + {children} ); diff --git a/app/modals/transaction/transaction-modal.tsx b/app/modals/transaction/transaction-modal.tsx index 6f7f2ba2c..de7d5d63b 100644 --- a/app/modals/transaction/transaction-modal.tsx +++ b/app/modals/transaction/transaction-modal.tsx @@ -4,7 +4,7 @@ import { useFormik } from 'formik'; import * as yup from 'yup'; import BN from 'bn.js'; import { BigNumber } from 'bignumber.js'; -import { Modal, Text, Button } from '@blockstack/ui'; +import { Modal, Text, Button, Box } from '@blockstack/ui'; import { StacksTransaction } from '@blockstack/stacks-transactions'; import { RootState } from '../../store'; @@ -25,6 +25,8 @@ import { createStxTransaction } from '../../crypto/create-stx-tx'; import { validateAddressChain } from '../../crypto/validate-address-net'; import { broadcastStxTransaction } from '../../store/transaction'; import { toHumanReadableStx, stxToMicroStx } from '../../utils/unit-convert'; +import { ErrorLabel } from '../../components/error-label'; +import { ErrorText } from '../../components/error-text'; interface TxModalProps { balance: string; @@ -53,6 +55,8 @@ export const TransactionModal: FC = ({ balance, address }) => { mnemonic: selectMnemonic(state), })); + const totalIsMoreThanBalance = total.isGreaterThan(balance); + const form = useFormik({ initialValues: { recipient: '', @@ -74,17 +78,28 @@ export const TransactionModal: FC = ({ balance, address }) => { ), amount: yup .number() - .positive('You cannot send a negative amount of STX') .typeError('Amount of STX must be described as number') + .positive('You cannot send a negative amount of STX') .test( 'test-has-less-than-or-equal-to-6-decimal-places', - 'STX cannot have more than 6 decimal places', + 'STX do not have more than 6 decimal places', (value: number) => { // Explicit base ensures BigNumber doesn't use exponential notation const decimals = new BigNumber(value).toString(10).split('.')[1]; return decimals === undefined || decimals.length <= 6; } ) + .test( + 'test-address-has-enough-balance', + 'Cannot send more STX than available balance', + (value: number) => { + // If there's no input, pass this test, + // otherwise it'll render the error for this test + if (value === undefined) return true; + const enteredAmount = stxToMicroStx(value); + return enteredAmount.isLessThanOrEqualTo(balance); + } + ) .required(), }), onSubmit: async () => { @@ -162,6 +177,15 @@ export const TransactionModal: FC = ({ balance, address }) => { {toHumanReadableStx(total.toString())} + + {totalIsMoreThanBalance && ( + + + You have insufficient balance to complete this transfer. + + + )} + ), footer: ( @@ -169,7 +193,13 @@ export const TransactionModal: FC = ({ balance, address }) => { - diff --git a/app/pages/root.tsx b/app/pages/root.tsx index 1a9b37782..e03c364ad 100644 --- a/app/pages/root.tsx +++ b/app/pages/root.tsx @@ -24,9 +24,7 @@ interface RootProps { } function Root({ store, history }: RootProps) { - useEffect(() => { - void loadFonts(); - }, []); + useEffect(() => void loadFonts(), []); return (