Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Don't show zero ammount message by default #2299

Merged
merged 12 commits into from
Jan 26, 2022
10 changes: 8 additions & 2 deletions src/custom/pages/Claim/FooterNavButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Trans } from '@lingui/macro'
import { isAddress } from '@ethersproject/address'
import { useClaimDispatchers, useClaimState, useHasClaimInvestmentFlowError } from 'state/claim/hooks'
import {
useClaimDispatchers,
useClaimState,
useHasClaimInvestmentFlowError,
useHasZeroInvested,
} from 'state/claim/hooks'
import { ButtonPrimary, ButtonSecondary } from 'components/Button'
import { ClaimStatus } from 'state/claim/actions'
import { FooterNavButtons as FooterNavButtonsWrapper, ReadMoreText } from './styled'
Expand Down Expand Up @@ -56,6 +61,7 @@ export default function FooterNavButtons({
} = useClaimDispatchers()

const hasError = useHasClaimInvestmentFlowError()
const hasZeroInvested = useHasZeroInvested()

const isInputAddressValid = isAddress(resolvedAddress || '')

Expand Down Expand Up @@ -104,7 +110,7 @@ export default function FooterNavButtons({
<Trans>Continue</Trans>
</ButtonPrimary>
) : investFlowStep === 1 ? (
<ButtonPrimary onClick={() => setInvestFlowStep(2)} disabled={hasError}>
<ButtonPrimary onClick={() => setInvestFlowStep(2)} disabled={hasError || hasZeroInvested}>
<Trans>Review</Trans>
</ButtonPrimary>
) : (
Expand Down
34 changes: 25 additions & 9 deletions src/custom/pages/Claim/InvestmentFlow/InvestOption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,9 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal
const { currencyAmount, price, cost: maxCost } = claim

const { account, chainId } = useActiveWeb3React()
const { updateInvestAmount, updateInvestError } = useClaimDispatchers()
const { updateInvestAmount, updateInvestError, setIsTouched } = useClaimDispatchers()
const { investFlowData, activeClaimAccount, estimatedGas } = useClaimState()

const investmentAmount = investFlowData[optionIndex].investedAmount

// Approve hooks
const {
approvalState: approveState,
Expand All @@ -87,6 +85,7 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal

const investedAmount = investFlowData[optionIndex].investedAmount
const inputError = investFlowData[optionIndex].error
const isTouched = investFlowData[optionIndex].isTouched

// Syntactic sugar fns for setting/resetting global state
const setInvestedAmount = useCallback(
Expand All @@ -101,6 +100,10 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal
() => updateInvestError({ index: optionIndex, error: undefined }),
[optionIndex, updateInvestError]
)
const setInputTouched = useCallback(
(value: boolean) => setIsTouched({ index: optionIndex, isTouched: value }),
[optionIndex, setIsTouched]
)

const token = currencyAmount?.currency
const isNative = token?.isNative
Expand All @@ -113,6 +116,11 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal

const isApproved = approveState === ApprovalState.APPROVED

const onUserInput = (input: string) => {
setTypedValue(input)
setInputTouched(true)
}

const gasCost = useMemo(() => {
if (!estimatedGas || !isNative) {
return
Expand All @@ -134,7 +142,8 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal

const value = maxCost.greaterThan(balance) ? balance : maxCost
setTypedValue(value.toExact() || '')
}, [balance, maxCost, noBalance])
setInputTouched(true)
}, [balance, maxCost, noBalance, setInputTouched])

// Save "local" approving state (pre-BC) for rendering spinners etc
const [approving, setApproving] = useState(false)
Expand Down Expand Up @@ -180,8 +189,8 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal
*/

const vCowAmount = useMemo(
() => calculateInvestmentAmounts(claim, investmentAmount)?.vCowAmount,
[claim, investmentAmount]
() => calculateInvestmentAmounts(claim, investedAmount)?.vCowAmount,
[claim, investedAmount]
)

// if there is investmentAmount in redux state for this option set it as typedValue
Expand Down Expand Up @@ -224,6 +233,11 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal
error = ErrorMessages.InsufficientBalance(token?.symbol)
} else if (!isNative && !isApproved) {
error = ErrorMessages.NotApproved(token?.symbol)
} else if (noBalance) {
error = ErrorMessages.InsufficientBalance(token?.symbol)
} else if (!parsedAmount && !isTouched) {
// this is to remove initial zero balance error message until user touches the input
error = ''
} else if (!parsedAmount) {
error = ErrorMessages.InvestmentIsZero
} else if (parsedAmount.greaterThan(maxCost)) {
Expand All @@ -232,7 +246,7 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal
error = ErrorMessages.InsufficientBalance(token?.symbol)
}

if (error) {
if (error !== null) {
// if there is error set it in redux
setInputError(error)
setPercentage('0')
Expand Down Expand Up @@ -264,6 +278,8 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal
setInvestedAmount,
percentage,
gasCost,
isTouched,
noBalance,
])

useEffect(() => {
Expand Down Expand Up @@ -370,7 +386,7 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal
{/* Error modal */}
<ErrorModal />
{/* Investment inputs */}
<InvestInput>
<InvestInput disabled={noBalance || !isSelfClaiming}>
<div>
<label>
<span>
Expand All @@ -387,7 +403,7 @@ export default function InvestOption({ claim, optionIndex, openModal, closeModal
)}
</span>
<StyledNumericalInput
onUserInput={setTypedValue}
onUserInput={onUserInput}
disabled={noBalance || !isSelfClaiming}
placeholder="0"
$loading={false}
Expand Down
5 changes: 5 additions & 0 deletions src/custom/pages/Claim/InvestmentFlow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
useUserEnhancedClaimData,
useClaimDispatchers,
useHasClaimInvestmentFlowError,
useSomeNotTouched,
} from 'state/claim/hooks'
import { ClaimStatus } from 'state/claim/actions'
import { InvestClaim } from 'state/claim/reducer'
Expand Down Expand Up @@ -134,6 +135,7 @@ export default function InvestmentFlow({ hasClaims, isAirdropOnly, modalCbs }: I
const claimData = useUserEnhancedClaimData(activeClaimAccount)

const hasError = useHasClaimInvestmentFlowError()
const someNotTouched = useSomeNotTouched()

// Filtering and splitting claims into free and selected paid claims
// `selectedClaims` are used on step 1 and 2
Expand Down Expand Up @@ -221,6 +223,9 @@ export default function InvestmentFlow({ hasClaims, isAirdropOnly, modalCbs }: I
))}

{hasError && <InvestFlowValidation>Fix the errors before continuing</InvestFlowValidation>}
{!hasError && someNotTouched && (
<InvestFlowValidation>Investment Amount is required to continue</InvestFlowValidation>
)}
</InvestContent>
) : null}
{/* Invest flow: Step 2 > Review summary */}
Expand Down
14 changes: 8 additions & 6 deletions src/custom/pages/Claim/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,7 @@ export const UnderlineButton = styled.button`
}
`

