Skip to content

Commit

Permalink
Feature #547: Modal Translations (#571)
Browse files Browse the repository at this point in the history
* finish legal modals, finish reward claim modals

* finish installmetamask modal, register wallet modal

* fix linting errors

* add switch network modal, add transaction explanation, unlock modal, verification error-modal, outcome price changed modal

* add proptype for t
  • Loading branch information
andre-meyer authored Nov 21, 2018
1 parent 97f5c0d commit b48ee04
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 124 deletions.
68 changes: 67 additions & 1 deletion src/assets/locales/en/translation.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"loading": "Loading...",
"application": "the Application",
"and": "and",
"header": {
"markets": "Markets",
"dashboard": "Dashboard",
Expand Down Expand Up @@ -107,5 +109,69 @@
"no_outcome_selected": "Please select an Outcome",
"loss_detected": "This transaction is not permitted because it will result in a loss of an outcome token."
}
}
},
"legal": {
"heading": "Terms of service and privacy policy",
"to_use_app": "For using {{appName}}, you have to agree with our",
"read_and_understood": "I have read and understood",
"documents": {
"terms_of_service": "Terms of Service",
"privacy_policy": "Privacy Policy",
"risk_disclaimer": "Terms of Service",
"address_public_description": "I understand and agree that my wallet address will be publicly displayed on the scoreboard"
}
},
"reward_claim": {
"info": "In order to claim your <1>{{value}} {{symbol}}</1> tokens, you first have to switch to the <2>{{targetNetwork}</span> network in your current wallet. Also make sure you have enough ETH to submit the transaction with the claim request. More information in our <3>FAQ</3>.",
"already_claimed": "Already Claimed",
"claim": "Claim",
"current_network": "Current network: ",
"gas_estimation": "Estimated Gas Costs: ",
"errors": {
"wrong_network": "Please connect to the mentioned network, before you can claim your reward.",
"not_enough_balance": "You do not have enough ETH for this transaction to cover the gas costs.",
"failed_tx_ask_support": "Unfortunately, the transaction failed. Please try again or contact our support for further assistance."
}
},
"metamask": {
"install_metamask": "Install Metamask",
"missing": "Metamask is currently not installed or detected. <1>Please download and install Metamask</1> to start using {{name}}"
},
"register_wallet": {
"heading": "Register wallet address",
"instructions": "Please register your wallet address, where we can send you {{symbol} tokens, and subsequently your {{rewardSymbol}} reward. Read our terms of service for more information",
"eth_required": "You need Rinkeby ETH to register your wallet address.",
"rinkeby_eth_balance": "Rinkeby ETH balance:",
"rinkeby_eth_request": "Request Rinkeby Ether",
"not_enough_balance": "Note: Not enough ETH balance in your MetaMask wallet to submit this transaction.",
"register_wallet": "Register Wallet"
},
"register_uport": {
"heading": "Setup claim Address",
"disclaimer": "Please register your Metamask address, where we can send your winning GNO tokens in case you finished in the top 50. <br /> Please note that you can register your address <em>only once</em>.",
"save_address": "Save Address",
"failed_tx_ask_support": "Sorry, the transaction failed. Please try again later or contact us!",
"ethereum_wallet_address": "Ethereum Address",
"enter_valid_address": "Please enter a valid address"
},
"switch_network": {
"heading": "Switch to the {{targetNetwork}} Network",
"instructions": "Your provider is not currently set to the {{targetNetwork}} network. Please switch to {{targetNetwork}} and make sure your wallet is unlocked to start using {{applicationName}}."
},
"transaction_explanations": {
"heading": "We will ask you to approve the following transactions:"
},
"unlock": {
"heading": "Unlock your MetaMask wallet",
"instructions": "Please unlock your MetaMask wallet to start using {applicationName}."
},
"verification": {
"errors": {
"not_loaded": "Our User Verification Integration could not be loaded.",
"not_found": "Sorry for the inconvience, please try again later!"
}
},
"warning": {
"price_changed": "The transaction could not be processed because the trading price changed. <br />Please check the new price and try again."
}
}
64 changes: 38 additions & 26 deletions src/components/ModalContent/ClaimReward/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react'
import cn from 'classnames/bind'
import { compose } from 'recompose'
import { Trans, withNamespaces } from 'react-i18next'
import PropTypes from 'prop-types'
import { Link, withRouter } from 'react-router-dom'
import Decimal from 'decimal.js'
Expand Down Expand Up @@ -56,6 +58,7 @@ class ClaimReward extends React.Component {
currentBalance,
rewardValue,
hasClaimedReward,
t,
} = this.props

