diff --git a/src/custom/pages/Claim/CanUserClaimMessage.tsx b/src/custom/pages/Claim/CanUserClaimMessage.tsx new file mode 100644 index 000000000..eb05e9709 --- /dev/null +++ b/src/custom/pages/Claim/CanUserClaimMessage.tsx @@ -0,0 +1,49 @@ +import { Trans } from '@lingui/macro' +import { ButtonSecondary } from 'components/Button' +import { ExternalLink } from 'theme' +import useClaimState from './state' +import { IntroDescription } from './styled' +import { ClaimCommonTypes } from './types' + +type ClaimIntroductionProps = Pick & { + isAirdropOnly: boolean +} + +export default function CanUserClaimMessage({ hasClaims, isAirdropOnly }: ClaimIntroductionProps) { + const { + state: { activeClaimAccount, claimAttempting, claimConfirmed }, + dispatchers, + } = useClaimState() + + const canClaim = !claimAttempting && !claimConfirmed && hasClaims && isAirdropOnly + + // only show when active claim account + if (!activeClaimAccount) return null + + if (canClaim) { + return ( + +

+ + Thank you for being a supporter of CowSwap and the CoW protocol. As an important member of the CowSwap + Community you may claim vCOW to be used for voting and governance. You can claim your tokens until{' '} + [XX-XX-XXXX - XX:XX GMT] + Read more about vCOW + +

+
+ ) + } else { + return ( + + + Unfortunately this account is not eligible for any vCOW claims.{' '} + dispatchers?.setActiveClaimAccount('')} padding="0"> + Try another account + {' '} + or read more about vCOW + + + ) + } +} diff --git a/src/custom/pages/Claim/ClaimAddress.tsx b/src/custom/pages/Claim/ClaimAddress.tsx new file mode 100644 index 000000000..5cacb104d --- /dev/null +++ b/src/custom/pages/Claim/ClaimAddress.tsx @@ -0,0 +1,67 @@ +import { useMemo } from 'react' +import { Trans } from '@lingui/macro' +import { ButtonSecondary } from 'components/Button' +import Circle from 'assets/images/blue-loader.svg' +import { CustomLightSpinner, TYPE } from 'theme' +import { CheckAddress, InputField, InputFieldTitle, InputErrorText } from './styled' +import useClaimState from './state' +import { ClaimCommonTypes } from './types' +import useENS from 'hooks/useENS' + +type ClaimAddressProps = Pick & { + toggleWalletModal: () => void +} + +export default function ClaimAddress({ account, toggleWalletModal }: ClaimAddressProps) { + const { + state: { activeClaimAccount, claimConfirmed, inputAddress }, + dispatchers, + } = useClaimState() + + const { loading, address: resolvedAddress } = useENS(inputAddress) + + // Show input error + const showInputError = useMemo( + () => Boolean(inputAddress.length > 0 && !loading && !resolvedAddress), + [resolvedAddress, inputAddress, loading] + ) + + const handleInputChange = (event: React.ChangeEvent) => { + const input = event.target.value + const withoutSpaces = input.replace(/\s+/g, '') + + dispatchers?.setInputAddress(withoutSpaces) + } + + if (activeClaimAccount || claimConfirmed) return null + + return ( + +

+ Enter an address to check for any eligible vCOW claims.
+ Note: It is possible to claim for an account, using any wallet/account. + {!account && ( + + or connect a wallet + + )} +

+ + + + Input address + {loading && } + + + + + {showInputError && ( + + + Enter valid token address or ENS + + + )} +
+ ) +} diff --git a/src/custom/pages/Claim/ClaimNav.tsx b/src/custom/pages/Claim/ClaimNav.tsx new file mode 100644 index 000000000..ee2bf671a --- /dev/null +++ b/src/custom/pages/Claim/ClaimNav.tsx @@ -0,0 +1,43 @@ +import { ButtonSecondary } from 'components/Button' +import { shortenAddress } from 'utils' +import useClaimState from './state' +import { TopNav, ClaimAccount, ClaimAccountButtons } from './styled' +import { ClaimCommonTypes } from './types' + +// should be updated +const DUMMY_IDENTICON = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAAA4ZJREFUeF7t3b1xFUEQReF5Jpj4BCC5CoIgiIFoSEAOyoEsZJEAPiaYojAxtWerWlvzye/96T5zb8/MW83t8enuZQ3+fb2/Dd59/tZffoymf90AMAsBACjAKIEUYDT9a1EACjCKIAUYTT8FWGYBZgHDY3D29noAPcAogXqA0fTrAfQAVgItBU+KEAuYzP5iASyABbCASRFiAZPZfwsW8PB8P7sUNVyA3W9/A8DeCABg7/ovAABAD7AzAxRg5+qvxQI2rz8AAGAdYGsG9ABbl18PsHn5AQAAS8F7M6AH2Lv+poGb1x8AAIjrAPXDhm8//6QafP74LsXX4Onnr19W5R4AALMAA4ACJBGjACl9a7GA+LPm6QTG+gNAD6AHSIOIArRZjCZQE5gGoCYwpU8TmP/LFQtgAWkMWgls31aygIQfC2ABw3sZZgFmAUnDWEBKHwtgAbtbQBxAGaB6/+n46uH1+bMF1Aeoewn1/tPxAIi7idMFrPcHAAAqQymeBaT09WAKQAE6ReEKFCAk74xQCkABzuDo8DUowOHUnRNIASjAOSQdvAoFOJi4s8IoAAU4i6VD16EAh9J2XhAFoADn0XTgShTgQNLODKEAFOBMnl59rawA09u50yPo6u8PgFePmf8DADAs4RTg4t8FxAE4fuoYBaAAleEUXxVQD5DSP3/wIwCGTx9nASwgakgLpwAUIBGkB0jp0wOMf9lTJTDW//LvTwEiAZpATWBEqIVXBaQALf8s4OoSGOsPAAC8VIZSfLaAx6e70TeoL3B1AKef/waANADzbiQA4kredAKvrmAUoAkABYj5u3wCKUAk4OoJvPrzs4DNAQYAAKwDFAZYQMneWprA4c00FrA5wAAAgB6gMKAHKNnTA4xvJ7OAzQEGAABaD1CPfYv5X1c/NWz6/bMCAKCdHQyAmAEK0A6epAARwKsrIAAAoAksDFCAeGxaSf6/WD2AHqAylOIpAAVIANXgqoCawFgBCkABIkItnAJc/PTwVv7eBLOAWAEWwAIiQi2cBbCARBALSOlb6/IW8PB8n/4/QP06tybw16f3sYQt/MP33+kCVcLrbxLH/0cQANpSLgAoQFIgCpDStxYLiJ82sQAWkMagJvDiR8ZQAApAAUIGzALMAgI+a5kFpPSZBeSPG/UAeoA0Bs0CzAISQDXYQpCFoMSQzaD4gxIWwALSCKzBV7eAv6T9ww6D8p2HAAAAAElFTkSuQmCC' + +type ClaimNavProps = Pick + +export default function ClaimNav({ account, handleChangeAccount }: ClaimNavProps) { + const { + state: { activeClaimAccount, activeClaimAccountENS, claimAttempting }, + dispatchers, + } = useClaimState() + + if (!activeClaimAccount) return null + + return ( + + +
+ {activeClaimAccount} +