export const InvestInput = styled.span`
export const InvestInput = styled.span<{ disabled: boolean }>`
display: flex;
flex-flow: column wrap;
font-size: 15px;
Expand All @@ -1131,10 +1131,12 @@ export const InvestInput = styled.span`
flex-flow: row wrap;
padding: 12px;
position: relative;
background: ${({ theme }) => (theme.currencyInput?.background ? theme.currencyInput?.background : theme.bg1)};
background: ${({ theme, disabled }) =>
disabled ? theme.bg5 : theme.currencyInput?.background ? theme.currencyInput?.background : theme.bg1};
border: ${({ theme }) =>
theme.currencyInput?.border ? theme.currencyInput?.border : `border: 1px solid ${theme.bg2}`};
border-radius: 12px;
opacity: ${({ disabled }) => (disabled ? '0.7' : '1')};

> span {
margin-left: 5px;
Expand Down Expand Up @@ -1248,11 +1250,11 @@ export const InvestInput = styled.span`
&:hover {
color: ${({ theme }) => theme.text1};
}
}

> div > label > span > ${UnderlineButton} {
margin-left: 4px;

}
> div > label > span > ${UnderlineButton} {
margin-left: 4px;
}
`

export const InvestAvailableBar = styled.div<{ percentage?: number }>`
Expand Down
5 changes: 5 additions & 0 deletions src/custom/state/claim/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type ClaimActions = {
initInvestFlowData: () => void
updateInvestAmount: (payload: { index: number; amount: string }) => void
updateInvestError: (payload: { index: number; error: string | undefined }) => void
setIsTouched: (payload: { index: number; isTouched: boolean }) => void

// claim row selection
setSelected: (payload: number[]) => void
Expand Down Expand Up @@ -58,6 +59,10 @@ export const updateInvestError = createAction<{
index: number
error: string | undefined
}>('claim/updateInvestError')
export const setIsTouched = createAction<{
index: number
isTouched: boolean
}>('claim/setIsTouched')
// claim row selection
export const setSelected = createAction<number[]>('claim/setSelected')
export const setSelectedAll = createAction<boolean>('claim/setSelectedAll')
Expand Down
26 changes: 25 additions & 1 deletion src/custom/state/claim/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
resetClaimUi,
updateInvestError,
setEstimatedGas,
setIsTouched,
} from '../actions'
import { EnhancedUserClaimData } from 'pages/Claim/types'
import { supportedChainId } from 'utils/supportedChainId'
Expand Down Expand Up @@ -838,6 +839,7 @@ export function useClaimDispatchers() {
updateInvestAmount: (payload: { index: number; amount: string }) => dispatch(updateInvestAmount(payload)),
updateInvestError: (payload: { index: number; error: string | undefined }) =>
dispatch(updateInvestError(payload)),
setIsTouched: (payload: { index: number; isTouched: boolean }) => dispatch(setIsTouched(payload)),
// claim row selection
setSelected: (payload: number[]) => dispatch(setSelected(payload)),
setSelectedAll: (payload: boolean) => dispatch(setSelectedAll(payload)),
Expand All @@ -853,7 +855,7 @@ export function useClaimState() {
}

/**
* Returns a boolean indicating whehter there's an error on claim investment flow
* Returns a boolean indicating whether there's an error on claim investment flow
*/
export function useHasClaimInvestmentFlowError(): boolean {
const { investFlowData } = useClaimState()
Expand All @@ -863,6 +865,28 @@ export function useHasClaimInvestmentFlowError(): boolean {
}, [investFlowData])
}

