fix: Add SwitchLocaleLink to a page where it does not exist (#1867)

This commit is contained in:
Yuta Sugimura 2021-06-16 23:24:25 +09:00 committed by GitHub
parent 9e93f809a0
commit 37cf492dd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 917 additions and 891 deletions

@ -55,6 +55,7 @@ import RateToggle from 'components/RateToggle'
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { AddRemoveTabs } from 'components/NavigationTabs' import { AddRemoveTabs } from 'components/NavigationTabs'
import HoverInlineText from 'components/HoverInlineText' import HoverInlineText from 'components/HoverInlineText'
import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
const DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE = new Percent(50, 10_000) const DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE = new Percent(50, 10_000)
@ -385,393 +386,401 @@ export default function AddLiquidity({
!argentWalletContract && approvalB !== ApprovalState.APPROVED && !!parsedAmounts[Field.CURRENCY_B] !argentWalletContract && approvalB !== ApprovalState.APPROVED && !!parsedAmounts[Field.CURRENCY_B]
return ( return (
<ScrollablePage> <>
<TransactionConfirmationModal <ScrollablePage>
isOpen={showConfirm} <TransactionConfirmationModal
onDismiss={handleDismissConfirmation} isOpen={showConfirm}
attemptingTxn={attemptingTxn} onDismiss={handleDismissConfirmation}
hash={txHash} attemptingTxn={attemptingTxn}
content={() => ( hash={txHash}
<ConfirmationModalContent content={() => (
title={'Add Liquidity'} <ConfirmationModalContent
onDismiss={handleDismissConfirmation} title={'Add Liquidity'}
topContent={() => ( onDismiss={handleDismissConfirmation}
<Review topContent={() => (
parsedAmounts={parsedAmounts} <Review
position={position} parsedAmounts={parsedAmounts}
existingPosition={existingPosition} position={position}
priceLower={priceLower} existingPosition={existingPosition}
priceUpper={priceUpper} priceLower={priceLower}
outOfRange={outOfRange} priceUpper={priceUpper}
/> outOfRange={outOfRange}
)}
bottomContent={() => (
<ButtonPrimary style={{ marginTop: '1rem' }} onClick={onAdd}>
<Text fontWeight={500} fontSize={20}>
<Trans>Add</Trans>
</Text>
</ButtonPrimary>
)}
/>
)}
pendingText={pendingText}
/>
<AppBody>
<AddRemoveTabs
creating={false}
adding={true}
positionID={tokenId}
defaultSlippage={DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE}
/>
<Wrapper>
<AutoColumn gap="32px">
{!hasExistingPosition && (
<>
<AutoColumn gap="md">
<RowBetween paddingBottom="20px">
<TYPE.label>
<Trans>Select pair</Trans>
</TYPE.label>
<ButtonText onClick={clearAll}>
<TYPE.blue fontSize="12px">
<Trans>Clear All</Trans>
</TYPE.blue>
</ButtonText>
</RowBetween>
<RowBetween>
<CurrencyDropdown
value={formattedAmounts[Field.CURRENCY_A]}
onUserInput={onFieldAInput}
hideInput={true}
onMax={() => {
onFieldAInput(maxAmounts[Field.CURRENCY_A]?.toExact() ?? '')
}}
onCurrencySelect={handleCurrencyASelect}
showMaxButton={!atMaxAmounts[Field.CURRENCY_A]}
currency={currencies[Field.CURRENCY_A]}
id="add-liquidity-input-tokena"
showCommonBases
/>
<div style={{ width: '12px' }} />
<CurrencyDropdown
value={formattedAmounts[Field.CURRENCY_B]}
hideInput={true}
onUserInput={onFieldBInput}
onCurrencySelect={handleCurrencyBSelect}
onMax={() => {
onFieldBInput(maxAmounts[Field.CURRENCY_B]?.toExact() ?? '')
}}
showMaxButton={!atMaxAmounts[Field.CURRENCY_B]}
currency={currencies[Field.CURRENCY_B]}
id="add-liquidity-input-tokenb"
showCommonBases
/>
</RowBetween>
</AutoColumn>{' '}
</>
)}
{hasExistingPosition && existingPosition ? (
<PositionPreview
position={existingPosition}
title={<Trans>Selected Range</Trans>}
inRange={!outOfRange}
/>
) : (
<>
<FeeSelector
disabled={!currencyB || !currencyA}
feeAmount={feeAmount}
handleFeePoolSelect={handleFeePoolSelect}
/> />
)}
{noLiquidity && ( bottomContent={() => (
<DynamicSection disabled={!currencyA || !currencyB}> <ButtonPrimary style={{ marginTop: '1rem' }} onClick={onAdd}>
<AutoColumn gap="md"> <Text fontWeight={500} fontSize={20}>
<RowBetween> <Trans>Add</Trans>
<TYPE.label> </Text>
<Trans>Set Starting Price</Trans> </ButtonPrimary>
</TYPE.label> )}
{baseCurrency && quoteCurrency ? ( />
<RateToggle )}
currencyA={baseCurrency} pendingText={pendingText}
currencyB={quoteCurrency} />
handleRateToggle={() => { <AppBody>
onLeftRangeInput('') <AddRemoveTabs
onRightRangeInput('') creating={false}
history.push( adding={true}
`/add/${currencyIdB as string}/${currencyIdA as string}${ positionID={tokenId}
feeAmount ? '/' + feeAmount : '' defaultSlippage={DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE}
}` />
) <Wrapper>
}} <AutoColumn gap="32px">
/> {!hasExistingPosition && (
) : null} <>
</RowBetween> <AutoColumn gap="md">
<RowBetween paddingBottom="20px">
<OutlineCard padding="12px"> <TYPE.label>
<StyledInput <Trans>Select pair</Trans>
className="start-price-input" </TYPE.label>
value={startPriceTypedValue} <ButtonText onClick={clearAll}>
onUserInput={onStartPriceInput} <TYPE.blue fontSize="12px">
/> <Trans>Clear All</Trans>
</OutlineCard> </TYPE.blue>
<RowBetween style={{ backgroundColor: theme.bg1, padding: '12px', borderRadius: '12px' }}> </ButtonText>
<TYPE.main> </RowBetween>
<Trans>Current {baseCurrency?.symbol} Price:</Trans> <RowBetween>
</TYPE.main> <CurrencyDropdown
<TYPE.main> value={formattedAmounts[Field.CURRENCY_A]}
{price ? ( onUserInput={onFieldAInput}
<TYPE.main> hideInput={true}
<RowFixed> onMax={() => {
<HoverInlineText onFieldAInput(maxAmounts[Field.CURRENCY_A]?.toExact() ?? '')
maxCharacters={20}
text={invertPrice ? price?.invert()?.toSignificant(5) : price?.toSignificant(5)}
/>{' '}
<span style={{ marginLeft: '4px' }}>{quoteCurrency?.symbol}</span>
</RowFixed>
</TYPE.main>
) : (
'-'
)}
</TYPE.main>
</RowBetween>
<BlueCard
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: ' 1.5rem 1.25rem',
}}
>
<AlertCircle color={theme.text1} size={32} style={{ marginBottom: '12px', opacity: 0.8 }} />
<TYPE.body
fontSize={14}
style={{ marginBottom: 8, fontWeight: 500, opacity: 0.8 }}
textAlign="center"
>
You are the first liquidity provider for this Uniswap V3 pool.
</TYPE.body>
<TYPE.body fontWeight={500} textAlign="center" fontSize={14} style={{ opacity: 0.8 }}>
The transaction cost will be much higher as it includes the gas to create the pool.
</TYPE.body>
</BlueCard>
</AutoColumn>
</DynamicSection>
)}
<DynamicSection gap="md" disabled={!feeAmount || invalidPool || (noLiquidity && !startPriceTypedValue)}>
<RowBetween>
<TYPE.label>
<Trans>Set Price Range</Trans>
</TYPE.label>
{baseCurrency && quoteCurrency ? (
<RateToggle
currencyA={baseCurrency}
currencyB={quoteCurrency}
handleRateToggle={() => {
onLeftRangeInput('')
onRightRangeInput('')
history.push(
`/add/${currencyIdB as string}/${currencyIdA as string}${feeAmount ? '/' + feeAmount : ''}`
)
}} }}
onCurrencySelect={handleCurrencyASelect}
showMaxButton={!atMaxAmounts[Field.CURRENCY_A]}
currency={currencies[Field.CURRENCY_A]}
id="add-liquidity-input-tokena"
showCommonBases
/> />
) : null} <div style={{ width: '12px' }} />
</RowBetween>
<TYPE.main fontSize={14} fontWeight={400} style={{ marginBottom: '.5rem', lineHeight: '125%' }}>
<Trans>
Your liquidity will only earn fees when the market price of the pair is within your range.{' '}
<ExternalLink
href={'https://docs.uniswap.org/concepts/introduction/liquidity-user-guide#4-set-price-range'}
style={{ fontSize: '14px' }}
>
Need help picking a range?
</ExternalLink>
</Trans>
</TYPE.main>
<RangeSelector <CurrencyDropdown
priceLower={priceLower} value={formattedAmounts[Field.CURRENCY_B]}
priceUpper={priceUpper} hideInput={true}
getDecrementLower={getDecrementLower} onUserInput={onFieldBInput}
getIncrementLower={getIncrementLower} onCurrencySelect={handleCurrencyBSelect}
getDecrementUpper={getDecrementUpper} onMax={() => {
getIncrementUpper={getIncrementUpper} onFieldBInput(maxAmounts[Field.CURRENCY_B]?.toExact() ?? '')
onLeftRangeInput={onLeftRangeInput} }}
onRightRangeInput={onRightRangeInput} showMaxButton={!atMaxAmounts[Field.CURRENCY_B]}
currencyA={baseCurrency} currency={currencies[Field.CURRENCY_B]}
currencyB={quoteCurrency} id="add-liquidity-input-tokenb"
showCommonBases
/>
</RowBetween>
</AutoColumn>{' '}
</>
)}
{hasExistingPosition && existingPosition ? (
<PositionPreview
position={existingPosition}
title={<Trans>Selected Range</Trans>}
inRange={!outOfRange}
/>
) : (
<>
<FeeSelector
disabled={!currencyB || !currencyA}
feeAmount={feeAmount} feeAmount={feeAmount}
handleFeePoolSelect={handleFeePoolSelect}
/> />
{price && baseCurrency && quoteCurrency && !noLiquidity && ( {noLiquidity && (
<LightCard style={{ padding: '12px' }}> <DynamicSection disabled={!currencyA || !currencyB}>
<AutoColumn gap="4px"> <AutoColumn gap="md">
<TYPE.main fontWeight={500} textAlign="center" fontSize={12}> <RowBetween>
<Trans>Current Price</Trans> <TYPE.label>
</TYPE.main> <Trans>Set Starting Price</Trans>
<TYPE.body fontWeight={500} textAlign="center" fontSize={20}> </TYPE.label>
<HoverInlineText {baseCurrency && quoteCurrency ? (
maxCharacters={20} <RateToggle
text={invertPrice ? price.invert().toSignificant(6) : price.toSignificant(6)} currencyA={baseCurrency}
/>{' '} currencyB={quoteCurrency}
</TYPE.body> handleRateToggle={() => {
<TYPE.main fontWeight={500} textAlign="center" fontSize={12}> onLeftRangeInput('')
<Trans> onRightRangeInput('')
{quoteCurrency?.symbol} per {baseCurrency.symbol} history.push(
</Trans> `/add/${currencyIdB as string}/${currencyIdA as string}${
</TYPE.main> feeAmount ? '/' + feeAmount : ''
}`
)
}}
/>
) : null}
</RowBetween>
<OutlineCard padding="12px">
<StyledInput
className="start-price-input"
value={startPriceTypedValue}
onUserInput={onStartPriceInput}
/>
</OutlineCard>
<RowBetween style={{ backgroundColor: theme.bg1, padding: '12px', borderRadius: '12px' }}>
<TYPE.main>
<Trans>Current {baseCurrency?.symbol} Price:</Trans>
</TYPE.main>
<TYPE.main>
{price ? (
<TYPE.main>
<RowFixed>
<HoverInlineText
maxCharacters={20}
text={invertPrice ? price?.invert()?.toSignificant(5) : price?.toSignificant(5)}
/>{' '}
<span style={{ marginLeft: '4px' }}>{quoteCurrency?.symbol}</span>
</RowFixed>
</TYPE.main>
) : (
'-'
)}
</TYPE.main>
</RowBetween>
<BlueCard
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
padding: ' 1.5rem 1.25rem',
}}
>
<AlertCircle color={theme.text1} size={32} style={{ marginBottom: '12px', opacity: 0.8 }} />
<TYPE.body
fontSize={14}
style={{ marginBottom: 8, fontWeight: 500, opacity: 0.8 }}
textAlign="center"
>
You are the first liquidity provider for this Uniswap V3 pool.
</TYPE.body>
<TYPE.body fontWeight={500} textAlign="center" fontSize={14} style={{ opacity: 0.8 }}>
The transaction cost will be much higher as it includes the gas to create the pool.
</TYPE.body>
</BlueCard>
</AutoColumn> </AutoColumn>
</LightCard> </DynamicSection>
)} )}
{outOfRange ? ( <DynamicSection
<YellowCard padding="8px 12px" borderRadius="12px"> gap="md"
<RowBetween> disabled={!feeAmount || invalidPool || (noLiquidity && !startPriceTypedValue)}
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
<Trans>
Your position will not earn fees or be used in trades until the market price moves into your
range.
</Trans>
</TYPE.yellow>
</RowBetween>
</YellowCard>
) : null}
{invalidRange ? (
<YellowCard padding="8px 12px" borderRadius="12px">
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
<Trans>Invalid range selected. The min price must be lower than the max price.</Trans>
</TYPE.yellow>
</RowBetween>
</YellowCard>
) : null}
</DynamicSection>
</>
)}
<DynamicSection
disabled={tickLower === undefined || tickUpper === undefined || invalidPool || invalidRange}
>
<AutoColumn gap="md">
<TYPE.label>{hasExistingPosition ? 'Add more liquidity' : t`Deposit Amounts`}</TYPE.label>
<CurrencyInputPanel
value={formattedAmounts[Field.CURRENCY_A]}
onUserInput={onFieldAInput}
onMax={() => {
onFieldAInput(maxAmounts[Field.CURRENCY_A]?.toExact() ?? '')
}}
showMaxButton={!atMaxAmounts[Field.CURRENCY_A]}
currency={currencies[Field.CURRENCY_A]}
id="add-liquidity-input-tokena"
fiatValue={usdcValues[Field.CURRENCY_A]}
showCommonBases
locked={depositADisabled}
/>
<CurrencyInputPanel
value={formattedAmounts[Field.CURRENCY_B]}
onUserInput={onFieldBInput}
onMax={() => {
onFieldBInput(maxAmounts[Field.CURRENCY_B]?.toExact() ?? '')
}}
showMaxButton={!atMaxAmounts[Field.CURRENCY_B]}
fiatValue={usdcValues[Field.CURRENCY_B]}
currency={currencies[Field.CURRENCY_B]}
id="add-liquidity-input-tokenb"
showCommonBases
locked={depositBDisabled}
/>
</AutoColumn>
</DynamicSection>
<div>
{addIsUnsupported ? (
<ButtonPrimary disabled={true} borderRadius="12px" padding={'12px'}>
<TYPE.main mb="4px">
<Trans>Unsupported Asset</Trans>
</TYPE.main>
</ButtonPrimary>
) : !account ? (
<ButtonLight onClick={toggleWalletModal} borderRadius="12px" padding={'12px'}>
<Trans>Connect wallet</Trans>
</ButtonLight>
) : (
<AutoColumn gap={'md'}>
{(approvalA === ApprovalState.NOT_APPROVED ||
approvalA === ApprovalState.PENDING ||
approvalB === ApprovalState.NOT_APPROVED ||
approvalB === ApprovalState.PENDING) &&
isValid && (
<RowBetween>
{showApprovalA && (
<ButtonPrimary
borderRadius="12px"
padding={'12px'}
onClick={approveACallback}
disabled={approvalA === ApprovalState.PENDING}
width={showApprovalB ? '48%' : '100%'}
>
{approvalA === ApprovalState.PENDING ? (
<Dots>
<Trans>Approving {currencies[Field.CURRENCY_A]?.symbol}</Trans>
</Dots>
) : (
<Trans>Approve {currencies[Field.CURRENCY_A]?.symbol}</Trans>
)}
</ButtonPrimary>
)}
{showApprovalB && (
<ButtonPrimary
borderRadius="12px"
padding={'12px'}
onClick={approveBCallback}
disabled={approvalB === ApprovalState.PENDING}
width={showApprovalA ? '48%' : '100%'}
>
{approvalB === ApprovalState.PENDING ? (
<Dots>
<Trans>Approving {currencies[Field.CURRENCY_B]?.symbol}</Trans>
</Dots>
) : (
<Trans>Approve {currencies[Field.CURRENCY_B]?.symbol}</Trans>
)}
</ButtonPrimary>
)}
</RowBetween>
)}
<ButtonError
onClick={() => {
expertMode ? onAdd() : setShowConfirm(true)
}}
disabled={
!isValid ||
(!argentWalletContract && approvalA !== ApprovalState.APPROVED && !depositADisabled) ||
(!argentWalletContract && approvalB !== ApprovalState.APPROVED && !depositBDisabled)
}
error={!isValid && !!parsedAmounts[Field.CURRENCY_A] && !!parsedAmounts[Field.CURRENCY_B]}
> >
<Text fontWeight={500}>{errorMessage ? errorMessage : <Trans>Add</Trans>}</Text> <RowBetween>
</ButtonError> <TYPE.label>
</AutoColumn> <Trans>Set Price Range</Trans>
</TYPE.label>
{baseCurrency && quoteCurrency ? (
<RateToggle
currencyA={baseCurrency}
currencyB={quoteCurrency}
handleRateToggle={() => {
onLeftRangeInput('')
onRightRangeInput('')
history.push(
`/add/${currencyIdB as string}/${currencyIdA as string}${
feeAmount ? '/' + feeAmount : ''
}`
)
}}
/>
) : null}
</RowBetween>
<TYPE.main fontSize={14} fontWeight={400} style={{ marginBottom: '.5rem', lineHeight: '125%' }}>
<Trans>
Your liquidity will only earn fees when the market price of the pair is within your range.{' '}
<ExternalLink
href={'https://docs.uniswap.org/concepts/introduction/liquidity-user-guide#4-set-price-range'}
style={{ fontSize: '14px' }}
>
Need help picking a range?
</ExternalLink>
</Trans>
</TYPE.main>
<RangeSelector
priceLower={priceLower}
priceUpper={priceUpper}
getDecrementLower={getDecrementLower}
getIncrementLower={getIncrementLower}
getDecrementUpper={getDecrementUpper}
getIncrementUpper={getIncrementUpper}
onLeftRangeInput={onLeftRangeInput}
onRightRangeInput={onRightRangeInput}
currencyA={baseCurrency}
currencyB={quoteCurrency}
feeAmount={feeAmount}
/>
{price && baseCurrency && quoteCurrency && !noLiquidity && (
<LightCard style={{ padding: '12px' }}>
<AutoColumn gap="4px">
<TYPE.main fontWeight={500} textAlign="center" fontSize={12}>
<Trans>Current Price</Trans>
</TYPE.main>
<TYPE.body fontWeight={500} textAlign="center" fontSize={20}>
<HoverInlineText
maxCharacters={20}
text={invertPrice ? price.invert().toSignificant(6) : price.toSignificant(6)}
/>{' '}
</TYPE.body>
<TYPE.main fontWeight={500} textAlign="center" fontSize={12}>
<Trans>
{quoteCurrency?.symbol} per {baseCurrency.symbol}
</Trans>
</TYPE.main>
</AutoColumn>
</LightCard>
)}
{outOfRange ? (
<YellowCard padding="8px 12px" borderRadius="12px">
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
<Trans>
Your position will not earn fees or be used in trades until the market price moves into
your range.
</Trans>
</TYPE.yellow>
</RowBetween>
</YellowCard>
) : null}
{invalidRange ? (
<YellowCard padding="8px 12px" borderRadius="12px">
<RowBetween>
<AlertTriangle stroke={theme.yellow3} size="16px" />
<TYPE.yellow ml="12px" fontSize="12px">
<Trans>Invalid range selected. The min price must be lower than the max price.</Trans>
</TYPE.yellow>
</RowBetween>
</YellowCard>
) : null}
</DynamicSection>
</>
)} )}
</div>
</AutoColumn> <DynamicSection
</Wrapper> disabled={tickLower === undefined || tickUpper === undefined || invalidPool || invalidRange}
</AppBody> >
{addIsUnsupported && ( <AutoColumn gap="md">
<UnsupportedCurrencyFooter <TYPE.label>{hasExistingPosition ? 'Add more liquidity' : t`Deposit Amounts`}</TYPE.label>
show={addIsUnsupported}
currencies={[currencies.CURRENCY_A, currencies.CURRENCY_B]} <CurrencyInputPanel
/> value={formattedAmounts[Field.CURRENCY_A]}
)} onUserInput={onFieldAInput}
</ScrollablePage> onMax={() => {
onFieldAInput(maxAmounts[Field.CURRENCY_A]?.toExact() ?? '')
}}
showMaxButton={!atMaxAmounts[Field.CURRENCY_A]}
currency={currencies[Field.CURRENCY_A]}
id="add-liquidity-input-tokena"
fiatValue={usdcValues[Field.CURRENCY_A]}
showCommonBases
locked={depositADisabled}
/>
<CurrencyInputPanel
value={formattedAmounts[Field.CURRENCY_B]}
onUserInput={onFieldBInput}
onMax={() => {
onFieldBInput(maxAmounts[Field.CURRENCY_B]?.toExact() ?? '')
}}
showMaxButton={!atMaxAmounts[Field.CURRENCY_B]}
fiatValue={usdcValues[Field.CURRENCY_B]}
currency={currencies[Field.CURRENCY_B]}
id="add-liquidity-input-tokenb"
showCommonBases
locked={depositBDisabled}
/>
</AutoColumn>
</DynamicSection>
<div>
{addIsUnsupported ? (
<ButtonPrimary disabled={true} borderRadius="12px" padding={'12px'}>
<TYPE.main mb="4px">
<Trans>Unsupported Asset</Trans>
</TYPE.main>
</ButtonPrimary>
) : !account ? (
<ButtonLight onClick={toggleWalletModal} borderRadius="12px" padding={'12px'}>
<Trans>Connect wallet</Trans>
</ButtonLight>
) : (
<AutoColumn gap={'md'}>
{(approvalA === ApprovalState.NOT_APPROVED ||
approvalA === ApprovalState.PENDING ||
approvalB === ApprovalState.NOT_APPROVED ||
approvalB === ApprovalState.PENDING) &&
isValid && (
<RowBetween>
{showApprovalA && (
<ButtonPrimary
borderRadius="12px"
padding={'12px'}
onClick={approveACallback}
disabled={approvalA === ApprovalState.PENDING}
width={showApprovalB ? '48%' : '100%'}
>
{approvalA === ApprovalState.PENDING ? (
<Dots>
<Trans>Approving {currencies[Field.CURRENCY_A]?.symbol}</Trans>
</Dots>
) : (
<Trans>Approve {currencies[Field.CURRENCY_A]?.symbol}</Trans>
)}
</ButtonPrimary>
)}
{showApprovalB && (
<ButtonPrimary
borderRadius="12px"
padding={'12px'}
onClick={approveBCallback}
disabled={approvalB === ApprovalState.PENDING}
width={showApprovalA ? '48%' : '100%'}
>
{approvalB === ApprovalState.PENDING ? (
<Dots>
<Trans>Approving {currencies[Field.CURRENCY_B]?.symbol}</Trans>
</Dots>
) : (
<Trans>Approve {currencies[Field.CURRENCY_B]?.symbol}</Trans>
)}
</ButtonPrimary>
)}
</RowBetween>
)}
<ButtonError
onClick={() => {
expertMode ? onAdd() : setShowConfirm(true)
}}
disabled={
!isValid ||
(!argentWalletContract && approvalA !== ApprovalState.APPROVED && !depositADisabled) ||
(!argentWalletContract && approvalB !== ApprovalState.APPROVED && !depositBDisabled)
}
error={!isValid && !!parsedAmounts[Field.CURRENCY_A] && !!parsedAmounts[Field.CURRENCY_B]}
>
<Text fontWeight={500}>{errorMessage ? errorMessage : <Trans>Add</Trans>}</Text>
</ButtonError>
</AutoColumn>
)}
</div>
</AutoColumn>
</Wrapper>
</AppBody>
{addIsUnsupported && (
<UnsupportedCurrencyFooter
show={addIsUnsupported}
currencies={[currencies.CURRENCY_A, currencies.CURRENCY_B]}
/>
)}
</ScrollablePage>
<SwitchLocaleLink />
</>
) )
} }

