diff --git a/src/components/AmplitudeAnalytics/constants.ts b/src/components/AmplitudeAnalytics/constants.ts index 4c9a018858..32ef18923f 100644 --- a/src/components/AmplitudeAnalytics/constants.ts +++ b/src/components/AmplitudeAnalytics/constants.ts @@ -17,7 +17,10 @@ export enum EventName { * Known pages in the app. Highest order context. */ export const enum PageName { + EXPLORE_PAGE = 'explore-page', + POOL_PAGE = 'pool-page', SWAP_PAGE = 'swap-page', + VOTE_PAGE = 'vote-page', // alphabetize additional page names. } diff --git a/src/pages/CreateProposal/index.tsx b/src/pages/CreateProposal/index.tsx index 6906308205..603ec8a62c 100644 --- a/src/pages/CreateProposal/index.tsx +++ b/src/pages/CreateProposal/index.tsx @@ -3,6 +3,8 @@ import { getAddress, isAddress } from '@ethersproject/address' import { Trans } from '@lingui/macro' import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core' import { useWeb3React } from '@web3-react/core' +import { PageName } from 'components/AmplitudeAnalytics/constants' +import { Trace } from 'components/AmplitudeAnalytics/Trace' import { ButtonError } from 'components/Button' import { BlueCard } from 'components/Card' import { AutoColumn } from 'components/Column' @@ -225,63 +227,66 @@ ${bodyValue} } return ( - - - - - - - - Tip: Select an action and describe your proposal for the community. The proposal cannot - be modified after submission, so please verify all information before submitting. The voting period will - begin immediately and last for 7 days. To propose a custom action,{' '} - - read the docs - - . - - - - + + + + + + + + + Tip: Select an action and describe your proposal for the community. The proposal + cannot be modified after submission, so please verify all information before submitting. The voting + period will begin immediately and last for 7 days. To propose a custom action,{' '} + + read the docs + + . + + + + - - + + + + {!hasEnoughVote ? ( + + Don’t have 2.5M votes? Anyone can create an autonomous proposal using{' '} + fish.vote + + ) : null} + + handleActionChange(proposalAction)} /> - - - {!hasEnoughVote ? ( - - Don’t have 2.5M votes? Anyone can create an autonomous proposal using{' '} - fish.vote - - ) : null} - - handleActionChange(proposalAction)} - /> - - + + + ) } diff --git a/src/pages/Pool/PositionPage.tsx b/src/pages/Pool/PositionPage.tsx index 693350a5c2..eca915fa97 100644 --- a/src/pages/Pool/PositionPage.tsx +++ b/src/pages/Pool/PositionPage.tsx @@ -4,6 +4,8 @@ import { Trans } from '@lingui/macro' import { Currency, CurrencyAmount, Fraction, Percent, Price, Token } from '@uniswap/sdk-core' import { NonfungiblePositionManager, Pool, Position } from '@uniswap/v3-sdk' import { useWeb3React } from '@web3-react/core' +import { PageName } from 'components/AmplitudeAnalytics/constants' +import { Trace } from 'components/AmplitudeAnalytics/Trace' import { sendEvent } from 'components/analytics' import Badge from 'components/Badge' import { ButtonConfirmed, ButtonGray, ButtonPrimary } from 'components/Button' @@ -567,344 +569,347 @@ export function PositionPage({
) : ( - <> - - setShowConfirm(false)} - attemptingTxn={collecting} - hash={collectMigrationHash ?? ''} - content={() => ( - Claim fees} - onDismiss={() => setShowConfirm(false)} - topContent={modalHeader} - /> - )} - pendingText={Collecting fees} - /> - - - - - ← Back to Pools Overview - - - - - - -  {currencyQuote?.symbol} / {currencyBase?.symbol} - - - - {new Percent(feeAmount, 1_000_000).toSignificant()}% - - - - - {ownsNFT && ( - - {currency0 && currency1 && feeAmount && tokenId ? ( - - Increase Liquidity - - ) : null} - {tokenId && !removed ? ( - - Remove Liquidity - - ) : null} - - )} - - - - - {'result' in metadata ? ( - -
- -
- {typeof chainId === 'number' && owner && !ownsNFT ? ( - - Owner - - ) : null} -
- ) : ( - - - - )} - - - - - - {fiatValueOfLiquidity?.greaterThan(new Fraction(1, 100)) ? ( - - ${fiatValueOfLiquidity.toFixed(2, { groupSeparator: ',' })} - - ) : ( - - $- - - )} - - - - - - - - {inverted ? position?.amount0.toSignificant(4) : position?.amount1.toSignificant(4)} - - {typeof ratio === 'number' && !removed ? ( - - - {inverted ? ratio : 100 - ratio}% - - - ) : null} - - - - - - - {inverted ? position?.amount1.toSignificant(4) : position?.amount0.toSignificant(4)} - - {typeof ratio === 'number' && !removed ? ( - - - {inverted ? 100 - ratio : ratio}% - - - ) : null} - - - - - - - - - - - - - {fiatValueOfFees?.greaterThan(new Fraction(1, 100)) ? ( - - ${fiatValueOfFees.toFixed(2, { groupSeparator: ',' })} - - ) : ( - - $- - - )} - - {ownsNFT && (feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) || !!collectMigrationHash) ? ( - setShowConfirm(true)} - > - {!!collectMigrationHash && !isCollectPending ? ( - - Collected - - ) : isCollectPending || collecting ? ( - - {' '} - - Collecting - - - ) : ( - <> - - Collect fees - - - )} - - ) : null} - - - - - - - - {feeValueUpper?.currency?.symbol} - - - - {feeValueUpper ? formatCurrencyAmount(feeValueUpper, 4) : '-'} - - - - - - - {feeValueLower?.currency?.symbol} - - - - {feeValueLower ? formatCurrencyAmount(feeValueLower, 4) : '-'} - - - - - - {showCollectAsWeth && ( - - - - Collect as {nativeWrappedSymbol} - - setReceiveWETH((receiveWETH) => !receiveWETH)} - /> - - - )} - - - -
- - - - - - - <> - - - - - - - {currencyBase && currencyQuote && ( - setManuallyInverted(!manuallyInverted)} - /> - )} - - - - - - - - Min price - - - {formatTickPrice(priceLower, tickAtLimit, Bound.LOWER)} - - - {' '} - - {currencyQuote?.symbol} per {currencyBase?.symbol} - - - - {inRange && ( - - Your position will be 100% {currencyBase?.symbol} at this price. - - )} - - - - - - - - Max price - - - {formatTickPrice(priceUpper, tickAtLimit, Bound.UPPER)} - - - {' '} - - {currencyQuote?.symbol} per {currencyBase?.symbol} - - - - {inRange && ( - - Your position will be 100% {currencyQuote?.symbol} at this price. - - )} - - - - + <> + + setShowConfirm(false)} + attemptingTxn={collecting} + hash={collectMigrationHash ?? ''} + content={() => ( + Claim fees} + onDismiss={() => setShowConfirm(false)} + topContent={modalHeader} /> + )} + pendingText={Collecting fees} + /> + + + + + ← Back to Pools Overview + + + + + + +  {currencyQuote?.symbol} / {currencyBase?.symbol} + + + + {new Percent(feeAmount, 1_000_000).toSignificant()}% + + + + + {ownsNFT && ( + + {currency0 && currency1 && feeAmount && tokenId ? ( + + Increase Liquidity + + ) : null} + {tokenId && !removed ? ( + + Remove Liquidity + + ) : null} + + )} + + - -
-
- - + + {'result' in metadata ? ( + +
+ +
+ {typeof chainId === 'number' && owner && !ownsNFT ? ( + + Owner + + ) : null} +
+ ) : ( + + + + )} + + + + + + {fiatValueOfLiquidity?.greaterThan(new Fraction(1, 100)) ? ( + + ${fiatValueOfLiquidity.toFixed(2, { groupSeparator: ',' })} + + ) : ( + + $- + + )} + + + + + + + + {inverted ? position?.amount0.toSignificant(4) : position?.amount1.toSignificant(4)} + + {typeof ratio === 'number' && !removed ? ( + + + {inverted ? ratio : 100 - ratio}% + + + ) : null} + + + + + + + {inverted ? position?.amount1.toSignificant(4) : position?.amount0.toSignificant(4)} + + {typeof ratio === 'number' && !removed ? ( + + + {inverted ? 100 - ratio : ratio}% + + + ) : null} + + + + + + + + + + + + + {fiatValueOfFees?.greaterThan(new Fraction(1, 100)) ? ( + + ${fiatValueOfFees.toFixed(2, { groupSeparator: ',' })} + + ) : ( + + $- + + )} + + {ownsNFT && + (feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) || !!collectMigrationHash) ? ( + setShowConfirm(true)} + > + {!!collectMigrationHash && !isCollectPending ? ( + + Collected + + ) : isCollectPending || collecting ? ( + + {' '} + + Collecting + + + ) : ( + <> + + Collect fees + + + )} + + ) : null} + + + + + + + + {feeValueUpper?.currency?.symbol} + + + + {feeValueUpper ? formatCurrencyAmount(feeValueUpper, 4) : '-'} + + + + + + + {feeValueLower?.currency?.symbol} + + + + {feeValueLower ? formatCurrencyAmount(feeValueLower, 4) : '-'} + + + + + + {showCollectAsWeth && ( + + + + Collect as {nativeWrappedSymbol} + + setReceiveWETH((receiveWETH) => !receiveWETH)} + /> + + + )} + + + +
+ + + + + + + <> + + + + + + + {currencyBase && currencyQuote && ( + setManuallyInverted(!manuallyInverted)} + /> + )} + + + + + + + + Min price + + + {formatTickPrice(priceLower, tickAtLimit, Bound.LOWER)} + + + {' '} + + {currencyQuote?.symbol} per {currencyBase?.symbol} + + + + {inRange && ( + + Your position will be 100% {currencyBase?.symbol} at this price. + + )} + + + + + + + + Max price + + + {formatTickPrice(priceUpper, tickAtLimit, Bound.UPPER)} + + + {' '} + + {currencyQuote?.symbol} per {currencyBase?.symbol} + + + + {inRange && ( + + Your position will be 100% {currencyQuote?.symbol} at this price. + + )} + + + + + + + + + + + ) } diff --git a/src/pages/Pool/index.tsx b/src/pages/Pool/index.tsx index 5250eb7e2c..f1d35e7882 100644 --- a/src/pages/Pool/index.tsx +++ b/src/pages/Pool/index.tsx @@ -1,5 +1,7 @@ import { Trans } from '@lingui/macro' import { useWeb3React } from '@web3-react/core' +import { PageName } from 'components/AmplitudeAnalytics/constants' +import { Trace } from 'components/AmplitudeAnalytics/Trace' import { ButtonGray, ButtonPrimary, ButtonText } from 'components/Button' import { AutoColumn } from 'components/Column' import { FlyoutAlignment, NewMenu } from 'components/Menu' @@ -252,76 +254,78 @@ export default function Pool() { ] return ( - <> - - - - - - - Pools Overview - - - {showV2Features && ( - ( - - - More - - - - )} - /> - )} - - + New Position - - - + + <> + + + + + + + Pools Overview + + + {showV2Features && ( + ( + + + More + + + + )} + /> + )} + + + New Position + + + - - {positionsLoading ? ( - - ) : filteredPositions && closedPositions && filteredPositions.length > 0 ? ( - - ) : ( - - - -
- Your active V3 liquidity positions will appear here. -
-
- {!showConnectAWallet && closedPositions.length > 0 && ( - setUserHideClosedPositions(!userHideClosedPositions)} - > - Show closed positions - - )} - {showConnectAWallet && ( - - Connect a wallet - - )} -
- )} -
- - - + + {positionsLoading ? ( + + ) : filteredPositions && closedPositions && filteredPositions.length > 0 ? ( + + ) : ( + + + +
+ Your active V3 liquidity positions will appear here. +
+
+ {!showConnectAWallet && closedPositions.length > 0 && ( + setUserHideClosedPositions(!userHideClosedPositions)} + > + Show closed positions + + )} + {showConnectAWallet && ( + + Connect a wallet + + )} +
+ )} +
+ + + + - - - - + + + + ) } diff --git a/src/pages/Pool/v2.tsx b/src/pages/Pool/v2.tsx index 54bcff2cd8..ab1a8ec292 100644 --- a/src/pages/Pool/v2.tsx +++ b/src/pages/Pool/v2.tsx @@ -1,6 +1,8 @@ import { Trans } from '@lingui/macro' import { Pair } from '@uniswap/v2-sdk' import { useWeb3React } from '@web3-react/core' +import { PageName } from 'components/AmplitudeAnalytics/constants' +import { Trace } from 'components/AmplitudeAnalytics/Trace' import { UNSUPPORTED_V2POOL_CHAIN_IDS } from 'constants/chains' import JSBI from 'jsbi' import { useContext, useMemo } from 'react' @@ -135,147 +137,149 @@ export default function Pool() { }) return ( - <> - - - - - - - - - - Liquidity provider rewards - - - - - - Liquidity providers earn a 0.3% fee on all trades proportional to their share of the pool. Fees are - added to the pool, accrue in real time and can be claimed by withdrawing your liquidity. - - - - - - Read more about providing liquidity - - - - - - - + + <> + + + + + + + + + + Liquidity provider rewards + + + + + + Liquidity providers earn a 0.3% fee on all trades proportional to their share of the pool. Fees + are added to the pool, accrue in real time and can be claimed by withdrawing your liquidity. + + + + + + Read more about providing liquidity + + + + + + + - {unsupportedV2Network ? ( - - - - - V2 Pool is not available on Layer 2. Switch to Layer 1 Ethereum. - - + {unsupportedV2Network ? ( + + + + + V2 Pool is not available on Layer 2. Switch to Layer 1 Ethereum. + + + - - ) : ( - - - - - - Your V2 liquidity - - - - - Create a pair - - - - Import Pool - - - - - Add V2 Liquidity - - - - + ) : ( + + + + + + Your V2 liquidity + + + + + Create a pair + + + + Import Pool + + + + + Add V2 Liquidity + + + + - {!account ? ( - - - Connect to a wallet to view your liquidity. - - - ) : v2IsLoading ? ( - - - - Loading - - - - ) : allV2PairsWithLiquidity?.length > 0 || stakingPairs?.length > 0 ? ( - <> - - - - - Account analytics and accrued fees - - - - - - {v2PairsWithoutStakedAmount.map((v2Pair) => ( - - ))} - {stakingPairs.map( - (stakingPair, i) => - stakingPair[1] && ( // skip pairs that arent loaded - - ) - )} - - - - Migrate Liquidity to V3 - - - - ) : ( - - - No liquidity found. - - - )} + {!account ? ( + + + Connect to a wallet to view your liquidity. + + + ) : v2IsLoading ? ( + + + + Loading + + + + ) : allV2PairsWithLiquidity?.length > 0 || stakingPairs?.length > 0 ? ( + <> + + + + + Account analytics and accrued fees + + + + + + {v2PairsWithoutStakedAmount.map((v2Pair) => ( + + ))} + {stakingPairs.map( + (stakingPair, i) => + stakingPair[1] && ( // skip pairs that arent loaded + + ) + )} + + + + Migrate Liquidity to V3 + + + + ) : ( + + + No liquidity found. + + + )} + - - )} - - - + )} + + + + ) } diff --git a/src/pages/PoolFinder/index.tsx b/src/pages/PoolFinder/index.tsx index 120bd812fc..04f4a6a734 100644 --- a/src/pages/PoolFinder/index.tsx +++ b/src/pages/PoolFinder/index.tsx @@ -1,6 +1,8 @@ import { Trans } from '@lingui/macro' import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core' import { useWeb3React } from '@web3-react/core' +import { PageName } from 'components/AmplitudeAnalytics/constants' +import { Trace } from 'components/AmplitudeAnalytics/Trace' import JSBI from 'jsbi' import { useCallback, useEffect, useState } from 'react' import { Plus } from 'react-feather' @@ -95,139 +97,141 @@ export default function PoolFinder() { ) return ( - <> - - - - - - - - Tip: Use this tool to find v2 pools that don't automatically appear in the interface. - - - - - { - setShowSearch(true) - setActiveField(Fields.TOKEN0) - }} - > - {currency0 ? ( - - - - {currency0.symbol} - - - ) : ( - - Select a token - - )} - - - - - - - { - setShowSearch(true) - setActiveField(Fields.TOKEN1) - }} - > - {currency1 ? ( - - - - {currency1.symbol} - - - ) : ( - - Select a token - - )} - - - {hasPosition && ( - + <> + + + + + + + + Tip: Use this tool to find v2 pools that don't automatically appear in the interface. + + + + + { + setShowSearch(true) + setActiveField(Fields.TOKEN0) + }} > - - Pool Found! - - - - Manage this pool. - - - - )} - - {currency0 && currency1 ? ( - pairState === PairState.EXISTS ? ( - hasPosition && pair ? ( - + {currency0 ? ( + + + + {currency0.symbol} + + ) : ( + + Select a token + + )} + + + + + + + { + setShowSearch(true) + setActiveField(Fields.TOKEN1) + }} + > + {currency1 ? ( + + + + {currency1.symbol} + + + ) : ( + + Select a token + + )} + + + {hasPosition && ( + + + Pool Found! + + + + Manage this pool. + + + + )} + + {currency0 && currency1 ? ( + pairState === PairState.EXISTS ? ( + hasPosition && pair ? ( + + ) : ( + + + + You don’t have liquidity in this pool yet. + + + + Add liquidity. + + + + + ) + ) : validPairNoLiquidity ? ( - You don’t have liquidity in this pool yet. + No pool found. - - Add liquidity. - + Create pool. - ) - ) : validPairNoLiquidity ? ( - - - - No pool found. - - - Create pool. - - - - ) : pairState === PairState.INVALID ? ( - - - - Invalid pair. - - - - ) : pairState === PairState.LOADING ? ( - - - - Loading - - - - - ) : null - ) : ( - prerequisiteMessage - )} - + ) : pairState === PairState.INVALID ? ( + + + + Invalid pair. + + + + ) : pairState === PairState.LOADING ? ( + + + + Loading + + + + + ) : null + ) : ( + prerequisiteMessage + )} + - - - - + + + + + ) } diff --git a/src/pages/Swap/index.tsx b/src/pages/Swap/index.tsx index bf4f394d63..c95ea1e528 100644 --- a/src/pages/Swap/index.tsx +++ b/src/pages/Swap/index.tsx @@ -398,7 +398,7 @@ export default function Swap({ history }: RouteComponentProps) { const priceImpactTooHigh = priceImpactSeverity > 3 && !isExpertMode return ( - + <> 0 && !dismissTokenWarning} diff --git a/src/pages/Vote/Landing.tsx b/src/pages/Vote/Landing.tsx index 115802ec0f..6c3b2f45dd 100644 --- a/src/pages/Vote/Landing.tsx +++ b/src/pages/Vote/Landing.tsx @@ -1,6 +1,8 @@ import { Trans } from '@lingui/macro' import { CurrencyAmount, Token } from '@uniswap/sdk-core' import { useWeb3React } from '@web3-react/core' +import { PageName } from 'components/AmplitudeAnalytics/constants' +import { Trace } from 'components/AmplitudeAnalytics/Trace' import { ButtonPrimary } from 'components/Button' import { AutoColumn } from 'components/Column' import { CardBGImage, CardNoise, CardSection, DataCard } from 'components/earn/styled' @@ -132,150 +134,155 @@ export default function Landing() { ) return ( <> - - Unlock Votes : Update Delegation} - /> - - - - - + + + Unlock Votes : Update Delegation} + /> + + + + + + + + + Uniswap Governance + + + + + + UNI tokens represent voting shares in Uniswap governance. You can vote on each proposal yourself + or delegate your votes to a third party. + + + + + + Read more about Uniswap governance + + + + + + + + + + + + Proposals + + + {loadingProposals || loadingAvailableVotes ? : null} + {showUnlockVoting ? ( + + Unlock Voting + + ) : availableVotes && JSBI.notEqual(JSBI.BigInt(0), availableVotes?.quotient) ? ( + + + Votes + + + ) : uniBalance && + userDelegatee && + userDelegatee !== ZERO_ADDRESS && + JSBI.notEqual(JSBI.BigInt(0), uniBalance?.quotient) ? ( + + + Votes + + + ) : ( + '' + )} + + Create Proposal + + + + {!showUnlockVoting && ( + +
+ {userDelegatee && userDelegatee !== ZERO_ADDRESS ? ( + + + Delegated to: + + + + {userDelegatee === account ? Self : shortenAddress(userDelegatee)} + + + (edit) + + + + ) : ( + '' + )} + + )} + + {allProposals?.length === 0 && } + + {allProposals?.length > 0 && ( - - Uniswap Governance - + + Show Cancelled + + setHideCancelled((hideCancelled) => !hideCancelled)} + /> - - - - UNI tokens represent voting shares in Uniswap governance. You can vote on each proposal yourself - or delegate your votes to a third party. - - - - - - Read more about Uniswap governance - - - - - - - - - - - Proposals - - - {loadingProposals || loadingAvailableVotes ? : null} - {showUnlockVoting ? ( - - Unlock Voting - - ) : availableVotes && JSBI.notEqual(JSBI.BigInt(0), availableVotes?.quotient) ? ( - - - Votes - - - ) : uniBalance && - userDelegatee && - userDelegatee !== ZERO_ADDRESS && - JSBI.notEqual(JSBI.BigInt(0), uniBalance?.quotient) ? ( - - - Votes - - - ) : ( - '' - )} - - Create Proposal - - - - {!showUnlockVoting && ( - -
- {userDelegatee && userDelegatee !== ZERO_ADDRESS ? ( - - - Delegated to: - - - - {userDelegatee === account ? Self : shortenAddress(userDelegatee)} - - - (edit) - - - - ) : ( - '' - )} - - )} + )} - {allProposals?.length === 0 && } + {allProposals + ?.slice(0) + ?.reverse() + ?.filter((p: ProposalData) => (hideCancelled ? p.status !== ProposalState.CANCELED : true)) + ?.map((p: ProposalData) => { + return ( + + + {p.governorIndex}.{p.id} + + {p.title} + + + ) + })} + - {allProposals?.length > 0 && ( - - - - Show Cancelled - - setHideCancelled((hideCancelled) => !hideCancelled)} /> - - - )} - - {allProposals - ?.slice(0) - ?.reverse() - ?.filter((p: ProposalData) => (hideCancelled ? p.status !== ProposalState.CANCELED : true)) - ?.map((p: ProposalData) => { - return ( - - - {p.governorIndex}.{p.id} - - {p.title} - - - ) - })} - - - - A minimum threshold of 0.25% of the total UNI supply is required to submit proposals - - + + A minimum threshold of 0.25% of the total UNI supply is required to submit proposals + + + ) diff --git a/src/pages/Vote/VotePage.tsx b/src/pages/Vote/VotePage.tsx index 1071cd862b..155703ef7a 100644 --- a/src/pages/Vote/VotePage.tsx +++ b/src/pages/Vote/VotePage.tsx @@ -2,6 +2,8 @@ import { BigNumber } from '@ethersproject/bignumber' import { Trans } from '@lingui/macro' import { CurrencyAmount, Fraction, Token } from '@uniswap/sdk-core' import { useWeb3React } from '@web3-react/core' +import { PageName } from 'components/AmplitudeAnalytics/constants' +import { Trace } from 'components/AmplitudeAnalytics/Trace' import ExecuteModal from 'components/vote/ExecuteModal' import QueueModal from 'components/vote/QueueModal' import { useActiveLocale } from 'hooks/useActiveLocale' @@ -258,226 +260,232 @@ export default function VotePage({ } return ( - <> - - - Unlock Votes} /> - - - - - - - All Proposals - - - {proposalData && } - - - {proposalData?.title} - - - {startDate && startDate > now ? ( - Voting starts approximately {startDate.toLocaleString(locale, dateFormat)} - ) : null} - + + <> + + + Unlock Votes} + /> + + + + + + + All Proposals + + + {proposalData && } - - - {endDate && - (endDate < now ? ( - Voting ended {endDate.toLocaleString(locale, dateFormat)} - ) : ( - Voting ends approximately {endDate.toLocaleString(locale, dateFormat)} - ))} - - - {proposalData && proposalData.status === ProposalState.ACTIVE && !showVotingButtons && ( - - - - Only UNI votes that were self delegated or delegated to another address before block{' '} - {proposalData.startBlock} are eligible for voting. - {' '} - {showLinkForUnlock && ( - - - Unlock voting to prepare for the next - proposal. - - - )} - - - )} - - {showVotingButtons && ( - - { - setVoteOption(VoteOption.For) - toggleVoteModal() - }} - > - Vote For - - { - setVoteOption(VoteOption.Against) - toggleVoteModal() - }} - > - Vote Against - - - )} - {showQueueButton && ( - - { - toggleQueueModal() - }} - > - Queue - - - )} - {showExecuteButton && ( - <> - {eta && ( - + + {proposalData?.title} + + + {startDate && startDate > now ? ( + Voting starts approximately {startDate.toLocaleString(locale, dateFormat)} + ) : null} + + + + + {endDate && + (endDate < now ? ( + Voting ended {endDate.toLocaleString(locale, dateFormat)} + ) : ( + Voting ends approximately {endDate.toLocaleString(locale, dateFormat)} + ))} + + + {proposalData && proposalData.status === ProposalState.ACTIVE && !showVotingButtons && ( + - This proposal may be executed after {eta.toLocaleString(locale, dateFormat)}. + + Only UNI votes that were self delegated or delegated to another address before block{' '} + {proposalData.startBlock} are eligible for voting. + {' '} + {showLinkForUnlock && ( + + + Unlock voting to prepare for the next + proposal. + + + )} - + )} + + {showVotingButtons && ( { - toggleExecuteModal() + setVoteOption(VoteOption.For) + toggleVoteModal() }} - // can't execute until the eta has arrived - disabled={!currentTimestamp || !proposalData?.eta || currentTimestamp.lt(proposalData.eta)} > - Execute + Vote For + + { + setVoteOption(VoteOption.Against) + toggleVoteModal() + }} + > + Vote Against - - )} - - - - - - - For + )} + {showQueueButton && ( + + { + toggleQueueModal() + }} + > + Queue + + + )} + {showExecuteButton && ( + <> + {eta && ( + + + This proposal may be executed after {eta.toLocaleString(locale, dateFormat)}. - {proposalData && ( + + )} + + { + toggleExecuteModal() + }} + // can't execute until the eta has arrived + disabled={!currentTimestamp || !proposalData?.eta || currentTimestamp.lt(proposalData.eta)} + > + Execute + + + + )} + + + + + - {proposalData.forCount.toFixed(0, { groupSeparator: ',' })} - {quorumAmount && ( - {` / ${quorumAmount.toExact({ - groupSeparator: ',', - })}`} - )} + For - )} - - - - - - - - - - - - - Against - - {proposalData && ( + {proposalData && ( + + {proposalData.forCount.toFixed(0, { groupSeparator: ',' })} + {quorumAmount && ( + {` / ${quorumAmount.toExact({ + groupSeparator: ',', + })}`} + )} + + )} + + + + + + + + + + + - {proposalData.againstCount.toFixed(0, { groupSeparator: ',' })} + Against - )} - - - - - - - - - - - Details - - {proposalData?.details?.map((d, i) => { - return ( - - {i + 1}: {linkIfAddress(d.target)}.{d.functionSig}( - {d.callData.split(',').map((content, i) => { - return ( - - {linkIfAddress(content)} - {d.callData.split(',').length - 1 === i ? '' : ','} - + {proposalData && ( + + {proposalData.againstCount.toFixed(0, { groupSeparator: ',' })} + + )} + + + + + + + + + + + Details + + {proposalData?.details?.map((d, i) => { + return ( + + {i + 1}: {linkIfAddress(d.target)}.{d.functionSig}( + {d.callData.split(',').map((content, i) => { + return ( + + {linkIfAddress(content)} + {d.callData.split(',').length - 1 === i ? '' : ','} + + ) + })} ) - })} - ) - - ) - })} - - - - Description - - - - - - - - Proposer - - - - - - - - - + + ) + })} + + + + Description + + + + + + + + Proposer + + + + + + + + + + ) }