/**
* Returns a boolean indicating whether there's "touched" field on claim investment flow
*/
export function useSomeNotTouched(): boolean {
const { investFlowData } = useClaimState()

return useMemo(() => {
return investFlowData.some(({ isTouched }) => !isTouched)
}, [investFlowData])
}

/**
* Returns a boolean indicating whether there's an zero invested amount on some invest option
*/
export function useHasZeroInvested(): boolean {
const { investFlowData } = useClaimState()

return useMemo(() => {
return investFlowData.some(({ investedAmount }) => investedAmount === '0')
}, [investFlowData])
}

/**
* Gets an array of available claims parsed and sorted for the UI
*
Expand Down
5 changes: 5 additions & 0 deletions src/custom/state/claim/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
ClaimStatus,
updateInvestError,
setEstimatedGas,
setIsTouched,
} from './actions'

export const initialState: ClaimState = {
Expand Down Expand Up @@ -43,6 +44,7 @@ export type InvestClaim = {
index: number
investedAmount: string
error?: string
isTouched?: boolean
}

export type ClaimState = {
Expand Down Expand Up @@ -126,4 +128,7 @@ export default createReducer(initialState, (builder) =>
state.claimedAmount = initialState.claimedAmount
state.estimatedGas = initialState.estimatedGas
})
.addCase(setIsTouched, (state, { payload: { index, isTouched } }) => {
state.investFlowData[index].isTouched = isTouched
})
)