@ -42,6 +42,7 @@ import { ConfirmAddModalBottom } from './ConfirmAddModalBottom'
import { currencyId } from '../../utils/currencyId' import { currencyId } from '../../utils/currencyId'
import { PoolPriceBar } from './PoolPriceBar' import { PoolPriceBar } from './PoolPriceBar'
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter' import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
import { t, Trans } from '@lingui/macro' import { t, Trans } from '@lingui/macro'
const DEFAULT_ADD_V2_SLIPPAGE_TOLERANCE = new Percent(50, 10_000) const DEFAULT_ADD_V2_SLIPPAGE_TOLERANCE = new Percent(50, 10_000)
@ -485,6 +486,8 @@ export default function AddLiquidity({
</AutoColumn> </AutoColumn>
</Wrapper> </Wrapper>
</AppBody> </AppBody>
<SwitchLocaleLink />
{!addIsUnsupported ? ( {!addIsUnsupported ? (
pair && !noLiquidity && pairState !== PairState.INVALID ? ( pair && !noLiquidity && pairState !== PairState.INVALID ? (
<AutoColumn style={{ minWidth: '20rem', width: '100%', maxWidth: '400px', marginTop: '1rem' }}> <AutoColumn style={{ minWidth: '20rem', width: '100%', maxWidth: '400px', marginTop: '1rem' }}>

@ -16,6 +16,7 @@ import { Dots } from '../../components/swap/styleds'
import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks' import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks'
import MigrateV2PositionCard from 'components/PositionCard/V2' import MigrateV2PositionCard from 'components/PositionCard/V2'
import MigrateSushiPositionCard from 'components/PositionCard/Sushi' import MigrateSushiPositionCard from 'components/PositionCard/Sushi'
import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
import { PairState, useV2Pairs } from 'hooks/useV2Pairs' import { PairState, useV2Pairs } from 'hooks/useV2Pairs'
import { getCreate2Address } from '@ethersproject/address' import { getCreate2Address } from '@ethersproject/address'
import { pack, keccak256 } from '@ethersproject/solidity' import { pack, keccak256 } from '@ethersproject/solidity'
@ -110,73 +111,76 @@ export default function MigrateV2() {
const v2IsLoading = fetchingPairBalances || v2Pairs.some(([pairState]) => pairState === PairState.LOADING) const v2IsLoading = fetchingPairBalances || v2Pairs.some(([pairState]) => pairState === PairState.LOADING)
return ( return (
<BodyWrapper style={{ padding: 24 }}> <>
<AutoColumn gap="16px"> <BodyWrapper style={{ padding: 24 }}>
<AutoRow style={{ alignItems: 'center', justifyContent: 'space-between' }} gap="8px"> <AutoColumn gap="16px">
<BackArrow to="/pool/v2" /> <AutoRow style={{ alignItems: 'center', justifyContent: 'space-between' }} gap="8px">
<TYPE.mediumHeader> <BackArrow to="/pool/v2" />
<Trans>Migrate V2 Liquidity</Trans> <TYPE.mediumHeader>
</TYPE.mediumHeader> <Trans>Migrate V2 Liquidity</Trans>
<div> </TYPE.mediumHeader>
<QuestionHelper text={<Trans>Migrate your liquidity tokens from Uniswap V2 to Uniswap V3.</Trans>} /> <div>
</div> <QuestionHelper text={<Trans>Migrate your liquidity tokens from Uniswap V2 to Uniswap V3.</Trans>} />
</AutoRow> </div>
</AutoRow>
<TYPE.body style={{ marginBottom: 8, fontWeight: 400 }}> <TYPE.body style={{ marginBottom: 8, fontWeight: 400 }}>
<Trans>
For each pool shown below, click migrate to remove your liquidity from Uniswap V2 and deposit it into
Uniswap V3.
</Trans>
</TYPE.body>
{!account ? (
<LightCard padding="40px">
<TYPE.body color={theme.text3} textAlign="center">
<Trans>Connect to a wallet to view your V2 liquidity.</Trans>
</TYPE.body>
</LightCard>
) : v2IsLoading ? (
<LightCard padding="40px">
<TYPE.body color={theme.text3} textAlign="center">
<Dots>
<Trans>Loading</Trans>
</Dots>
</TYPE.body>
</LightCard>
) : v2Pairs.filter(([, pair]) => !!pair).length > 0 ? (
<>
{v2Pairs
.filter(([, pair]) => !!pair)
.map(([, pair]) => (
<MigrateV2PositionCard key={(pair as Pair).liquidityToken.address} pair={pair as Pair} />
))}
{tokenPairsWithSushiBalance.map(({ sushiLiquidityToken, tokens }) => {
return (
<MigrateSushiPositionCard
key={(sushiLiquidityToken as Token).address}
tokenA={tokens[0]}
tokenB={tokens[1]}
liquidityToken={sushiLiquidityToken as Token}
/>
)
})}
</>
) : (
<EmptyState message={<Trans>No V2 Liquidity found.</Trans>} />
)}
<AutoColumn justify={'center'} gap="md">
<Text textAlign="center" fontSize={14} style={{ padding: '.5rem 0 .5rem 0' }}>
<Trans> <Trans>
Dont see one of your v2 positions?{' '} For each pool shown below, click migrate to remove your liquidity from Uniswap V2 and deposit it into
<StyledInternalLink id="import-pool-link" to={'/find?origin=/migrate/v2'}> Uniswap V3.
Import it.
</StyledInternalLink>
</Trans> </Trans>
</Text> </TYPE.body>
{!account ? (
<LightCard padding="40px">
<TYPE.body color={theme.text3} textAlign="center">
<Trans>Connect to a wallet to view your V2 liquidity.</Trans>
</TYPE.body>
</LightCard>
) : v2IsLoading ? (
<LightCard padding="40px">
<TYPE.body color={theme.text3} textAlign="center">
<Dots>
<Trans>Loading</Trans>
</Dots>
</TYPE.body>
</LightCard>
) : v2Pairs.filter(([, pair]) => !!pair).length > 0 ? (
<>
{v2Pairs
.filter(([, pair]) => !!pair)
.map(([, pair]) => (
<MigrateV2PositionCard key={(pair as Pair).liquidityToken.address} pair={pair as Pair} />
))}
{tokenPairsWithSushiBalance.map(({ sushiLiquidityToken, tokens }) => {
return (
<MigrateSushiPositionCard
key={(sushiLiquidityToken as Token).address}
tokenA={tokens[0]}
tokenB={tokens[1]}
liquidityToken={sushiLiquidityToken as Token}
/>
)
})}
</>
) : (
<EmptyState message={<Trans>No V2 Liquidity found.</Trans>} />
)}
<AutoColumn justify={'center'} gap="md">
<Text textAlign="center" fontSize={14} style={{ padding: '.5rem 0 .5rem 0' }}>
<Trans>
Dont see one of your v2 positions?{' '}
<StyledInternalLink id="import-pool-link" to={'/find?origin=/migrate/v2'}>
Import it.
</StyledInternalLink>
</Trans>
</Text>
</AutoColumn>
</AutoColumn> </AutoColumn>
</AutoColumn> </BodyWrapper>
</BodyWrapper> <SwitchLocaleLink />
</>
) )
} }

@ -37,6 +37,7 @@ import useTheme from '../../hooks/useTheme'
import RateToggle from '../../components/RateToggle' import RateToggle from '../../components/RateToggle'
import { useSingleCallResult } from 'state/multicall/hooks' import { useSingleCallResult } from 'state/multicall/hooks'
import RangeBadge from '../../components/Badge/RangeBadge' import RangeBadge from '../../components/Badge/RangeBadge'
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
import useUSDCPrice from 'hooks/useUSDCPrice' import useUSDCPrice from 'hooks/useUSDCPrice'
import Loader from 'components/Loader' import Loader from 'components/Loader'
import Toggle from 'components/Toggle' import Toggle from 'components/Toggle'
@ -495,338 +496,341 @@ export function PositionPage({
<div /> <div />
</LoadingRows> </LoadingRows>
) : ( ) : (
<PageWrapper> <>
<TransactionConfirmationModal <PageWrapper>
isOpen={showConfirm} <TransactionConfirmationModal
onDismiss={() => setShowConfirm(false)} isOpen={showConfirm}
attemptingTxn={collecting} onDismiss={() => setShowConfirm(false)}
hash={collectMigrationHash ?? ''} attemptingTxn={collecting}
content={() => ( hash={collectMigrationHash ?? ''}
<ConfirmationModalContent content={() => (
title={<Trans>Claim fees</Trans>} <ConfirmationModalContent
onDismiss={() => setShowConfirm(false)} title={<Trans>Claim fees</Trans>}
topContent={modalHeader} onDismiss={() => setShowConfirm(false)}
/> topContent={modalHeader}
)}
pendingText={<Trans>Collecting fees</Trans>}
/>
<AutoColumn gap="md">
<AutoColumn gap="sm">
<Link style={{ textDecoration: 'none', width: 'fit-content', marginBottom: '0.5rem' }} to="/pool">
<HoverText>
<Trans> Back to Pools Overview</Trans>
</HoverText>
</Link>
<ResponsiveRow>
<RowFixed>
<DoubleCurrencyLogo currency0={currencyBase} currency1={currencyQuote} size={24} margin={true} />
<TYPE.label fontSize={'24px'} mr="10px">
&nbsp;{currencyQuote?.symbol}&nbsp;/&nbsp;{currencyBase?.symbol}
</TYPE.label>
<Badge style={{ marginRight: '8px' }}>
<BadgeText>
<Trans>{new Percent(feeAmount, 1_000_000).toSignificant()}%</Trans>
</BadgeText>
</Badge>
<RangeBadge removed={removed} inRange={inRange} />
</RowFixed>
{ownsNFT && (
<RowFixed>
{currency0 && currency1 && feeAmount && tokenId ? (
<ButtonGray
as={Link}
to={`/increase/${currencyId(currency0)}/${currencyId(currency1)}/${feeAmount}/${tokenId}`}
width="fit-content"
padding="6px 8px"
borderRadius="12px"
style={{ marginRight: '8px' }}
>
<Trans>Increase Liquidity</Trans>
</ButtonGray>
) : null}
{tokenId && !removed ? (
<ResponsiveButtonPrimary
as={Link}
to={`/remove/${tokenId}`}
width="fit-content"
padding="6px 8px"
borderRadius="12px"
>
<Trans>Remove Liquidity</Trans>
</ResponsiveButtonPrimary>
) : null}
</RowFixed>
)}
</ResponsiveRow>
<RowBetween></RowBetween>
</AutoColumn>
<ResponsiveRow align="flex-start">
{'result' in metadata ? (
<DarkCard
width="100%"
height="100%"
style={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
justifyContent: 'space-around',
marginRight: '12px',
}}
>
<div style={{ marginRight: 12 }}>
<NFT image={metadata.result.image} height={400} />
</div>
{typeof chainId === 'number' && owner && !ownsNFT ? (
<ExternalLink href={getExplorerLink(chainId, owner, ExplorerDataType.ADDRESS)}>
<Trans>Owner</Trans>
</ExternalLink>
) : null}
</DarkCard>
) : (
<DarkCard
width="100%"
height="100%"
style={{
marginRight: '12px',
minWidth: '340px',
}}
>
<Loader />
</DarkCard>
)}
<AutoColumn gap="sm" style={{ width: '100%', height: '100%' }}>
<DarkCard>
<AutoColumn gap="md" style={{ width: '100%' }}>
<AutoColumn gap="md">
<Label>
<Trans>Liquidity</Trans>
</Label>
{fiatValueOfLiquidity?.greaterThan(new Fraction(1, 100)) ? (
<TYPE.largeHeader fontSize="36px" fontWeight={500}>
<Trans>${fiatValueOfLiquidity.toFixed(2, { groupSeparator: ',' })}</Trans>
</TYPE.largeHeader>
) : (
<TYPE.largeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
<Trans>$-</Trans>
</TYPE.largeHeader>
)}
</AutoColumn>
<LightCard padding="12px 16px">
<AutoColumn gap="md">
<RowBetween>
<LinkedCurrency chainId={chainId} currency={currencyQuote} />
<RowFixed>
<TYPE.main>
{inverted ? position?.amount0.toSignificant(4) : position?.amount1.toSignificant(4)}
</TYPE.main>
{typeof ratio === 'number' && !removed ? (
<Badge style={{ marginLeft: '10px' }}>
<TYPE.main fontSize={11}>
<Trans>{inverted ? ratio : 100 - ratio}%</Trans>
</TYPE.main>
</Badge>
) : null}
</RowFixed>
</RowBetween>
<RowBetween>
<LinkedCurrency chainId={chainId} currency={currencyBase} />
<RowFixed>
<TYPE.main>
{inverted ? position?.amount1.toSignificant(4) : position?.amount0.toSignificant(4)}
</TYPE.main>
{typeof ratio === 'number' && !removed ? (
<Badge style={{ marginLeft: '10px' }}>
<TYPE.main color={theme.text2} fontSize={11}>
<Trans>{inverted ? 100 - ratio : ratio}%</Trans>
</TYPE.main>
</Badge>
) : null}
</RowFixed>
</RowBetween>
</AutoColumn>
</LightCard>
</AutoColumn>
</DarkCard>
<DarkCard>
<AutoColumn gap="md" style={{ width: '100%' }}>
<AutoColumn gap="md">
<RowBetween style={{ alignItems: 'flex-start' }}>
<AutoColumn gap="md">
<Label>
<Trans>Unclaimed fees</Trans>
</Label>
{fiatValueOfFees?.greaterThan(new Fraction(1, 100)) ? (
<TYPE.largeHeader color={theme.green1} fontSize="36px" fontWeight={500}>
<Trans>${fiatValueOfFees.toFixed(2, { groupSeparator: ',' })}</Trans>
</TYPE.largeHeader>
) : (
<TYPE.largeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
<Trans>$-</Trans>
</TYPE.largeHeader>
)}
</AutoColumn>
{ownsNFT && (feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) || !!collectMigrationHash) ? (
<ButtonConfirmed
disabled={collecting || !!collectMigrationHash}
confirmed={!!collectMigrationHash && !isCollectPending}
width="fit-content"
style={{ borderRadius: '12px' }}
padding="4px 8px"
onClick={() => setShowConfirm(true)}
>
{!!collectMigrationHash && !isCollectPending ? (
<TYPE.main color={theme.text1}>
<Trans> Collected</Trans>
</TYPE.main>
) : isCollectPending || collecting ? (
<TYPE.main color={theme.text1}>
{' '}
<Dots>
<Trans>Collecting</Trans>
</Dots>
</TYPE.main>
) : (
<>
<TYPE.main color={theme.white}>
<Trans>Collect fees</Trans>
</TYPE.main>
</>
)}
</ButtonConfirmed>
) : null}
</RowBetween>
</AutoColumn>
<LightCard padding="12px 16px">
<AutoColumn gap="md">
<RowBetween>
<RowFixed>
<CurrencyLogo
currency={feeValueUpper?.currency}
size={'20px'}
style={{ marginRight: '0.5rem' }}
/>
<TYPE.main>{feeValueUpper?.currency?.symbol}</TYPE.main>
</RowFixed>
<RowFixed>
<TYPE.main>{feeValueUpper ? formatCurrencyAmount(feeValueUpper, 4) : '-'}</TYPE.main>
</RowFixed>
</RowBetween>
<RowBetween>
<RowFixed>
<CurrencyLogo
currency={feeValueLower?.currency}
size={'20px'}
style={{ marginRight: '0.5rem' }}
/>
<TYPE.main>{feeValueLower?.currency?.symbol}</TYPE.main>
</RowFixed>
<RowFixed>
<TYPE.main>{feeValueLower ? formatCurrencyAmount(feeValueLower, 4) : '-'}</TYPE.main>
</RowFixed>
</RowBetween>
</AutoColumn>
</LightCard>
{ownsNFT &&
(feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0)) &&
currency0 &&
currency1 &&
(currency0.isNative || currency1.isNative) &&
!collectMigrationHash ? (
<AutoColumn gap="md">
<RowBetween>
<TYPE.main>
<Trans>Collect as WETH</Trans>
</TYPE.main>
<Toggle
id="receive-as-weth"
isActive={receiveWETH}
toggle={() => setReceiveWETH((receiveWETH) => !receiveWETH)}
/>
</RowBetween>
</AutoColumn>
) : null}
</AutoColumn>
</DarkCard>
</AutoColumn>
</ResponsiveRow>
<DarkCard>
<AutoColumn gap="md">
<RowBetween>
<RowFixed>
<Label display="flex" style={{ marginRight: '12px' }}>
<Trans>Price range</Trans>
</Label>
<HideExtraSmall>
<>
<RangeBadge removed={removed} inRange={inRange} />
<span style={{ width: '8px' }} />
</>
</HideExtraSmall>
</RowFixed>
<RowFixed>
{currencyBase && currencyQuote && (
<RateToggle
currencyA={currencyBase}
currencyB={currencyQuote}
handleRateToggle={() => setManuallyInverted(!manuallyInverted)}
/>
)}
</RowFixed>
</RowBetween>
<RowBetween>
<LightCard padding="12px" width="100%">
<AutoColumn gap="8px" justify="center">
<ExtentsText>
<Trans>Min price</Trans>
</ExtentsText>
<TYPE.mediumHeader textAlign="center">{priceLower?.toSignificant(5)}</TYPE.mediumHeader>
<ExtentsText>
{' '}
<Trans>
{currencyQuote?.symbol} per {currencyBase?.symbol}
</Trans>
</ExtentsText>
{inRange && (
<TYPE.small color={theme.text3}>
<Trans>Your position will be 100% {currencyBase?.symbol} at this price.</Trans>
</TYPE.small>
)}
</AutoColumn>
</LightCard>
<DoubleArrow></DoubleArrow>
<LightCard padding="12px" width="100%">
<AutoColumn gap="8px" justify="center">
<ExtentsText>
<Trans>Max price</Trans>
</ExtentsText>
<TYPE.mediumHeader textAlign="center">{priceUpper?.toSignificant(5)}</TYPE.mediumHeader>
<ExtentsText>
{' '}
<Trans>
{currencyQuote?.symbol} per {currencyBase?.symbol}
</Trans>
</ExtentsText>
{inRange && (
<TYPE.small color={theme.text3}>
<Trans>Your position will be 100% {currencyQuote?.symbol} at this price.</Trans>
</TYPE.small>
)}
</AutoColumn>
</LightCard>
</RowBetween>
<CurrentPriceCard
inverted={inverted}
pool={pool}
currencyQuote={currencyQuote}
currencyBase={currencyBase}
/> />
)}
pendingText={<Trans>Collecting fees</Trans>}
/>
<AutoColumn gap="md">
<AutoColumn gap="sm">
<Link style={{ textDecoration: 'none', width: 'fit-content', marginBottom: '0.5rem' }} to="/pool">
<HoverText>
<Trans> Back to Pools Overview</Trans>
</HoverText>
</Link>
<ResponsiveRow>
<RowFixed>
<DoubleCurrencyLogo currency0={currencyBase} currency1={currencyQuote} size={24} margin={true} />
<TYPE.label fontSize={'24px'} mr="10px">
&nbsp;{currencyQuote?.symbol}&nbsp;/&nbsp;{currencyBase?.symbol}
</TYPE.label>
<Badge style={{ marginRight: '8px' }}>
<BadgeText>
<Trans>{new Percent(feeAmount, 1_000_000).toSignificant()}%</Trans>
</BadgeText>
</Badge>
<RangeBadge removed={removed} inRange={inRange} />
</RowFixed>
{ownsNFT && (
<RowFixed>
{currency0 && currency1 && feeAmount && tokenId ? (
<ButtonGray
as={Link}
to={`/increase/${currencyId(currency0)}/${currencyId(currency1)}/${feeAmount}/${tokenId}`}
width="fit-content"
padding="6px 8px"
borderRadius="12px"
style={{ marginRight: '8px' }}
>
<Trans>Increase Liquidity</Trans>
</ButtonGray>
) : null}
{tokenId && !removed ? (
<ResponsiveButtonPrimary
as={Link}
to={`/remove/${tokenId}`}
width="fit-content"
padding="6px 8px"
borderRadius="12px"
>
<Trans>Remove Liquidity</Trans>
</ResponsiveButtonPrimary>
) : null}
</RowFixed>
)}
</ResponsiveRow>
<RowBetween></RowBetween>
</AutoColumn> </AutoColumn>
</DarkCard> <ResponsiveRow align="flex-start">
</AutoColumn> {'result' in metadata ? (
</PageWrapper> <DarkCard
width="100%"
height="100%"
style={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
justifyContent: 'space-around',
marginRight: '12px',
}}
>
<div style={{ marginRight: 12 }}>
<NFT image={metadata.result.image} height={400} />
</div>
{typeof chainId === 'number' && owner && !ownsNFT ? (
<ExternalLink href={getExplorerLink(chainId, owner, ExplorerDataType.ADDRESS)}>
<Trans>Owner</Trans>
</ExternalLink>
) : null}
</DarkCard>
) : (
<DarkCard
width="100%"
height="100%"
style={{
marginRight: '12px',
minWidth: '340px',
}}
>
<Loader />
</DarkCard>
)}
<AutoColumn gap="sm" style={{ width: '100%', height: '100%' }}>
<DarkCard>
<AutoColumn gap="md" style={{ width: '100%' }}>
<AutoColumn gap="md">
<Label>
<Trans>Liquidity</Trans>
</Label>
{fiatValueOfLiquidity?.greaterThan(new Fraction(1, 100)) ? (
<TYPE.largeHeader fontSize="36px" fontWeight={500}>
<Trans>${fiatValueOfLiquidity.toFixed(2, { groupSeparator: ',' })}</Trans>
</TYPE.largeHeader>
) : (
<TYPE.largeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
<Trans>$-</Trans>
</TYPE.largeHeader>
)}
</AutoColumn>
<LightCard padding="12px 16px">
<AutoColumn gap="md">
<RowBetween>
<LinkedCurrency chainId={chainId} currency={currencyQuote} />
<RowFixed>
<TYPE.main>
{inverted ? position?.amount0.toSignificant(4) : position?.amount1.toSignificant(4)}
</TYPE.main>
{typeof ratio === 'number' && !removed ? (
<Badge style={{ marginLeft: '10px' }}>
<TYPE.main fontSize={11}>
<Trans>{inverted ? ratio : 100 - ratio}%</Trans>
</TYPE.main>
</Badge>
) : null}
</RowFixed>
</RowBetween>
<RowBetween>
<LinkedCurrency chainId={chainId} currency={currencyBase} />
<RowFixed>
<TYPE.main>
{inverted ? position?.amount1.toSignificant(4) : position?.amount0.toSignificant(4)}
</TYPE.main>
{typeof ratio === 'number' && !removed ? (
<Badge style={{ marginLeft: '10px' }}>
<TYPE.main color={theme.text2} fontSize={11}>
<Trans>{inverted ? 100 - ratio : ratio}%</Trans>
</TYPE.main>
</Badge>
) : null}
</RowFixed>
</RowBetween>
</AutoColumn>
</LightCard>
</AutoColumn>
</DarkCard>
<DarkCard>
<AutoColumn gap="md" style={{ width: '100%' }}>
<AutoColumn gap="md">
<RowBetween style={{ alignItems: 'flex-start' }}>
<AutoColumn gap="md">
<Label>
<Trans>Unclaimed fees</Trans>
</Label>
{fiatValueOfFees?.greaterThan(new Fraction(1, 100)) ? (
<TYPE.largeHeader color={theme.green1} fontSize="36px" fontWeight={500}>
<Trans>${fiatValueOfFees.toFixed(2, { groupSeparator: ',' })}</Trans>
</TYPE.largeHeader>
) : (
<TYPE.largeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
<Trans>$-</Trans>
</TYPE.largeHeader>
)}
</AutoColumn>
{ownsNFT && (feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) || !!collectMigrationHash) ? (
<ButtonConfirmed
disabled={collecting || !!collectMigrationHash}
confirmed={!!collectMigrationHash && !isCollectPending}
width="fit-content"
style={{ borderRadius: '12px' }}
padding="4px 8px"
onClick={() => setShowConfirm(true)}
>
{!!collectMigrationHash && !isCollectPending ? (
<TYPE.main color={theme.text1}>
<Trans> Collected</Trans>
</TYPE.main>
) : isCollectPending || collecting ? (
<TYPE.main color={theme.text1}>
{' '}
<Dots>
<Trans>Collecting</Trans>
</Dots>
</TYPE.main>
) : (
<>
<TYPE.main color={theme.white}>
<Trans>Collect fees</Trans>
</TYPE.main>
</>
)}
</ButtonConfirmed>
) : null}
</RowBetween>
</AutoColumn>
<LightCard padding="12px 16px">
<AutoColumn gap="md">
<RowBetween>
<RowFixed>
<CurrencyLogo
currency={feeValueUpper?.currency}
size={'20px'}
style={{ marginRight: '0.5rem' }}
/>
<TYPE.main>{feeValueUpper?.currency?.symbol}</TYPE.main>
</RowFixed>
<RowFixed>
<TYPE.main>{feeValueUpper ? formatCurrencyAmount(feeValueUpper, 4) : '-'}</TYPE.main>
</RowFixed>
</RowBetween>
<RowBetween>
<RowFixed>
<CurrencyLogo
currency={feeValueLower?.currency}
size={'20px'}
style={{ marginRight: '0.5rem' }}
/>
<TYPE.main>{feeValueLower?.currency?.symbol}</TYPE.main>
</RowFixed>
<RowFixed>
<TYPE.main>{feeValueLower ? formatCurrencyAmount(feeValueLower, 4) : '-'}</TYPE.main>
</RowFixed>
</RowBetween>
</AutoColumn>
</LightCard>
{ownsNFT &&
(feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0)) &&
currency0 &&
currency1 &&
(currency0.isNative || currency1.isNative) &&
!collectMigrationHash ? (
<AutoColumn gap="md">
<RowBetween>
<TYPE.main>
<Trans>Collect as WETH</Trans>
</TYPE.main>
<Toggle
id="receive-as-weth"
isActive={receiveWETH}
toggle={() => setReceiveWETH((receiveWETH) => !receiveWETH)}
/>
</RowBetween>
</AutoColumn>
) : null}
</AutoColumn>
</DarkCard>
</AutoColumn>
</ResponsiveRow>
<DarkCard>
<AutoColumn gap="md">
<RowBetween>
<RowFixed>
<Label display="flex" style={{ marginRight: '12px' }}>
<Trans>Price range</Trans>
</Label>
<HideExtraSmall>
<>
<RangeBadge removed={removed} inRange={inRange} />
<span style={{ width: '8px' }} />
</>
</HideExtraSmall>
</RowFixed>
<RowFixed>
{currencyBase && currencyQuote && (
<RateToggle
currencyA={currencyBase}
currencyB={currencyQuote}
handleRateToggle={() => setManuallyInverted(!manuallyInverted)}
/>
)}
</RowFixed>
</RowBetween>
<RowBetween>
<LightCard padding="12px" width="100%">
<AutoColumn gap="8px" justify="center">
<ExtentsText>
<Trans>Min price</Trans>
</ExtentsText>
<TYPE.mediumHeader textAlign="center">{priceLower?.toSignificant(5)}</TYPE.mediumHeader>
<ExtentsText>
{' '}
<Trans>
{currencyQuote?.symbol} per {currencyBase?.symbol}
</Trans>
</ExtentsText>
{inRange && (
<TYPE.small color={theme.text3}>
<Trans>Your position will be 100% {currencyBase?.symbol} at this price.</Trans>
</TYPE.small>
)}
</AutoColumn>
</LightCard>
<DoubleArrow></DoubleArrow>
<LightCard padding="12px" width="100%">
<AutoColumn gap="8px" justify="center">
<ExtentsText>
<Trans>Max price</Trans>
</ExtentsText>
<TYPE.mediumHeader textAlign="center">{priceUpper?.toSignificant(5)}</TYPE.mediumHeader>
<ExtentsText>
{' '}
<Trans>
{currencyQuote?.symbol} per {currencyBase?.symbol}
</Trans>
</ExtentsText>
{inRange && (
<TYPE.small color={theme.text3}>
<Trans>Your position will be 100% {currencyQuote?.symbol} at this price.</Trans>
</TYPE.small>
)}
</AutoColumn>
</LightCard>
</RowBetween>
<CurrentPriceCard
inverted={inverted}
pool={pool}
currencyQuote={currencyQuote}
currencyBase={currencyBase}
/>
</AutoColumn>
</DarkCard>
</AutoColumn>
</PageWrapper>
<SwitchLocaleLink />
</>
) )
} }