{activeClaimAccountENS ? activeClaimAccountENS : shortenAddress(activeClaimAccount)}

+
+ + + {!!account && account !== activeClaimAccount && ( + dispatchers?.setActiveClaimAccount(account)}> + Your claims + + )} + + + Change account + + +
+
+ ) +} diff --git a/src/custom/pages/Claim/ClaimSummary.tsx b/src/custom/pages/Claim/ClaimSummary.tsx new file mode 100644 index 000000000..039373128 --- /dev/null +++ b/src/custom/pages/Claim/ClaimSummary.tsx @@ -0,0 +1,41 @@ +import { Trans } from '@lingui/macro' +import CowProtocolLogo from 'components/CowProtocolLogo' +import { formatSmart } from 'utils/format' +import useClaimState from './state' +import { ClaimSummary as ClaimSummaryWrapper, ClaimSummaryTitle, ClaimTotal } from './styled' +import { ClaimCommonTypes } from './types' + +type ClaimSummaryProps = Pick & { + unclaimedAmount: ClaimCommonTypes['tokenCurrencyAmount'] | undefined +} + +export default function ClaimSummary({ hasClaims, unclaimedAmount }: ClaimSummaryProps) { + const { + state: { activeClaimAccount, claimAttempting, claimConfirmed, claimSubmitted, isInvestFlowActive }, + } = useClaimState() + + const hasClaimSummary = !claimAttempting && !claimConfirmed && !claimSubmitted && !isInvestFlowActive + + if (!hasClaimSummary) return null + + return ( + + + {!activeClaimAccount && !hasClaims && ( + + + Claim vCOW token + + + )} + {activeClaimAccount && ( +
+ + Total available to claim +

{formatSmart(unclaimedAmount)} vCOW

+
+
+ )} +
+ ) +} diff --git a/src/custom/pages/Claim/index.tsx b/src/custom/pages/Claim/index.tsx index 5cbb867b4..cd5d72b26 100644 --- a/src/custom/pages/Claim/index.tsx +++ b/src/custom/pages/Claim/index.tsx @@ -18,16 +18,9 @@ import { ConfirmOrLoadingWrapper, ConfirmedIcon, AttemptFooter, - ClaimSummary, - ClaimTotal, - IntroDescription, ClaimTable, - ClaimAccount, - InputField, - CheckAddress, ClaimBreakdown, FooterNavButtons, - TopNav, InvestFlow, InvestContent, InvestTokenGroup, @@ -39,10 +32,6 @@ import { StepIndicator, Steps, TokenLogo, - ClaimSummaryTitle, - InputErrorText, - InputFieldTitle, - ClaimAccountButtons, } from 'pages/Claim/styled' import EligibleBanner from './EligibleBanner' import { @@ -58,12 +47,14 @@ import { import { useWalletModalToggle } from 'state/application/hooks' import CowProtocolLogo from 'components/CowProtocolLogo' import Confetti from 'components/Confetti' -import { shortenAddress } from 'utils' import { isAddress } from 'web3-utils' import useENS from 'hooks/useENS' -import { TYPE } from 'theme' import { formatSmart } from 'utils/format' import { useClaimReducer, ClaimContext } from './state' +import ClaimNav from './ClaimNav' +import ClaimSummary from './ClaimSummary' +import ClaimAddress from './ClaimAddress' +import CanUserClaimMessage from './CanUserClaimMessage' export default function Claim() { const { account, chainId } = useActiveWeb3React() @@ -76,7 +67,6 @@ export default function Claim() { inputAddress, // account activeClaimAccount, - activeClaimAccountENS, // check address isSearchUsed, // claiming @@ -112,19 +102,9 @@ export default function Claim() { setSelectedAll, } = dispatchers - const { loading, address: resolvedAddress, name: resolvedENS } = useENS(inputAddress) + const { address: resolvedAddress, name: resolvedENS } = useENS(inputAddress) const isInputAddressValid = useMemo(() => isAddress(resolvedAddress || ''), [resolvedAddress]) - // Show input error - const showInputError = useMemo( - () => Boolean(inputAddress.length > 0 && !loading && !resolvedAddress), - [resolvedAddress, inputAddress, loading] - ) - - // should be updated - const dummyIdenticon = - 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAAA4ZJREFUeF7t3b1xFUEQReF5Jpj4BCC5CoIgiIFoSEAOyoEsZJEAPiaYojAxtWerWlvzye/96T5zb8/MW83t8enuZQ3+fb2/Dd59/tZffoymf90AMAsBACjAKIEUYDT9a1EACjCKIAUYTT8FWGYBZgHDY3D29noAPcAogXqA0fTrAfQAVgItBU+KEAuYzP5iASyABbCASRFiAZPZfwsW8PB8P7sUNVyA3W9/A8DeCABg7/ovAABAD7AzAxRg5+qvxQI2rz8AAGAdYGsG9ABbl18PsHn5AQAAS8F7M6AH2Lv+poGb1x8AAIjrAPXDhm8//6QafP74LsXX4Onnr19W5R4AALMAA4ACJBGjACl9a7GA+LPm6QTG+gNAD6AHSIOIArRZjCZQE5gGoCYwpU8TmP/LFQtgAWkMWgls31aygIQfC2ABw3sZZgFmAUnDWEBKHwtgAbtbQBxAGaB6/+n46uH1+bMF1Aeoewn1/tPxAIi7idMFrPcHAAAqQymeBaT09WAKQAE6ReEKFCAk74xQCkABzuDo8DUowOHUnRNIASjAOSQdvAoFOJi4s8IoAAU4i6VD16EAh9J2XhAFoADn0XTgShTgQNLODKEAFOBMnl59rawA09u50yPo6u8PgFePmf8DADAs4RTg4t8FxAE4fuoYBaAAleEUXxVQD5DSP3/wIwCGTx9nASwgakgLpwAUIBGkB0jp0wOMf9lTJTDW//LvTwEiAZpATWBEqIVXBaQALf8s4OoSGOsPAAC8VIZSfLaAx6e70TeoL3B1AKef/waANADzbiQA4kredAKvrmAUoAkABYj5u3wCKUAk4OoJvPrzs4DNAQYAAKwDFAZYQMneWprA4c00FrA5wAAAgB6gMKAHKNnTA4xvJ7OAzQEGAABaD1CPfYv5X1c/NWz6/bMCAKCdHQyAmAEK0A6epAARwKsrIAAAoAksDFCAeGxaSf6/WD2AHqAylOIpAAVIANXgqoCawFgBCkABIkItnAJc/PTwVv7eBLOAWAEWwAIiQi2cBbCARBALSOlb6/IW8PB8n/4/QP06tybw16f3sYQt/MP33+kCVcLrbxLH/0cQANpSLgAoQFIgCpDStxYLiJ82sQAWkMagJvDiR8ZQAApAAUIGzALMAgI+a5kFpPSZBeSPG/UAeoA0Bs0CzAISQDXYQpCFoMSQzaD4gxIWwALSCKzBV7eAv6T9ww6D8p2HAAAAAElFTkSuQmCC' - // toggle wallet when disconnected const toggleWalletModal = useWalletModalToggle() @@ -170,12 +150,6 @@ export default function Claim() { setSelectedAll(checked) } - const handleInputChange = (event: React.ChangeEvent) => { - const input = event.target.value - const withoutSpaces = input.replace(/\s+/g, '') - setInputAddress(withoutSpaces) - } - // handle change account const handleChangeAccount = () => { setActiveClaimAccount('') @@ -263,114 +237,17 @@ export default function Claim() { {/* If claim is confirmed > trigger confetti effect */} - {/* START -- Top nav buttons */} - {!!activeClaimAccount && ( - - -
- {activeClaimAccount} -

{activeClaimAccountENS ? activeClaimAccountENS : shortenAddress(activeClaimAccount)}

-
- - - {!!account && account !== activeClaimAccount && ( - setActiveClaimAccount(account)}> - Your claims - - )} - - - Change account - - -
-
- )} - {/* END -- Top nav buttons */} - {/* START - Show general title OR total to claim (user has airdrop or airdrop+investment) --------------------------- */} + {/* Top nav buttons */} + + {/* Show general title OR total to claim (user has airdrop or airdrop+investment) --------------------------- */} - - {!claimAttempting && !claimConfirmed && !claimSubmitted && !isInvestFlowActive && ( - - - {!activeClaimAccount && !hasClaims && ( - - - Claim vCOW token - - - )} - {activeClaimAccount && ( -
- - Total available to claim -

{formatSmart(unclaimedAmount)} vCOW

-
-
- )} -
- )} - {/* END - Show total to claim (user has airdrop or airdrop+investment) --------------------------- */} - - {/* START - Get address/ENS (user not connected yet or opted for checking 'another' account) */} - {!activeClaimAccount && !claimConfirmed && ( - -

- Enter an address to check for any eligible vCOW claims.
- Note: It is possible to claim for an account, using any wallet/account. - {!account && ( - - or connect a wallet - - )} -

- - - - Input address - {loading && } - - - - - {showInputError && ( - - - Enter valid token address or ENS - - - )} -
- )} - {/* END - Get address/ENS (user not connected yet or opted for checking 'another' account) */} - - {/* START -- IS Airdrop only (simple) ----------------------------------------------------- */} - {!!activeClaimAccount && !!hasClaims && !!isAirdropOnly && !claimAttempting && !claimConfirmed && ( - -

- - Thank you for being a supporter of CowSwap and the CoW protocol. As an important member of the CowSwap - Community you may claim vCOW to be used for voting and governance. You can claim your tokens until{' '} - [XX-XX-XXXX - XX:XX GMT] - Read more about vCOW - -

-
- )} - {/* END -- IS Airdrop only (simple) ---------------------------------------- */} - - {/* START -- NO CLAIMS ----------------------------------------------------- */} - {!!activeClaimAccount && !hasClaims && !claimAttempting && !claimConfirmed && ( - - - Unfortunately this account is not eligible for any vCOW claims.{' '} - setActiveClaimAccount('')}>Try another account or - read more about vCOW - - - )} - {/* END ---- NO CLAIMS ----------------------------------------------------- */} + {/* Show total to claim (user has airdrop or airdrop+investment) */} + + {/* Get address/ENS (user not connected yet or opted for checking 'another' account) */} + + {/* Is Airdrop only (simple) - does user have claims? Show messages dependent on claim state */} + {/* START - Try claiming or inform succesfull claim ---------------------- */} {activeClaimAccount && (claimAttempting || claimConfirmed) && ( diff --git a/src/custom/pages/Claim/types.ts b/src/custom/pages/Claim/types.ts new file mode 100644 index 000000000..8218243d1 --- /dev/null +++ b/src/custom/pages/Claim/types.ts @@ -0,0 +1,9 @@ +import { CurrencyAmount, Token } from '@uniswap/sdk-core' +import { SyntheticEvent } from 'react' + +export type ClaimCommonTypes = { + account: string | null | undefined + hasClaims: boolean + tokenCurrencyAmount: CurrencyAmount + handleChangeAccount: (e: SyntheticEvent) => void +}