const { claimState } = this.state
Expand All @@ -76,73 +79,75 @@ class ClaimReward extends React.Component {

let problemMessage
if (isWrongNetwork) {
problemMessage = 'Please connect to the mentioned network, before you can claim your reward.'
problemMessage = t('reward_claim.errors.wrong_network')
} else if (!sufficentFunds) {
problemMessage = 'You do not have enough ETH for this transaction to cover the gas costs.'
problemMessage = t('reward_claim.errors.not_enough_balance')
}

const canClaim = sufficentFunds && !isWrongNetwork

let claimButton
if (hasClaimedReward) {
claimButton = (
<button className={cx('btn', 'btn-primary', 'claim', 'disabled')} disabled>
ALREADY CLAIMED
<button type="button" className={cx('btn', 'btn-primary', 'claim', 'disabled')} disabled>
{t('reward_claim.already_claimed').toUpperCase()}
</button>
)
} else if (claimState === 'loading') {
claimButton = (
<button className={cx('btn', 'btn-primary', 'claim', 'disabled')} disabled>
<button type="button" className={cx('btn', 'btn-primary', 'claim', 'disabled')} disabled>
<IndefiniteSpinner width={16} height={16} />
</button>
)
} else if (claimState === 'error') {
claimButton = (
<Tooltip overlay="Unfortunately, the transaction failed. Please try again or contact our support for further assistance.">
<button className={cx('btn', 'btn-primary', 'claim')}>CLAIM</button>
<Tooltip overlay={t('reward_claim.errors.failed_tx_ask_support')}>
<button type="button" className={cx('btn', 'btn-primary', 'claim')}>CLAIM</button>
</Tooltip>
)
} else if (!canClaim) {
claimButton = (
<Tooltip overlay={problemMessage}>
<button className={cx('btn', 'btn-primary', 'claim', 'disabled')} disabled>
CLAIM
<button type="button" className={cx('btn', 'btn-primary', 'claim', 'disabled')} disabled>
{t('reward_claim.claim').toUpperCase()}
</button>
</Tooltip>
)
} else {
claimButton = (
<button onClick={this.handleClaim} className={cx('btn', 'btn-primary', 'claim')}>
CLAIM
<button type="button" onClick={this.handleClaim} className={cx('btn', 'btn-primary', 'claim')}>
{t('reward_claim.claim').toUpperCase()}
</button>
)
}

return (
<div className={cx('claimRewards')}>
<button className={cx('closeButton')} onClick={closeModal} />
<button type="button" className={cx('closeButton')} onClick={closeModal} />
<div className={cx('claimContainer')}>
<h4 className={cx('heading')}>Claim {rewardToken.symbol}</h4>
<p className={cx('annotation')}>
In order to claim your{' '}
<span className={cx('rewardInfo')}>
{rewardValue} {rewardToken.symbol}
</span>{' '}
tokens, you first have to switch to the <span className={cx('network')}>{targetNetwork}</span> network in
your MetaMask wallet. Also make sure you have enough ETH to submit the transaction with the claim request.
More information in{' '}
<Link to="/game-guide" href="/game-guide" className={cx('faqLink')}>
FAQ
</Link>
.
<Trans key="reward_claim.info">
In order to claim your&nbsp;
<span className={cx('rewardInfo')}>
{rewardValue} {rewardToken.symbol}
</span>&nbsp;
tokens, you first have to switch to the <span className={cx('network')}>{targetNetwork}</span> network in
your MetaMask wallet. Also make sure you have enough ETH to submit the transaction with the claim request.
More information in our&nbsp;
<Link to="/game-guide" href="/game-guide" className={cx('faqLink')}>
FAQ
</Link>
.
</Trans>
</p>
<div className={cx('currentNetworkContainer')}>
Current network:
{t('reward_claim.current_network')}
<span className={cx('network', { wrongNetwork: isWrongNetwork })}>{currentNetwork}</span>
</div>
{!isWrongNetwork && (
<p className={cx('gasCosts')}>
Estimated Gas Costs:{' '}
{t('reward_claim.gas_estimation')}
{hasGasCosts ? (
<b className={cx('gasEstimation')}>{decimalToText(gasCosts)}</b>
) : (
Expand All @@ -168,6 +173,8 @@ ClaimReward.propTypes = {
gasPrice: PropTypes.instanceOf(Decimal),
claimRewardGasCost: PropTypes.oneOfType([PropTypes.string, PropTypes.number, decimalJsTest]),
rewardValue: PropTypes.number.isRequired,
hasClaimedReward: PropTypes.bool.isRequired,
t: PropTypes.func.isRequired,
}

ClaimReward.defaultProps = {
Expand All @@ -178,4 +185,9 @@ ClaimReward.defaultProps = {
claimRewardGasCost: Decimal(0),
}

export default withRouter(ClaimReward)
const enhancer = compose(
withRouter,
withNamespaces(),
)

export default enhancer(ClaimReward)
24 changes: 14 additions & 10 deletions src/components/ModalContent/InstallMetamask/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Trans, withNamespaces } from 'react-i18next'
import cn from 'classnames/bind'
import MetamaskIcon from 'assets/img/icons/icon_metamask_color.svg'
import { getFeatureConfig } from 'utils/features'
Expand All @@ -12,19 +13,22 @@ const logoStyle = {
height: 100,
}

const { name = 'the application' } = getFeatureConfig('tournament')
const { name } = getFeatureConfig('tournament')

const InstallMetamask = ({ closeModal }) => (
const InstallMetamask = ({ closeModal, t }) => (
<div className={cx('installMetamask')}>
<button className={cx('closeButton')} onClick={() => closeModal()} />
<button type="button" className={cx('closeButton')} onClick={() => closeModal()} />
<img src={MetamaskIcon} alt="logo" style={logoStyle} />
<h3 className={cx('installText')}>Install MetaMask</h3>
<h3 className={cx('installText')}>{t('metamask.install_metamask')}</h3>
<p className={cx('downloadText')}>
Metamask is not currently installed or detected.{' '}
<a className={cx('downloadLink')} href="https://metamask.io/" target="_blank" rel="noopener noreferrer">
Please download and install MetaMask
</a>{' '}
to start using {name}.
<Trans key="metamask.missing" name={name || t('application')}>
Metamask is not currently installed or detected.&nbsp;
<a className={cx('downloadLink')} href="https://metamask.io/" target="_blank" rel="noopener noreferrer">
Please download and install MetaMask
</a>&nbsp;
to start using {name || t('application')}.
</Trans>

</p>
</div>
)
Expand All @@ -33,4 +37,4 @@ InstallMetamask.propTypes = {
closeModal: PropTypes.func.isRequired,
}

export default InstallMetamask
export default withNamespaces()(InstallMetamask)
11 changes: 6 additions & 5 deletions src/components/ModalContent/OutcomePriceChanged.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import React from 'react'
import { withNamespaces } from 'react-i18next'
import PropTypes from 'prop-types'
import cn from 'classnames/bind'
import style from './TransactionsExplanation/TransactionExplanation.scss'

const cx = cn.bind(style)

const OutcomePriceChanged = ({ closeModal }) => (
const OutcomePriceChanged = ({ closeModal, t }) => (
<div className={cx('transactionsExplanation')}>
<div className={cx('closeButton')} onClick={closeModal} />
<button type="button" className={cx('closeButton')} onClick={closeModal} />
<h3>
The transaction could not be processed because the trading price changed. <br />
Please check the new price and try again.
{t('warning.price_changed')}
</h3>
</div>
)

OutcomePriceChanged.propTypes = {
closeModal: PropTypes.func.isRequired,
t: PropTypes.func.isRequired,
}

export default OutcomePriceChanged
export default withNamespaces()(OutcomePriceChanged)
51 changes: 28 additions & 23 deletions src/components/ModalContent/RegisterWallet/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react'
import cn from 'classnames/bind'
import { withNamespaces } from 'react-i18next'
import PropTypes from 'prop-types'
import { lifecycle } from 'recompose'
import { compose, lifecycle } from 'recompose'
import Decimal from 'decimal.js'
import DecimalValue from 'components/DecimalValue'
import InteractionButton from 'containers/InteractionButton'
Expand All @@ -25,6 +26,7 @@ const RegisterMainnetAddress = ({
gasPrice,
registrationGasCost,
collateralToken: { symbol: collateralTokenSymbol },
t,
}) => {
const handleRegistration = async (documentsAccepted) => {
await updateMainnetAddress(currentAccount)
Expand All @@ -41,32 +43,31 @@ const RegisterMainnetAddress = ({

return (
<div className={cx('registerWallet')}>
<button className={cx('closeButton')} onClick={closeModal} />
<button type="button" className={cx('closeButton')} onClick={closeModal} />
<div className={cx('registerContainer')}>
<h4 className={cx('heading')}>Register wallet address</h4>
<h4 className={cx('heading')}>{t('register_wallet.heading')}</h4>
<p className={cx('annotation')}>
Please register your wallet address, where we can send you {collateralTokenSymbol} tokens, and subsequently
your {rewardTokenSymbol} reward. Read our terms of service for more information
{t('register_wallet.instructions', { symbol: collateralTokenSymbol, rewardSymbol: rewardTokenSymbol })}
</p>
<div className={cx('walletAddressContainer')}>
<img src={WalletIcon} className={cx('walletIcon')} alt="" />
<h4 className={cx('walletAddress')}>{currentAccount}</h4>
</div>
<p className={cx('rinkebyEthAnnotation')}>
You need Rinkeby ETH to register your wallet address. <br />
Rinkeby ETH balance: <DecimalValue value={currentBalance} className={cx('walletBalance')} /> -{' '}
{t('register_wallet.eth_required')} <br />
{t('register_wallet.rinkeby_eth_balance')} <DecimalValue value={currentBalance} className={cx('walletBalance')} /> -{' '}
<a className={cx('faucetLink')} href="https://faucet.rinkeby.io/" target="_blank" rel="noopener noreferrer">
Request Rinkeby Ether
{t('register_wallet.rinkeby_eth_request')}
</a>
<img src={LinkIcon} className={cx('linkIcon')} alt="" />
</p>
{insufficientFunds && (
<span className={cx('insufficientETH')}>
Note: Not enough ETH balance in your MetaMask wallet to submit this transaction.
{t('register_wallet.not_enough_balance')}
</span>
)}
<LegalCompliance
submitButtonLabel="REGISTER ADDRESS"
submitButtonLabel={t('register_wallet.register_wallet').toUpperCase()}
submitButtonClassName={cx('btn', 'btn-primary', 'actionButton')}
submitButtonDisabledClassName={cx('disabled')}
submitButtonOpts={{
Expand All @@ -93,23 +94,27 @@ RegisterMainnetAddress.propTypes = {
collateralToken: PropTypes.shape({
symbol: PropTypes.string,
}).isRequired,
mainnetAddress: PropTypes.string,
t: PropTypes.func.isRequired,
}

RegisterMainnetAddress.defaultProps = {
gasPrice: Decimal(0),
registrationGasCost: 0,
mainnetAddress: undefined,
}

export default lifecycle({
componentDidMount() {
this.props.requestRegistrationGasCost()
this.props.requestGasPrice()
},
componentDidUpdate() {
if (this.props.mainnetAddress) {
this.props.closeModal()
}
},
})(RegisterMainnetAddress)
const enhancer = compose(
withNamespaces(),
lifecycle({
componentDidMount() {
this.props.requestRegistrationGasCost()
this.props.requestGasPrice()
},
componentDidUpdate() {
if (this.props.mainnetAddress) {
this.props.closeModal()
}
},
}),
)

export default enhancer(RegisterMainnetAddress)
Loading

0 comments on commit b48ee04

Please sign in to comment.