@ -19,6 +19,7 @@ import { useV2Pairs } from '../../hooks/useV2Pairs'
import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks' import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks'
import { Dots } from '../../components/swap/styleds' import { Dots } from '../../components/swap/styleds'
import { CardSection, DataCard, CardNoise, CardBGImage } from '../../components/earn/styled' import { CardSection, DataCard, CardNoise, CardBGImage } from '../../components/earn/styled'
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
import { useStakingInfo } from '../../state/stake/hooks' import { useStakingInfo } from '../../state/stake/hooks'
import { BIG_INT_ZERO } from '../../constants/misc' import { BIG_INT_ZERO } from '../../constants/misc'
import { Pair } from '@uniswap/v2-sdk' import { Pair } from '@uniswap/v2-sdk'
@ -256,6 +257,7 @@ export default function Pool() {
</AutoColumn> </AutoColumn>
</AutoColumn> </AutoColumn>
</PageWrapper> </PageWrapper>
<SwitchLocaleLink />
</> </>
) )
} }

@ -11,6 +11,7 @@ import { FindPoolTabs } from '../../components/NavigationTabs'
import { MinimalPositionCard } from '../../components/PositionCard' import { MinimalPositionCard } from '../../components/PositionCard'
import Row from '../../components/Row' import Row from '../../components/Row'
import CurrencySearchModal from '../../components/SearchModal/CurrencySearchModal' import CurrencySearchModal from '../../components/SearchModal/CurrencySearchModal'
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
import { ExtendedEther } from '../../constants/tokens' import { ExtendedEther } from '../../constants/tokens'
import { PairState, useV2Pair } from '../../hooks/useV2Pairs' import { PairState, useV2Pair } from '../../hooks/useV2Pairs'
import { useActiveWeb3React } from '../../hooks/web3' import { useActiveWeb3React } from '../../hooks/web3'
@ -93,136 +94,139 @@ export default function PoolFinder() {
) )
return ( return (
<AppBody> <>
<FindPoolTabs origin={query.get('origin') ?? '/pool/v2'} /> <AppBody>
<AutoColumn style={{ padding: '1rem' }} gap="md"> <FindPoolTabs origin={query.get('origin') ?? '/pool/v2'} />
<BlueCard> <AutoColumn style={{ padding: '1rem' }} gap="md">
<AutoColumn gap="10px"> <BlueCard>
<TYPE.link fontWeight={400} color={'primaryText1'}> <AutoColumn gap="10px">
<Trans> <TYPE.link fontWeight={400} color={'primaryText1'}>
<b>Tip:</b> Use this tool to find v2 pools that don&apos;t automatically appear in the interface. <Trans>
</Trans> <b>Tip:</b> Use this tool to find v2 pools that don&apos;t automatically appear in the interface.
</TYPE.link> </Trans>
</AutoColumn> </TYPE.link>
</BlueCard> </AutoColumn>
<ButtonDropdownLight </BlueCard>
onClick={() => { <ButtonDropdownLight
setShowSearch(true) onClick={() => {
setActiveField(Fields.TOKEN0) setShowSearch(true)
}} setActiveField(Fields.TOKEN0)
> }}
{currency0 ? (
<Row>
<CurrencyLogo currency={currency0} />
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
{currency0.symbol}
</Text>
</Row>
) : (
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
<Trans>Select a token</Trans>
</Text>
)}
</ButtonDropdownLight>
<ColumnCenter>
<Plus size="16" color="#888D9B" />
</ColumnCenter>
<ButtonDropdownLight
onClick={() => {
setShowSearch(true)
setActiveField(Fields.TOKEN1)
}}
>
{currency1 ? (
<Row>
<CurrencyLogo currency={currency1} />
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
{currency1.symbol}
</Text>
</Row>
) : (
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
<Trans>Select a token</Trans>
</Text>
)}
</ButtonDropdownLight>
{hasPosition && (
<ColumnCenter
style={{ justifyItems: 'center', backgroundColor: '', padding: '12px 0px', borderRadius: '12px' }}
> >
<Text textAlign="center" fontWeight={500}> {currency0 ? (
<Trans>Pool Found!</Trans> <Row>
</Text> <CurrencyLogo currency={currency0} />
<StyledInternalLink to={`/pool/v2`}> <Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
<Text textAlign="center"> {currency0.symbol}
<Trans>Manage this pool.</Trans> </Text>
</Text> </Row>
</StyledInternalLink>
</ColumnCenter>
)}
{currency0 && currency1 ? (
pairState === PairState.EXISTS ? (
hasPosition && pair ? (
<MinimalPositionCard pair={pair} border="1px solid #CED0D9" />
) : ( ) : (
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
<Trans>Select a token</Trans>
</Text>
)}
</ButtonDropdownLight>
<ColumnCenter>
<Plus size="16" color="#888D9B" />
</ColumnCenter>
<ButtonDropdownLight
onClick={() => {
setShowSearch(true)
setActiveField(Fields.TOKEN1)
}}
>
{currency1 ? (
<Row>
<CurrencyLogo currency={currency1} />
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
{currency1.symbol}
</Text>
</Row>
) : (
<Text fontWeight={500} fontSize={20} marginLeft={'12px'}>
<Trans>Select a token</Trans>
</Text>
)}
</ButtonDropdownLight>
{hasPosition && (
<ColumnCenter
style={{ justifyItems: 'center', backgroundColor: '', padding: '12px 0px', borderRadius: '12px' }}
>
<Text textAlign="center" fontWeight={500}>
<Trans>Pool Found!</Trans>
</Text>
<StyledInternalLink to={`/pool/v2`}>
<Text textAlign="center">
<Trans>Manage this pool.</Trans>
</Text>
</StyledInternalLink>
</ColumnCenter>
)}
{currency0 && currency1 ? (
pairState === PairState.EXISTS ? (
hasPosition && pair ? (
<MinimalPositionCard pair={pair} border="1px solid #CED0D9" />
) : (
<LightCard padding="45px 10px">
<AutoColumn gap="sm" justify="center">
<Text textAlign="center">
<Trans>You dont have liquidity in this pool yet.</Trans>
</Text>
<StyledInternalLink to={`/add/${currencyId(currency0)}/${currencyId(currency1)}`}>
<Text textAlign="center">
<Trans>Add liquidity.</Trans>
</Text>
</StyledInternalLink>
</AutoColumn>
</LightCard>
)
) : validPairNoLiquidity ? (
<LightCard padding="45px 10px"> <LightCard padding="45px 10px">
<AutoColumn gap="sm" justify="center"> <AutoColumn gap="sm" justify="center">
<Text textAlign="center"> <Text textAlign="center">
<Trans>You dont have liquidity in this pool yet.</Trans> <Trans>No pool found.</Trans>
</Text> </Text>
<StyledInternalLink to={`/add/${currencyId(currency0)}/${currencyId(currency1)}`}> <StyledInternalLink to={`/add/${currencyId(currency0)}/${currencyId(currency1)}`}>
<Text textAlign="center"> <Trans>Create pool.</Trans>
<Trans>Add liquidity.</Trans>
</Text>
</StyledInternalLink> </StyledInternalLink>
</AutoColumn> </AutoColumn>
</LightCard> </LightCard>
) ) : pairState === PairState.INVALID ? (
) : validPairNoLiquidity ? ( <LightCard padding="45px 10px">
<LightCard padding="45px 10px"> <AutoColumn gap="sm" justify="center">
<AutoColumn gap="sm" justify="center"> <Text textAlign="center" fontWeight={500}>
<Text textAlign="center"> <Trans>Invalid pair.</Trans>
<Trans>No pool found.</Trans> </Text>
</Text> </AutoColumn>
<StyledInternalLink to={`/add/${currencyId(currency0)}/${currencyId(currency1)}`}> </LightCard>
<Trans>Create pool.</Trans> ) : pairState === PairState.LOADING ? (
</StyledInternalLink> <LightCard padding="45px 10px">
</AutoColumn> <AutoColumn gap="sm" justify="center">
</LightCard> <Text textAlign="center">
) : pairState === PairState.INVALID ? ( <Trans>Loading</Trans>
<LightCard padding="45px 10px"> <Dots />
<AutoColumn gap="sm" justify="center"> </Text>
<Text textAlign="center" fontWeight={500}> </AutoColumn>
<Trans>Invalid pair.</Trans> </LightCard>
</Text> ) : null
</AutoColumn> ) : (
</LightCard> prerequisiteMessage
) : pairState === PairState.LOADING ? ( )}
<LightCard padding="45px 10px"> </AutoColumn>
<AutoColumn gap="sm" justify="center">
<Text textAlign="center">
<Trans>Loading</Trans>
<Dots />
</Text>
</AutoColumn>
</LightCard>
) : null
) : (
prerequisiteMessage
)}
</AutoColumn>
<CurrencySearchModal <CurrencySearchModal
isOpen={showSearch} isOpen={showSearch}
onCurrencySelect={handleCurrencySelect} onCurrencySelect={handleCurrencySelect}
onDismiss={handleSearchDismiss} onDismiss={handleSearchDismiss}
showCommonBases showCommonBases
selectedCurrency={(activeField === Fields.TOKEN0 ? currency1 : currency0) ?? undefined} selectedCurrency={(activeField === Fields.TOKEN0 ? currency1 : currency0) ?? undefined}
/> />
</AppBody> </AppBody>
<SwitchLocaleLink />
</>
) )
} }