diff --git a/src/custom/pages/Claim/FooterNavButtons.tsx b/src/custom/pages/Claim/FooterNavButtons.tsx
index 7045543fd..a913a5bef 100644
--- a/src/custom/pages/Claim/FooterNavButtons.tsx
+++ b/src/custom/pages/Claim/FooterNavButtons.tsx
@@ -1,3 +1,4 @@
+import { useMemo } from 'react'
import { Trans } from '@lingui/macro'
import { isAddress } from '@ethersproject/address'
import { useClaimDispatchers, useClaimState } from 'state/claim/hooks'
@@ -33,6 +34,7 @@ export default function FooterNavButtons({
// claiming
claimStatus,
// investment
+ investFlowData,
investFlowStep,
isInvestFlowActive,
// table select change
@@ -45,6 +47,10 @@ export default function FooterNavButtons({
setIsInvestFlowActive,
} = useClaimDispatchers()
+ const hasError = useMemo(() => {
+ return investFlowData.some(({ error }) => Boolean(error))
+ }, [investFlowData])
+
const isInputAddressValid = isAddress(resolvedAddress || '')
// User is connected and has some unclaimed claims
@@ -86,7 +92,7 @@ export default function FooterNavButtons({
Approve tokens
) : investFlowStep === 1 ? (
- setInvestFlowStep(2)}>
+ setInvestFlowStep(2)} disabled={hasError}>
Review
) : (
diff --git a/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx b/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx
index 2863fa21b..606e564c0 100644
--- a/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx
+++ b/src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx
@@ -28,7 +28,7 @@ enum ErrorMsgs {
export default function InvestOption({ approveData, claim, optionIndex }: InvestOptionProps) {
const { currencyAmount, price, cost: maxCost } = claim
- const { updateInvestAmount } = useClaimDispatchers()
+ const { updateInvestAmount, updateInvestError } = useClaimDispatchers()
const { investFlowData, activeClaimAccount } = useClaimState()
const { handleSetError, handleCloseError, ErrorModal } = useErrorModal()
@@ -37,9 +37,23 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
const [percentage, setPercentage] = useState('0')
const [typedValue, setTypedValue] = useState('0')
- const [inputError, setInputError] = useState('')
const investedAmount = investFlowData[optionIndex].investedAmount
+ const inputError = investFlowData[optionIndex].error
+
+ // Syntactic sugar fns for setting/resetting global state
+ const setInvestedAmount = useCallback(
+ (amount: string) => updateInvestAmount({ index: optionIndex, amount }),
+ [optionIndex, updateInvestAmount]
+ )
+ const setInputError = useCallback(
+ (error: string) => updateInvestError({ index: optionIndex, error }),
+ [optionIndex, updateInvestError]
+ )
+ const resetInputError = useCallback(
+ () => updateInvestError({ index: optionIndex, error: undefined }),
+ [optionIndex, updateInvestError]
+ )
const token = currencyAmount?.currency
const balance = useCurrencyBalance(account || undefined, token)
@@ -56,25 +70,25 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
const value = maxCost.greaterThan(balance) ? balance : maxCost
const amount = value.quotient.toString()
- updateInvestAmount({ index: optionIndex, amount })
+ setInvestedAmount(amount)
setTypedValue(value.toExact() || '')
- setInputError('')
+ resetInputError()
setPercentage(_formatPercentage(calculatePercentage(balance, maxCost)))
- }, [balance, maxCost, noBalance, optionIndex, updateInvestAmount])
+ }, [balance, maxCost, noBalance, resetInputError, setInvestedAmount])
// on input field change handler
const onInputChange = useCallback(
(value: string) => {
setTypedValue(value)
- setInputError('')
+ resetInputError()
// parse to CurrencyAmount
const parsedAmount = tryParseAmount(value, token)
// no amount/necessary params, return 0
if (!parsedAmount || !maxCost || !balance || !token) {
- updateInvestAmount({ index: optionIndex, amount: '0' })
+ setInvestedAmount('0')
setPercentage('0')
return
}
@@ -86,18 +100,18 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
if (errorMsg) {
setInputError(errorMsg)
- updateInvestAmount({ index: optionIndex, amount: '0' })
+ setInvestedAmount('0')
setPercentage('0')
return
}
// update redux state with new investAmount value
- updateInvestAmount({ index: optionIndex, amount: parsedAmount.quotient.toString() })
+ setInvestedAmount(parsedAmount.quotient.toString())
// update the local state with percentage value
setPercentage(_formatPercentage(calculatePercentage(parsedAmount, maxCost)))
},
- [balance, maxCost, optionIndex, token, updateInvestAmount]
+ [balance, maxCost, resetInputError, setInputError, setInvestedAmount, token]
)
// Cache approveData methods
@@ -142,7 +156,7 @@ export default function InvestOption({ approveData, claim, optionIndex }: Invest
setMaxAmount()
}
}
- }, [balance, isSelfClaiming, maxCost, setMaxAmount])
+ }, [balance, isSelfClaiming, maxCost, optionIndex, setInputError, setMaxAmount])
// this will set input and percentage value if you go back from the review page
useEffect(() => {
diff --git a/src/custom/state/claim/actions.ts b/src/custom/state/claim/actions.ts
index 85c037b01..01bd3582d 100644
--- a/src/custom/state/claim/actions.ts
+++ b/src/custom/state/claim/actions.ts
@@ -25,6 +25,7 @@ export type ClaimActions = {
setInvestFlowStep: (payload: number) => void
initInvestFlowData: () => void
updateInvestAmount: (payload: { index: number; amount: string }) => void
+ updateInvestError: (payload: { index: number; error: string | undefined }) => void
// claim row selection
setSelected: (payload: number[]) => void
@@ -51,7 +52,10 @@ export const updateInvestAmount = createAction<{
index: number
amount: string
}>('claim/updateInvestAmount')
-
+export const updateInvestError = createAction<{
+ index: number
+ error: string | undefined
+}>('claim/updateInvestError')
// claim row selection
export const setSelected = createAction('claim/setSelected')
export const setSelectedAll = createAction('claim/setSelectedAll')
diff --git a/src/custom/state/claim/hooks/index.ts b/src/custom/state/claim/hooks/index.ts
index 70bda0727..d5ce0f0aa 100644
--- a/src/custom/state/claim/hooks/index.ts
+++ b/src/custom/state/claim/hooks/index.ts
@@ -53,6 +53,7 @@ import {
setSelectedAll,
ClaimStatus,
resetClaimUi,
+ updateInvestError,
} from '../actions'
import { EnhancedUserClaimData } from 'pages/Claim/types'
import { supportedChainId } from 'utils/supportedChainId'
@@ -767,6 +768,8 @@ export function useClaimDispatchers() {
setInvestFlowStep: (payload: number) => dispatch(setInvestFlowStep(payload)),
initInvestFlowData: () => dispatch(initInvestFlowData()),
updateInvestAmount: (payload: { index: number; amount: string }) => dispatch(updateInvestAmount(payload)),
+ updateInvestError: (payload: { index: number; error: string | undefined }) =>
+ dispatch(updateInvestError(payload)),
// claim row selection
setSelected: (payload: number[]) => dispatch(setSelected(payload)),
setSelectedAll: (payload: boolean) => dispatch(setSelectedAll(payload)),
diff --git a/src/custom/state/claim/reducer.ts b/src/custom/state/claim/reducer.ts
index 4f308437c..6f48b3cdb 100644
--- a/src/custom/state/claim/reducer.ts
+++ b/src/custom/state/claim/reducer.ts
@@ -14,6 +14,7 @@ import {
setSelectedAll,
resetClaimUi,
ClaimStatus,
+ updateInvestError,
} from './actions'
export const initialState: ClaimState = {
@@ -39,6 +40,7 @@ export const initialState: ClaimState = {
export type InvestClaim = {
index: number
investedAmount: string
+ error?: string
}
export type ClaimState = {
@@ -101,6 +103,9 @@ export default createReducer(initialState, (builder) =>
.addCase(updateInvestAmount, (state, { payload: { index, amount } }) => {
state.investFlowData[index].investedAmount = amount
})
+ .addCase(updateInvestError, (state, { payload: { index, error } }) => {
+ state.investFlowData[index].error = error
+ })
.addCase(setSelected, (state, { payload }) => {
state.selected = payload
})