fix: add a link to switch the locale conditionally (#1776)

* add a link to switch the locale conditionally

* make it smaller

* add the locale labels

* language labels from the internet

* fix the heart in the claim popup

* undo the conditional change

* remove todo

* updated Chinese locale name to office-365 language ids

* added missing <Trans>

Co-authored-by: Justin Domingue <judo@uniswap.org>
This commit is contained in:
Moody Salem 2021-06-01 09:54:43 -05:00 committed by GitHub
parent 5125cbb1a3
commit a7a1607faa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 372 additions and 281 deletions

@ -1,7 +1,8 @@
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import React, { useCallback, useEffect } from 'react'
import ReactGA from 'react-ga'
import { X } from 'react-feather'
import { Heart, X } from 'react-feather'
import styled, { keyframes } from 'styled-components'
import tokenLogo from '../../assets/images/token-logo.png'
import { ButtonPrimary } from '../../components/Button'
@ -104,18 +105,20 @@ export default function ClaimPopup() {
<span role="img" aria-label="party">
🎉
</span>{' '}
UNI has arrived{' '}
<Trans>UNI has arrived</Trans>{' '}
<span role="img" aria-label="party">
🎉
</span>
</TYPE.white>
<TYPE.subHeader style={{ paddingTop: '0.5rem', textAlign: 'center' }} color="white">
{`Thanks for being part of the Uniswap community <3`}
<Trans>
Thanks for being part of the Uniswap community <Heart size={12} />
</Trans>
</TYPE.subHeader>
</AutoColumn>
<AutoColumn style={{ zIndex: 10 }} justify="center">
<ButtonPrimary padding="8px" borderRadius="8px" width={'fit-content'} onClick={handleToggleSelfClaimModal}>
Claim your UNI tokens
<Trans>Claim your UNI tokens</Trans>
</ButtonPrimary>
</AutoColumn>
</StyledClaimPopup>

@ -0,0 +1,47 @@
import { Trans } from '@lingui/macro'
import React, { useMemo } from 'react'
import { useLocation } from 'react-router'
import styled from 'styled-components/macro'
import { DEFAULT_LOCALE, LOCALE_LABEL, SupportedLocale } from '../../constants/locales'
import { navigatorLocale, useActiveLocale } from '../../hooks/useActiveLocale'
import useParsedQueryString from '../../hooks/useParsedQueryString'
import { StyledInternalLink, TYPE } from '../../theme'
import { stringify } from 'qs'
const Container = styled(TYPE.small)`
opacity: 0.6;
:hover {
opacity: 1;
}
margin-top: 1rem !important;
`
export function SwitchLocaleLink() {
const activeLocale = useActiveLocale()
const browserLocale = useMemo(() => navigatorLocale(), [])
const location = useLocation()
const qs = useParsedQueryString()
if (browserLocale && (browserLocale !== DEFAULT_LOCALE || activeLocale !== DEFAULT_LOCALE)) {
let targetLocale: SupportedLocale
if (activeLocale === browserLocale) {
targetLocale = DEFAULT_LOCALE
} else {
targetLocale = browserLocale
}
const target = {
...location,
search: stringify({ ...qs, lng: targetLocale }),
}
return (
<Container>
<Trans>
Uniswap available in: {<StyledInternalLink to={target}>{LOCALE_LABEL[targetLocale]}</StyledInternalLink>}
</Trans>
</Container>
)
}
return null
}

@ -35,7 +35,36 @@ export type SupportedLocale = typeof SUPPORTED_LOCALES[number]
export const DEFAULT_LOCALE: SupportedLocale = 'en-US'
// todo: fill this back out
export const LOCALE_LABEL: { [locale in SupportedLocale]?: string } = {
export const LOCALE_LABEL: { [locale in SupportedLocale]: string } = {
'af-ZA': 'Afrikaans',
'ar-SA': 'العربية',
'ca-ES': 'Català',
'cs-CZ': 'čeština',
'da-DK': 'dansk',
'de-DE': 'Deutsche',
'el-GR': 'ελληνικά',
'en-US': 'English',
'es-ES': 'Español',
'fi-FI': 'Suomalainen',
'fr-FR': 'français',
'he-IL': 'עִברִית',
'hu-HU': 'Magyar',
'id-ID': 'bahasa Indonesia',
'it-IT': 'Italiano',
'ja-JP': '日本語',
'ko-KR': '한국어',
'nl-NL': 'Nederlands',
'no-NO': 'norsk',
'pl-PL': 'Polskie',
'pt-BR': 'português',
'pt-PT': 'português',
'ro-RO': 'Română',
'ru-RU': 'русский',
'sr-SP': 'Српски',
'sv-SE': 'svenska',
'tr-TR': 'Türkçe',
'uk-UA': 'Український',
'vi-VN': 'Tiếng Việt',
'zh-CN': '中文 ( 中国 )',
'zh-TW': '中文 ( 台灣 )',
}

@ -17,7 +17,7 @@ function parseLocale(maybeSupportedLocale: string): SupportedLocale | undefined
/**
* Returns the supported locale read from the user agent (navigator)
*/
function navigatorLocale(): SupportedLocale | undefined {
export function navigatorLocale(): SupportedLocale | undefined {
if (!navigator.language) return undefined
const [language, region] = navigator.language.split('-')

@ -13,6 +13,7 @@ import { Link } from 'react-router-dom'
import { useWalletModalToggle } from 'state/application/hooks'
import styled, { ThemeContext } from 'styled-components'
import { HideSmall, TYPE } from 'theme'
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
import { LoadingRows } from './styleds'
import Toggle from 'components/Toggle'
import { useUserHideClosedPositions } from 'state/user/hooks'
@ -295,6 +296,7 @@ export default function Pool() {
</AutoColumn>
</AutoColumn>
</PageWrapper>
<SwitchLocaleLink />
</>
)
}

@ -1,3 +1,4 @@
import { Trans } from '@lingui/macro'
import { Currency, CurrencyAmount, Token, TradeType } from '@uniswap/sdk-core'
import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk'
@ -6,7 +7,7 @@ import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter
import { MouseoverTooltip, MouseoverTooltipContent } from 'components/Tooltip'
import JSBI from 'jsbi'
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { ArrowDown, CheckCircle, HelpCircle, Info, ArrowLeft } from 'react-feather'
import { ArrowDown, ArrowLeft, CheckCircle, HelpCircle, Info } from 'react-feather'
import ReactGA from 'react-ga'
import { Link, RouteComponentProps } from 'react-router-dom'
import { Text } from 'rebass'
@ -26,8 +27,8 @@ import ConfirmSwapModal from '../../components/swap/ConfirmSwapModal'
import { ArrowWrapper, BottomGrouping, Dots, SwapCallbackError, Wrapper } from '../../components/swap/styleds'
import SwapHeader from '../../components/swap/SwapHeader'
import TradePrice from '../../components/swap/TradePrice'
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
import TokenWarningModal from '../../components/TokenWarningModal'
import { useActiveWeb3React } from '../../hooks/web3'
import { useAllTokens, useCurrency } from '../../hooks/Tokens'
import { ApprovalState, useApproveCallbackFromTrade } from '../../hooks/useApproveCallback'
import { V3TradeState } from '../../hooks/useBestV3Trade'
@ -39,6 +40,7 @@ import { useSwapCallback } from '../../hooks/useSwapCallback'
import useToggledVersion, { Version } from '../../hooks/useToggledVersion'
import { useUSDCValue } from '../../hooks/useUSDCPrice'
import useWrapCallback, { WrapType } from '../../hooks/useWrapCallback'
import { useActiveWeb3React } from '../../hooks/web3'
import { useWalletModalToggle } from '../../state/application/hooks'
import { Field } from '../../state/swap/actions'
import {
@ -55,7 +57,6 @@ import { isTradeBetter } from '../../utils/isTradeBetter'
import { maxAmountSpend } from '../../utils/maxAmountSpend'
import { warningSeverity } from '../../utils/prices'
import AppBody from '../AppBody'
import { Trans } from '@lingui/macro'
const StyledInfo = styled(Info)`
opacity: 0.4;
@ -658,6 +659,7 @@ export default function Swap({ history }: RouteComponentProps) {
</AutoColumn>
</Wrapper>
</AppBody>
<SwitchLocaleLink />
{!swapIsUnsupported ? null : (
<UnsupportedCurrencyFooter show={swapIsUnsupported} currencies={[currencies.INPUT, currencies.OUTPUT]} />
)}

@ -14,6 +14,7 @@ import { GreyCard } from '../../components/Card'
import { AutoColumn } from '../../components/Column'
import { CardSection, DataCard } from '../../components/earn/styled'
import { RowBetween, RowFixed } from '../../components/Row'
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
import DelegateModal from '../../components/vote/DelegateModal'
import VoteModal from '../../components/vote/VoteModal'
import {
@ -199,161 +200,164 @@ export default function VotePage({
}
return (
<PageWrapper gap="lg" justify="center">
<VoteModal isOpen={showVoteModal} onDismiss={toggleVoteModal} proposalId={proposalData?.id} support={support} />
<DelegateModal isOpen={showDelegateModal} onDismiss={toggleDelegateModal} title={<Trans>Unlock Votes</Trans>} />
<ProposalInfo gap="lg" justify="start">
<RowBetween style={{ width: '100%' }}>
<ArrowWrapper to="/vote">
<Trans>
<ArrowLeft size={20} /> All Proposals
</Trans>
</ArrowWrapper>
{proposalData && (
<ProposalStatus status={proposalData.status}>{ProposalState[proposalData.status]}</ProposalStatus>
)}
</RowBetween>
<AutoColumn gap="10px" style={{ width: '100%' }}>
<TYPE.largeHeader style={{ marginBottom: '.5rem' }}>{proposalData?.title}</TYPE.largeHeader>
<RowBetween>
<TYPE.main>
{endDate && endDate < now ? (
<Trans>Voting ended {endDate && endDate.toLocaleString(DateTime.DATETIME_FULL)}</Trans>
) : proposalData ? (
<Trans>Voting ends approximately {endDate && endDate.toLocaleString(DateTime.DATETIME_FULL)}</Trans>
) : (
''
)}
</TYPE.main>
<>
<PageWrapper gap="lg" justify="center">
<VoteModal isOpen={showVoteModal} onDismiss={toggleVoteModal} proposalId={proposalData?.id} support={support} />
<DelegateModal isOpen={showDelegateModal} onDismiss={toggleDelegateModal} title={<Trans>Unlock Votes</Trans>} />
<ProposalInfo gap="lg" justify="start">
<RowBetween style={{ width: '100%' }}>
<ArrowWrapper to="/vote">
<Trans>
<ArrowLeft size={20} /> All Proposals
</Trans>
</ArrowWrapper>
{proposalData && (
<ProposalStatus status={proposalData.status}>{ProposalState[proposalData.status]}</ProposalStatus>
)}
</RowBetween>
{proposalData && proposalData.status === ProposalState.Active && !showVotingButtons && (
<GreyCard>
<TYPE.black>
<Trans>
Only UNI votes that were self delegated or delegated to another address before block{' '}
{proposalData.startBlock} are eligible for voting.{' '}
</Trans>
{showLinkForUnlock && (
<span>
<Trans>
<StyledInternalLink to="/vote">Unlock voting</StyledInternalLink> to prepare for the next
proposal.
</Trans>
</span>
<AutoColumn gap="10px" style={{ width: '100%' }}>
<TYPE.largeHeader style={{ marginBottom: '.5rem' }}>{proposalData?.title}</TYPE.largeHeader>
<RowBetween>
<TYPE.main>
{endDate && endDate < now ? (
<Trans>Voting ended {endDate && endDate.toLocaleString(DateTime.DATETIME_FULL)}</Trans>
) : proposalData ? (
<Trans>Voting ends approximately {endDate && endDate.toLocaleString(DateTime.DATETIME_FULL)}</Trans>
) : (
''
)}
</TYPE.black>
</GreyCard>
)}
</AutoColumn>
{showVotingButtons ? (
<RowFixed style={{ width: '100%', gap: '12px' }}>
<ButtonPrimary
padding="8px"
borderRadius="8px"
onClick={() => {
setSupport(true)
toggleVoteModal()
}}
>
Vote For
</ButtonPrimary>
<ButtonPrimary
padding="8px"
borderRadius="8px"
onClick={() => {
setSupport(false)
toggleVoteModal()
}}
>
<Trans>Vote Against</Trans>
</ButtonPrimary>
</RowFixed>
) : (
''
)}
<CardWrapper>
<StyledDataCard>
<CardSection>
<AutoColumn gap="md">
<WrapSmall>
</TYPE.main>
</RowBetween>
{proposalData && proposalData.status === ProposalState.Active && !showVotingButtons && (
<GreyCard>
<TYPE.black>
<Trans>
<TYPE.black fontWeight={600}>
<Trans>For</Trans>
</TYPE.black>
<TYPE.black fontWeight={600}>
{' '}
{proposalData?.forCount.toLocaleString(undefined, { maximumFractionDigits: 0 })}
</TYPE.black>
Only UNI votes that were self delegated or delegated to another address before block{' '}
{proposalData.startBlock} are eligible for voting.{' '}
</Trans>
</WrapSmall>
</AutoColumn>
<ProgressWrapper>
<Progress status={'for'} percentageString={forPercentage} />
</ProgressWrapper>
</CardSection>
</StyledDataCard>
<StyledDataCard>
<CardSection>
<AutoColumn gap="md">
<WrapSmall>
<TYPE.black fontWeight={600}>
<Trans>Against</Trans>
</TYPE.black>
<TYPE.black fontWeight={600}>
{proposalData?.againstCount.toLocaleString(undefined, { maximumFractionDigits: 0 })}
</TYPE.black>
</WrapSmall>
</AutoColumn>
<ProgressWrapper>
<Progress status={'against'} percentageString={againstPercentage} />
</ProgressWrapper>
</CardSection>
</StyledDataCard>
</CardWrapper>
<AutoColumn gap="md">
<TYPE.mediumHeader fontWeight={600}>
<Trans>Details</Trans>
</TYPE.mediumHeader>
{proposalData?.details?.map((d, i) => {
return (
<DetailText key={i}>
{i + 1}: {linkIfAddress(d.target)}.{d.functionSig}(
{d.callData.split(',').map((content, i) => {
return (
<span key={i}>
{linkIfAddress(content)}
{d.callData.split(',').length - 1 === i ? '' : ','}
{showLinkForUnlock && (
<span>
<Trans>
<StyledInternalLink to="/vote">Unlock voting</StyledInternalLink> to prepare for the next
proposal.
</Trans>
</span>
)}
</TYPE.black>
</GreyCard>
)}
</AutoColumn>
{showVotingButtons ? (
<RowFixed style={{ width: '100%', gap: '12px' }}>
<ButtonPrimary
padding="8px"
borderRadius="8px"
onClick={() => {
setSupport(true)
toggleVoteModal()
}}
>
<Trans>Vote For</Trans>
</ButtonPrimary>
<ButtonPrimary
padding="8px"
borderRadius="8px"
onClick={() => {
setSupport(false)
toggleVoteModal()
}}
>
<Trans>Vote Against</Trans>
</ButtonPrimary>
</RowFixed>
) : (
''
)}
<CardWrapper>
<StyledDataCard>
<CardSection>
<AutoColumn gap="md">
<WrapSmall>
<Trans>
<TYPE.black fontWeight={600}>
<Trans>For</Trans>
</TYPE.black>
<TYPE.black fontWeight={600}>
{' '}
{proposalData?.forCount.toLocaleString(undefined, { maximumFractionDigits: 0 })}
</TYPE.black>
</Trans>
</WrapSmall>
</AutoColumn>
<ProgressWrapper>
<Progress status={'for'} percentageString={forPercentage} />
</ProgressWrapper>
</CardSection>
</StyledDataCard>
<StyledDataCard>
<CardSection>
<AutoColumn gap="md">
<WrapSmall>
<TYPE.black fontWeight={600}>
<Trans>Against</Trans>
</TYPE.black>
<TYPE.black fontWeight={600}>
{proposalData?.againstCount.toLocaleString(undefined, { maximumFractionDigits: 0 })}
</TYPE.black>
</WrapSmall>
</AutoColumn>
<ProgressWrapper>
<Progress status={'against'} percentageString={againstPercentage} />
</ProgressWrapper>
</CardSection>
</StyledDataCard>
</CardWrapper>
<AutoColumn gap="md">
<TYPE.mediumHeader fontWeight={600}>
<Trans>Details</Trans>
</TYPE.mediumHeader>
{proposalData?.details?.map((d, i) => {
return (
<DetailText key={i}>
{i + 1}: {linkIfAddress(d.target)}.{d.functionSig}(
{d.callData.split(',').map((content, i) => {
return (
<span key={i}>
{linkIfAddress(content)}
{d.callData.split(',').length - 1 === i ? '' : ','}
</span>
)
})}
)
})}
)
</DetailText>
)
})}
</AutoColumn>
<AutoColumn gap="md">
<TYPE.mediumHeader fontWeight={600}>
<Trans>Description</Trans>
</TYPE.mediumHeader>
<MarkDownWrapper>
<ReactMarkdown source={proposalData?.description} />
</MarkDownWrapper>
</AutoColumn>
<AutoColumn gap="md">
<TYPE.mediumHeader fontWeight={600}>
<Trans>Proposer</Trans>
</TYPE.mediumHeader>
<ProposerAddressLink
href={
proposalData?.proposer && chainId
? getExplorerLink(chainId, proposalData?.proposer, ExplorerDataType.ADDRESS)
: ''
}
>
<ReactMarkdown source={proposalData?.proposer} />
</ProposerAddressLink>
</AutoColumn>
</ProposalInfo>
</PageWrapper>
</DetailText>
)
})}
</AutoColumn>
<AutoColumn gap="md">
<TYPE.mediumHeader fontWeight={600}>
<Trans>Description</Trans>
</TYPE.mediumHeader>
<MarkDownWrapper>
<ReactMarkdown source={proposalData?.description} />
</MarkDownWrapper>
</AutoColumn>
<AutoColumn gap="md">
<TYPE.mediumHeader fontWeight={600}>
<Trans>Proposer</Trans>
</TYPE.mediumHeader>
<ProposerAddressLink
href={
proposalData?.proposer && chainId
? getExplorerLink(chainId, proposalData?.proposer, ExplorerDataType.ADDRESS)
: ''
}
>
<ReactMarkdown source={proposalData?.proposer} />
</ProposerAddressLink>
</AutoColumn>
</ProposalInfo>
</PageWrapper>
<SwitchLocaleLink />
</>
)
}

@ -1,6 +1,7 @@
import React from 'react'
import { AutoColumn } from '../../components/Column'
import styled from 'styled-components/macro'
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
import { UNI } from '../../constants/tokens'
import { ExternalLink, TYPE } from '../../theme'
import { RowBetween, RowFixed } from '../../components/Row'
@ -135,130 +136,133 @@ export default function Vote() {
)
return (
<PageWrapper gap="lg" justify="center">
<DelegateModal
isOpen={showDelegateModal}
onDismiss={toggleDelegateModal}
title={showUnlockVoting ? <Trans>Unlock Votes</Trans> : <Trans>Update Delegation</Trans>}
/>
<TopSection gap="md">
<VoteCard>
<CardBGImage />
<CardNoise />
<CardSection>
<AutoColumn gap="md">
<RowBetween>
<TYPE.white fontWeight={600}>
<Trans>Uniswap Governance</Trans>
</TYPE.white>
</RowBetween>
<RowBetween>
<TYPE.white fontSize={14}>
<Trans>
UNI tokens represent voting shares in Uniswap governance. You can vote on each proposal yourself or
delegate your votes to a third party.
</Trans>
</TYPE.white>
</RowBetween>
<ExternalLink
style={{ color: 'white', textDecoration: 'underline' }}
href="https://uniswap.org/blog/uni"
target="_blank"
<>
<PageWrapper gap="lg" justify="center">
<DelegateModal
isOpen={showDelegateModal}
onDismiss={toggleDelegateModal}
title={showUnlockVoting ? <Trans>Unlock Votes</Trans> : <Trans>Update Delegation</Trans>}
/>
<TopSection gap="md">
<VoteCard>
<CardBGImage />
<CardNoise />
<CardSection>
<AutoColumn gap="md">
<RowBetween>
<TYPE.white fontWeight={600}>
<Trans>Uniswap Governance</Trans>
</TYPE.white>
</RowBetween>
<RowBetween>
<TYPE.white fontSize={14}>
<Trans>
UNI tokens represent voting shares in Uniswap governance. You can vote on each proposal yourself
or delegate your votes to a third party.
</Trans>
</TYPE.white>
</RowBetween>
<ExternalLink
style={{ color: 'white', textDecoration: 'underline' }}
href="https://uniswap.org/blog/uni"
target="_blank"
>
<TYPE.white fontSize={14}>
<Trans>Read more about Uniswap governance</Trans>
</TYPE.white>
</ExternalLink>
</AutoColumn>
</CardSection>
<CardBGImage />
<CardNoise />
</VoteCard>
</TopSection>
<TopSection gap="2px">
<WrapSmall>
<TYPE.mediumHeader style={{ margin: '0.5rem 0.5rem 0.5rem 0', flexShrink: 0 }}>
<Trans>Proposals</Trans>
</TYPE.mediumHeader>
{(!allProposals || allProposals.length === 0) && !availableVotes && <Loader />}
{showUnlockVoting ? (
<ButtonPrimary
style={{ width: 'fit-content' }}
padding="8px"
borderRadius="8px"
onClick={toggleDelegateModal}
>
<TYPE.white fontSize={14}>
<Trans>Read more about Uniswap governance</Trans>
</TYPE.white>
</ExternalLink>
</AutoColumn>
</CardSection>
<CardBGImage />
<CardNoise />
</VoteCard>
</TopSection>
<TopSection gap="2px">
<WrapSmall>
<TYPE.mediumHeader style={{ margin: '0.5rem 0.5rem 0.5rem 0', flexShrink: 0 }}>
<Trans>Proposals</Trans>
</TYPE.mediumHeader>
{(!allProposals || allProposals.length === 0) && !availableVotes && <Loader />}
{showUnlockVoting ? (
<ButtonPrimary
style={{ width: 'fit-content' }}
padding="8px"
borderRadius="8px"
onClick={toggleDelegateModal}
>
<Trans>Unlock Voting</Trans>
</ButtonPrimary>
) : availableVotes && JSBI.notEqual(JSBI.BigInt(0), availableVotes?.quotient) ? (
<TYPE.body fontWeight={500} mr="6px">
<Trans>
<FormattedCurrencyAmount currencyAmount={availableVotes} /> Votes
</Trans>
</TYPE.body>
) : uniBalance &&
userDelegatee &&
userDelegatee !== ZERO_ADDRESS &&
JSBI.notEqual(JSBI.BigInt(0), uniBalance?.quotient) ? (
<TYPE.body fontWeight={500} mr="6px">
<Trans>
<FormattedCurrencyAmount currencyAmount={uniBalance} /> Votes
</Trans>
</TYPE.body>
) : (
''
)}
</WrapSmall>
{!showUnlockVoting && (
<RowBetween>
<div />
{userDelegatee && userDelegatee !== ZERO_ADDRESS ? (
<RowFixed>
<TYPE.body fontWeight={500} mr="4px">
<Trans>Delegated to:</Trans>
</TYPE.body>
<AddressButton>
<StyledExternalLink
href={getExplorerLink(1, userDelegatee, ExplorerDataType.ADDRESS)}
style={{ margin: '0 4px' }}
>
{userDelegatee === account ? <Trans>Self</Trans> : shortenAddress(userDelegatee)}
</StyledExternalLink>
<TextButton onClick={toggleDelegateModal} style={{ marginLeft: '4px' }}>
<Trans>(edit)</Trans>
</TextButton>
</AddressButton>
</RowFixed>
<Trans>Unlock Voting</Trans>
</ButtonPrimary>
) : availableVotes && JSBI.notEqual(JSBI.BigInt(0), availableVotes?.quotient) ? (
<TYPE.body fontWeight={500} mr="6px">
<Trans>
<FormattedCurrencyAmount currencyAmount={availableVotes} /> Votes
</Trans>
</TYPE.body>
) : uniBalance &&
userDelegatee &&
userDelegatee !== ZERO_ADDRESS &&
JSBI.notEqual(JSBI.BigInt(0), uniBalance?.quotient) ? (
<TYPE.body fontWeight={500} mr="6px">
<Trans>
<FormattedCurrencyAmount currencyAmount={uniBalance} /> Votes
</Trans>
</TYPE.body>
) : (
''
)}
</RowBetween>
)}
{allProposals?.length === 0 && (
<EmptyProposals>
<TYPE.body style={{ marginBottom: '8px' }}>
<Trans>No proposals found.</Trans>
</TYPE.body>
<TYPE.subHeader>
<i>
<Trans>Proposals submitted by community members will appear here.</Trans>
</i>
</TYPE.subHeader>
</EmptyProposals>
)}
{allProposals?.map((p: ProposalData, i) => {
return (
<Proposal as={Link} to={'/vote/' + p.id} key={i}>
<ProposalNumber>{p.id}</ProposalNumber>
<ProposalTitle>{p.title}</ProposalTitle>
<ProposalStatus status={p.status}>{ProposalState[p.status]}</ProposalStatus>
</Proposal>
)
})}
</TopSection>
<TYPE.subHeader color="text3">
<Trans>A minimum threshold of 1% of the total UNI supply is required to submit proposals</Trans>
</TYPE.subHeader>
</PageWrapper>
</WrapSmall>
{!showUnlockVoting && (
<RowBetween>
<div />
{userDelegatee && userDelegatee !== ZERO_ADDRESS ? (
<RowFixed>
<TYPE.body fontWeight={500} mr="4px">
<Trans>Delegated to:</Trans>
</TYPE.body>
<AddressButton>
<StyledExternalLink
href={getExplorerLink(1, userDelegatee, ExplorerDataType.ADDRESS)}
style={{ margin: '0 4px' }}
>
{userDelegatee === account ? <Trans>Self</Trans> : shortenAddress(userDelegatee)}
</StyledExternalLink>
<TextButton onClick={toggleDelegateModal} style={{ marginLeft: '4px' }}>
<Trans>(edit)</Trans>
</TextButton>
</AddressButton>
</RowFixed>
) : (
''
)}
</RowBetween>
)}
{allProposals?.length === 0 && (
<EmptyProposals>
<TYPE.body style={{ marginBottom: '8px' }}>
<Trans>No proposals found.</Trans>
</TYPE.body>
<TYPE.subHeader>
<i>
<Trans>Proposals submitted by community members will appear here.</Trans>
</i>
</TYPE.subHeader>
</EmptyProposals>
)}
{allProposals?.map((p: ProposalData, i) => {
return (
<Proposal as={Link} to={'/vote/' + p.id} key={i}>
<ProposalNumber>{p.id}</ProposalNumber>
<ProposalTitle>{p.title}</ProposalTitle>
<ProposalStatus status={p.status}>{ProposalState[p.status]}</ProposalStatus>
</Proposal>
)
})}
</TopSection>
<TYPE.subHeader color="text3">
<Trans>A minimum threshold of 1% of the total UNI supply is required to submit proposals</Trans>
</TYPE.subHeader>
</PageWrapper>
<SwitchLocaleLink />
</>
)
}