Skip to content

Commit

Permalink
feat: add form error when user doesn't have enough balance to buy cre…
Browse files Browse the repository at this point in the history
…dits
  • Loading branch information
r41ph committed Oct 10, 2024
1 parent cde9ef2 commit 6eb76bf
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ const BuyCreditsModal: React.FC<React.PropsWithChildren<BuyCreditsModalProps>> =
bankDenom: selectedSellOrder?.askDenom ?? '',
baseDenom: selectedSellOrder?.askBaseDenom,
}),
userBalance,
userBalance: userBalance || 0,
_,
})}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ import { UISellOrderInfo } from 'pages/Projects/AllProjects/AllProjects.types';

interface Params {
selectedSellOrder?: UISellOrderInfo;
askDenom?: string;
}

export const useFetchUserBalance = ({ selectedSellOrder }: Params): number => {
export const useFetchUserBalance = ({
selectedSellOrder,
askDenom,
}: Params): number | null => {
const { wallet } = useWallet();
const { bankClient } = useLedger();
const { data: allBalancesData } = useQuery(
const { data: allBalancesData, isLoading } = useQuery(
getAllBalancesQuery({
request: { address: wallet?.address },
client: bankClient,
Expand All @@ -25,10 +29,13 @@ export const useFetchUserBalance = ({ selectedSellOrder }: Params): number => {
const userBalance = useMemo(
() =>
allBalancesData?.balances.find(
balance => balance.denom === selectedSellOrder?.askDenom,
balance => balance.denom === selectedSellOrder?.askDenom || askDenom,
)?.amount,
[allBalancesData?.balances, selectedSellOrder?.askDenom],
[allBalancesData?.balances, selectedSellOrder?.askDenom, askDenom],
);

if (isLoading) {
return null;
}
return userBalance ? Number(userBalance) : 0;
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ import { msg } from '@lingui/macro';
export const MAX_AMOUNT = msg`Amount cannot exceed`;
export const MAX_CREDITS = msg`Credits cannot exceed`;
export const POSITIVE_NUMBER = msg`Must be positive`;
export const NOT_ENOUGH_BALANCE = msg`You don’t have enough`;
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@ import { z } from 'zod';
import {
MAX_AMOUNT,
MAX_CREDITS,
NOT_ENOUGH_BALANCE,
POSITIVE_NUMBER,
} from './ChooseCreditsForm.constants';

export const createChooseCreditsFormSchema = ({
creditsAvailable,
spendingCap,
userBalance,
}: {
creditsAvailable: number;
spendingCap: number;
userBalance: number;
}) => {
return z.object({
[CURRENCY_AMOUNT]: z.coerce
Expand All @@ -31,7 +34,8 @@ export const createChooseCreditsFormSchema = ({
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}`,
),
)
.max(userBalance, `${i18n._(NOT_ENOUGH_BALANCE)}`),
[CREDITS_AMOUNT]: z.coerce
.number()
.positive(i18n._(POSITIVE_NUMBER))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ import { Loading } from 'web-components/src/components/loading';
import { PrevNextButtons } from 'web-components/src/components/molecules/PrevNextButtons/PrevNextButtons';
import { UseStateSetter } from 'web-components/src/types/react/useState';

import { microToDenom } from 'lib/denom.utils';

import { NEXT, PAYMENT_OPTIONS } from 'pages/BuyCredits/BuyCredits.constants';
import { PaymentOptionsType } from 'pages/BuyCredits/BuyCredits.types';
import { UISellOrderInfo } from 'pages/Projects/AllProjects/AllProjects.types';
import { Currency } from 'components/molecules/CreditsAmount/CreditsAmount.types';
import { AllowedDenoms } from 'components/molecules/DenomLabel/DenomLabel.utils';

import { useFetchUserBalance } from '../BuyCreditsModal/hooks/useFetchUserBalance';
import { CryptoOptions } from './ChooseCreditsForm.CryptoOptions';
import { PaymentOptions } from './ChooseCreditsForm.PaymentOptions';
import {
Expand Down Expand Up @@ -99,11 +102,15 @@ export function ChooseCreditsForm({

const [spendingCap, setSpendingCap] = useState(0);
const [creditsAvailable, setCreditsAvailable] = useState(0);
// A big number here avoids the NOT_ENOUGH_BALANCE error on rendering
// the form until the actual user balance is fetched
const [userBalance, setUserBalance] = useState(10101010101010101);

const form = useZodForm({
schema: createChooseCreditsFormSchema({
creditsAvailable,
spendingCap,
userBalance,
}),
defaultValues: {
[CURRENCY_AMOUNT]: initialValues?.[CURRENCY_AMOUNT] || 0,
Expand All @@ -127,6 +134,17 @@ export function ChooseCreditsForm({
name: CURRENCY,
});

const microUserBalance = useFetchUserBalance({
askDenom: currency?.askDenom,
});

useEffect(() => {
if (microUserBalance) {
const _userBalance = microToDenom(microUserBalance);
setUserBalance(_userBalance);
}
}, [microUserBalance, userBalance]);

const filteredCryptoSellOrders = useMemo(
() =>
getFilteredCryptoSellOrders({
Expand Down

0 comments on commit 6eb76bf

Please sign in to comment.