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

Commit

Permalink
2245/hide claims while loading (#2338)
Browse files Browse the repository at this point in the history
* Removed unused hook

* Made claim loading return an isLoading state

* Refactored ClaimsTable and Investment flow

To take claims as parameter to avoid unnecessary hook calls

* Added a very ugly loader to claims page

* Organized a bit claim/index imports mess

* Refactoring claim page components props

* Start hook loading by default

* Show loader inside modal. Still ugly

Co-authored-by: Leandro <[email protected]>
  • Loading branch information
alfetopito and Leandro authored Jan 28, 2022
1 parent 32c2f4f commit 9bc32af
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 129 deletions.
4 changes: 1 addition & 3 deletions src/custom/pages/Claim/CanUserClaimMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import { COW_LINKS } from '.'
import SVG from 'react-inlinesvg'
import CowProtocolImage from 'assets/cow-swap/cowprotocol.svg'

type ClaimIntroductionProps = Pick<ClaimCommonTypes, 'hasClaims' | 'handleChangeAccount'> & {
isAirdropOnly: boolean
}
type ClaimIntroductionProps = Pick<ClaimCommonTypes, 'hasClaims' | 'handleChangeAccount' | 'isAirdropOnly'>

export default function CanUserClaimMessage({ hasClaims, isAirdropOnly, handleChangeAccount }: ClaimIntroductionProps) {
const { activeClaimAccount, claimStatus } = useClaimState()
Expand Down
18 changes: 6 additions & 12 deletions src/custom/pages/Claim/ClaimsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import CowProtocolLogo from 'components/CowProtocolLogo'
import { ClaimStatus } from 'state/claim/actions'
// import { UserClaimDataDetails } from './types' TODO: fix in another PR
import { formatMax, formatSmartLocaleAware } from 'utils/format'
import { EnhancedUserClaimData } from './types'
import { ClaimCommonTypes, EnhancedUserClaimData } from './types'
import { useAllClaimingTransactionIndices } from 'state/enhancedTransactions/hooks'
import { useUserEnhancedClaimData } from 'state/claim/hooks'

import { CustomLightSpinner } from 'theme'
import Circle from 'assets/images/blue-loader.svg'
Expand All @@ -20,10 +19,7 @@ import { COW_LINKS } from '.'
import SVG from 'react-inlinesvg'
import CowProtocolImage from 'assets/cow-swap/cowprotocol.svg'

export type ClaimsTableProps = {
isAirdropOnly: boolean
hasClaims: boolean
}
export type ClaimsTableProps = Pick<ClaimCommonTypes, 'claims' | 'hasClaims' | 'isAirdropOnly'>

// TODO: fix in other pr
type ClaimsTableRowProps = EnhancedUserClaimData & {
Expand Down Expand Up @@ -116,15 +112,13 @@ const ClaimsTableRow = ({
)
}

export default function ClaimsTable({ isAirdropOnly, hasClaims }: ClaimsTableProps) {
export default function ClaimsTable({ isAirdropOnly, claims, hasClaims }: ClaimsTableProps) {
const { selectedAll, selected, activeClaimAccount, claimStatus, isInvestFlowActive } = useClaimState()

const { setSelectedAll, setSelected } = useClaimDispatchers()

const pendingClaimsSet = useAllClaimingTransactionIndices()

const userClaimData = useUserEnhancedClaimData(activeClaimAccount)

const { deployment: start, investmentDeadline, airdropDeadline } = useClaimTimeInfo()

const handleSelect = (event: React.ChangeEvent<HTMLInputElement>, index: number) => {
Expand All @@ -136,12 +130,12 @@ export default function ClaimsTable({ isAirdropOnly, hasClaims }: ClaimsTablePro

const handleSelectAll = (event: React.ChangeEvent<HTMLInputElement>) => {
const checked = event.target.checked
const paid = getIndexes(getPaidClaims(userClaimData))
const paid = getIndexes(getPaidClaims(claims))
setSelected(checked ? paid : [])
setSelectedAll(checked)
}

const paidClaims = getPaidClaims(userClaimData)
const paidClaims = getPaidClaims(claims)

useEffect(() => {
setSelectedAll(selected.length === paidClaims.length)
Expand Down Expand Up @@ -174,7 +168,7 @@ export default function ClaimsTable({ isAirdropOnly, hasClaims }: ClaimsTablePro
</tr>
</thead>
<tbody>
{userClaimData.map((claim: EnhancedUserClaimData) => (
{claims.map((claim: EnhancedUserClaimData) => (
<ClaimsTableRow
key={claim.index}
{...claim}
Expand Down
3 changes: 2 additions & 1 deletion src/custom/pages/Claim/EligibleBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { EligibleBanner as EligibleBannerWrapper } from './styled'
import CheckCircle from 'assets/cow-swap/check.svg'
import { ClaimStatus } from 'state/claim/actions'
import SVG from 'react-inlinesvg'
import { ClaimCommonTypes } from 'pages/Claim/types'

export default function EligibleBanner({ hasClaims }: { hasClaims: boolean }) {
export default function EligibleBanner({ hasClaims }: Pick<ClaimCommonTypes, 'hasClaims'>) {
const { claimStatus, activeClaimAccount, isInvestFlowActive } = useClaimState()

const isEligible = claimStatus === ClaimStatus.DEFAULT && !!activeClaimAccount && !isInvestFlowActive && hasClaims
Expand Down
8 changes: 4 additions & 4 deletions src/custom/pages/Claim/FooterNavButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ReactNode, useEffect, useRef } from 'react'
import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'
import { Trans } from '@lingui/macro'
import { isAddress } from '@ethersproject/address'
import {
Expand All @@ -10,12 +12,10 @@ import { ButtonPrimary, ButtonSecondary } from 'components/Button'
import { ClaimStatus } from 'state/claim/actions'
import { FooterNavButtons as FooterNavButtonsWrapper } from './styled'
import { useActiveWeb3React } from 'hooks/web3'
import { ClaimsTableProps } from './ClaimsTable'
import { ClaimAddressProps } from './ClaimAddress'
import { ReactNode, useEffect, useRef } from 'react'
import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'
import { ClaimCommonTypes } from 'pages/Claim/types'

type FooterNavButtonsProps = Pick<ClaimsTableProps, 'hasClaims' | 'isAirdropOnly'> &
type FooterNavButtonsProps = Pick<ClaimCommonTypes, 'hasClaims' | 'isAirdropOnly'> &
Pick<ClaimAddressProps, 'toggleWalletModal'> & {
isPaidClaimsOnly: boolean
resolvedAddress: string | null
Expand Down
12 changes: 3 additions & 9 deletions src/custom/pages/Claim/InvestmentFlow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { FaqDrawer } from 'components/FaqDrawer'

import {
useClaimState,
useUserEnhancedClaimData,
useClaimDispatchers,
useHasClaimInvestmentFlowError,
useSomeNotTouched,
Expand Down Expand Up @@ -71,8 +70,7 @@ const FAQ_DATA = [
},
]

export type InvestmentFlowProps = Pick<ClaimCommonTypes, 'hasClaims'> & {
isAirdropOnly: boolean
export type InvestmentFlowProps = Pick<ClaimCommonTypes, 'hasClaims' | 'claims' | 'isAirdropOnly'> & {
modalCbs: {
openModal: (message: string, operationType: OperationType) => void
closeModal: () => void
Expand Down Expand Up @@ -149,23 +147,19 @@ function AccountDetails({ isClaimer, label, account, connectedAccount }: Account
)
}

export default function InvestmentFlow({ hasClaims, isAirdropOnly, modalCbs }: InvestmentFlowProps) {
export default function InvestmentFlow({ claims, hasClaims, isAirdropOnly, modalCbs }: InvestmentFlowProps) {
const { account } = useActiveWeb3React()
const { selected, activeClaimAccount, claimStatus, isInvestFlowActive, investFlowStep, investFlowData } =
useClaimState()
const { initInvestFlowData } = useClaimDispatchers()
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
// `freeClaims` are used on step 2
const [freeClaims, selectedClaims] = useMemo(
() => _classifyAndFilterClaimData(claimData, selected),
[claimData, selected]
)
const [freeClaims, selectedClaims] = useMemo(() => _classifyAndFilterClaimData(claims, selected), [claims, selected])

// Merge all claims together again, with their investment data for step 2
const allClaims: ClaimWithInvestmentData[] = useMemo(
Expand Down
126 changes: 68 additions & 58 deletions src/custom/pages/Claim/index.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
import { useCallback, useEffect, useMemo } from 'react'
import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'

import { useActiveWeb3React } from 'hooks/web3'
import useENS from 'hooks/useENS'
import useTransactionConfirmationModal from 'hooks/useTransactionConfirmationModal'
import { useErrorModal } from 'hooks/useErrorMessageAndModal'
import { useUserEnhancedClaimData, useUserUnclaimedAmount, useClaimCallback, ClaimInput } from 'state/claim/hooks'
import { PageWrapper, InnerPageWrapper } from 'pages/Claim/styled'
import EligibleBanner from './EligibleBanner'
import { getFreeClaims, hasPaidClaim, hasFreeClaim, prepareInvestClaims } from 'state/claim/hooks/utils'
import { useWalletModalToggle } from 'state/application/hooks'
import Confetti from 'components/Confetti'

import useENS from 'hooks/useENS'

import ClaimNav from './ClaimNav'
import { ClaimSummary } from './ClaimSummary'
import ClaimAddress from './ClaimAddress'
import CanUserClaimMessage from './CanUserClaimMessage'
import ClaimingStatus from './ClaimingStatus'
import ClaimsTable from './ClaimsTable'
import InvestmentFlow from './InvestmentFlow'

import { getFreeClaims, hasPaidClaim, hasFreeClaim, prepareInvestClaims } from 'state/claim/hooks/utils'
import { useClaimDispatchers, useClaimState } from 'state/claim/hooks'
import { ClaimStatus } from 'state/claim/actions'

import { OperationType } from 'components/TransactionConfirmationModal'
import useTransactionConfirmationModal from 'hooks/useTransactionConfirmationModal'
import Confetti from 'components/Confetti'
import Loader from 'components/Loader'

import { useErrorModal } from 'hooks/useErrorMessageAndModal'
import FooterNavButtons from './FooterNavButtons'
import { PageWrapper, InnerPageWrapper } from 'pages/Claim/styled'
import CanUserClaimMessage from './CanUserClaimMessage'
import ClaimAddress from './ClaimAddress'
import ClaimNav from './ClaimNav'
import ClaimingStatus from './ClaimingStatus'
import ClaimsOnOtherChainsBanner from './ClaimsOnOtherChainsBanner'
import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'
import ClaimsTable from './ClaimsTable'
import EligibleBanner from './EligibleBanner'
import FooterNavButtons from './FooterNavButtons'
import InvestmentFlow from './InvestmentFlow'
import { ClaimSummary } from './ClaimSummary'

/* TODO: Replace URLs with the actual final URL destinations */
export const COW_LINKS = {
Expand Down Expand Up @@ -83,7 +82,7 @@ export default function Claim() {
const { handleCloseError, handleSetError, ErrorModal } = useErrorModal()

// get user claim data
const userClaimData = useUserEnhancedClaimData(activeClaimAccount)
const { claims: userClaimData, isLoading: isClaimDataLoading } = useUserEnhancedClaimData(activeClaimAccount)

// get total unclaimed amount
const unclaimedAmount = useUserUnclaimedAmount(activeClaimAccount)
Expand All @@ -101,7 +100,7 @@ export default function Claim() {
setActiveClaimAccount('')
setActiveClaimAccountENS('')
setSelected([])
}, [setActiveClaimAccount, setClaimStatus, setSelected])
}, [setActiveClaimAccount, setActiveClaimAccountENS, setClaimStatus, setSelected])

// handle change account
const handleChangeAccount = () => {
Expand Down Expand Up @@ -212,43 +211,54 @@ export default function Claim() {
<ClaimsOnOtherChainsBanner />
{/* Claiming content */}
<InnerPageWrapper>
{/* Approve confirmation modal */}
<TransactionConfirmationModal />
{/* Error modal */}
<ErrorModal />
{/* If claim is confirmed > trigger confetti effect */}
<Confetti start={claimStatus === ClaimStatus.CONFIRMED} />
{/* Top nav buttons */}
<ClaimNav account={account} handleChangeAccount={handleChangeAccount} />
{/* Show general title OR total to claim (user has airdrop or airdrop+investment) --------------------------- */}
<EligibleBanner hasClaims={hasClaims} />
{/* Show total to claim (user has airdrop or airdrop+investment) */}
<ClaimSummary hasClaims={hasClaims} unclaimedAmount={unclaimedAmount} />
{/* Get address/ENS (user not connected yet or opted for checking 'another' account) */}
<ClaimAddress account={account} toggleWalletModal={toggleWalletModal} />
{/* Is Airdrop only (simple) - does user have claims? Show messages dependent on claim state */}
<CanUserClaimMessage
hasClaims={hasClaims}
isAirdropOnly={isAirdropOnly}
handleChangeAccount={handleChangeAccount}
/>

{/* Try claiming or inform successful claim */}
<ClaimingStatus />
{/* IS Airdrop + investing (advanced) */}
<ClaimsTable isAirdropOnly={isAirdropOnly} hasClaims={hasClaims} />
{/* Investing vCOW flow (advanced) */}
<InvestmentFlow isAirdropOnly={isAirdropOnly} hasClaims={hasClaims} modalCbs={{ openModal, closeModal }} />

<FooterNavButtons
handleCheckClaim={handleCheckClaim}
handleSubmitClaim={handleSubmitClaim}
toggleWalletModal={toggleWalletModal}
isAirdropOnly={isAirdropOnly}
isPaidClaimsOnly={isPaidClaimsOnly}
hasClaims={hasClaims}
resolvedAddress={resolvedAddress}
/>
{isClaimDataLoading ? (
<Loader />
) : (
<>
{/* Approve confirmation modal */}
<TransactionConfirmationModal />
{/* Error modal */}
<ErrorModal />
{/* If claim is confirmed > trigger confetti effect */}
<Confetti start={claimStatus === ClaimStatus.CONFIRMED} />
{/* Top nav buttons */}
<ClaimNav account={account} handleChangeAccount={handleChangeAccount} />
{/* Show general title OR total to claim (user has airdrop or airdrop+investment) --------------------------- */}
<EligibleBanner hasClaims={hasClaims} />
{/* Show total to claim (user has airdrop or airdrop+investment) */}
<ClaimSummary hasClaims={hasClaims} unclaimedAmount={unclaimedAmount} />
{/* Get address/ENS (user not connected yet or opted for checking 'another' account) */}
<ClaimAddress account={account} toggleWalletModal={toggleWalletModal} />
{/* Is Airdrop only (simple) - does user have claims? Show messages dependent on claim state */}
<CanUserClaimMessage
hasClaims={hasClaims}
isAirdropOnly={isAirdropOnly}
handleChangeAccount={handleChangeAccount}
/>

{/* Try claiming or inform successful claim */}
<ClaimingStatus />
{/* IS Airdrop + investing (advanced) */}
<ClaimsTable isAirdropOnly={isAirdropOnly} claims={userClaimData} hasClaims={hasClaims} />
{/* Investing vCOW flow (advanced) */}
<InvestmentFlow
isAirdropOnly={isAirdropOnly}
claims={userClaimData}
hasClaims={hasClaims}
modalCbs={{ openModal, closeModal }}
/>

<FooterNavButtons
handleCheckClaim={handleCheckClaim}
handleSubmitClaim={handleSubmitClaim}
toggleWalletModal={toggleWalletModal}
isAirdropOnly={isAirdropOnly}
isPaidClaimsOnly={isPaidClaimsOnly}
hasClaims={hasClaims}
resolvedAddress={resolvedAddress}
/>
</>
)}
</InnerPageWrapper>
</PageWrapper>
)
Expand Down
2 changes: 2 additions & 0 deletions src/custom/pages/Claim/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { GpEther } from 'constants/tokens'
export type ClaimCommonTypes = {
account: string | null | undefined
hasClaims: boolean
claims: EnhancedUserClaimData[]
isAirdropOnly: boolean
tokenCurrencyAmount: CurrencyAmount<Token>
handleChangeAccount: (e: SyntheticEvent<HTMLButtonElement>) => void
}
Expand Down
Loading

0 comments on commit 9bc32af

Please sign in to comment.