Skip to content

Commit 907d830

Browse files
committed
Merge branch 'frontend-i18n-params-II'
2 parents 81b3b25 + ebbc518 commit 907d830

File tree

9 files changed

+87
-64
lines changed

9 files changed

+87
-64
lines changed

frontends/web/src/components/terms/moonpay-terms.tsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { useTranslation } from 'react-i18next';
19-
import { getCryptoName } from '@/routes/account/utils';
2018
import { ChangeEvent } from 'react';
19+
import { useTranslation } from 'react-i18next';
20+
import { isBitcoinBased } from '@/routes/account/utils';
2121
import { Button, Checkbox } from '@/components/forms';
2222
import { setConfig } from '@/utils/config';
2323
import { IAccount } from '@/api/account';
@@ -32,24 +32,27 @@ type TProps = {
3232
export const MoonpayTerms = ({ account, onAgreedTerms }: TProps) => {
3333
const { t } = useTranslation();
3434

35-
const name = getCryptoName(t('buy.info.crypto'), account);
36-
3735
const handleSkipDisclaimer = (e: ChangeEvent<HTMLInputElement>) => {
3836
setConfig({ frontend: { skipMoonpayDisclaimer: e.target.checked } });
3937
};
4038

39+
const coinCode = account.coinCode.toUpperCase();
40+
const isBitcoin = isBitcoinBased(account.coinCode);
41+
4142
return (
4243
<div className={style.disclaimerContainer}>
4344
<div className={style.disclaimer}>
4445
<h2 className={style.title}>
45-
{t('buy.info.disclaimer.title', { name })}
46+
{t('buy.info.disclaimer.title', {
47+
context: isBitcoin ? 'bitcoin' : 'crypto'
48+
})}
4649
</h2>
47-
<p>{t('buy.info.disclaimer.intro.0', { name })}</p>
48-
<p>{t('buy.info.disclaimer.intro.1', { name })}</p>
50+
<p>{t('buy.info.disclaimer.intro.0', { coinCode })}</p>
51+
<p>{t('buy.info.disclaimer.intro.1', { coinCode })}</p>
4952
<h2 className={style.title}>
5053
{t('buy.info.disclaimer.payment.title')}
5154
</h2>
52-
<p>{t('buy.info.disclaimer.payment.details', { name })}</p>
55+
<p>{t('buy.info.disclaimer.payment.details', { coinCode })}</p>
5356
<div className={style.table}>
5457
<table>
5558
<colgroup>
@@ -82,7 +85,11 @@ export const MoonpayTerms = ({ account, onAgreedTerms }: TProps) => {
8285
<h2 className={style.title}>
8386
{t('buy.info.disclaimer.security.title')}
8487
</h2>
85-
<p>{t('buy.info.disclaimer.security.description', { name })}</p>
88+
<p>
89+
{t('buy.info.disclaimer.security.description', {
90+
context: isBitcoin ? 'bitcoin' : 'crypto'
91+
})}
92+
</p>
8693
<p>
8794
<A href="https://bitbox.swiss/bitbox02/threat-model/">
8895
{t('buy.info.disclaimer.security.link')}
@@ -91,7 +98,11 @@ export const MoonpayTerms = ({ account, onAgreedTerms }: TProps) => {
9198
<h2 className={style.title}>
9299
{t('buy.info.disclaimer.protection.title')}
93100
</h2>
94-
<p>{t('buy.info.disclaimer.protection.description', { name })}</p>
101+
<p>
102+
{t('buy.info.disclaimer.protection.description', {
103+
context: isBitcoin ? 'bitcoin' : 'crypto'
104+
})}
105+
</p>
95106
<p>
96107
<A href="https://www.moonpay.com/privacy_policy">
97108
{t('buy.info.disclaimer.privacyPolicy')}

frontends/web/src/locales/en/app.json

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -454,19 +454,18 @@
454454
},
455455
"noExchanges": "Sorry, there are no available exchanges in this region.",
456456
"region": "Region",
457-
"selectRegion": "Not specified",
458-
"title": "Buy {{name}}"
457+
"selectRegion": "Not specified"
459458
},
460459
"info": {
461460
"continue": "Agree and continue",
462461
"crypto": "crypto",
463462
"disclaimer": {
464463
"intro": [
465-
"We partner with MoonPay to offer you a seamless way to buy {{name}} directly within the BitBoxApp. It's just a few clicks.",
466-
"MoonPay is a platform that makes it easy and quick to buy {{name}} in over 160+ countries."
464+
"We partner with MoonPay to offer you a seamless way to buy {{coinCode}} directly within the BitBoxApp. It's just a few clicks.",
465+
"MoonPay is a platform that makes it easy and quick to buy {{coinCode}} in over 160+ countries."
467466
],
468467
"payment": {
469-
"details": "You can buy {{name}} instantly via MoonPay with the following payment methods. Credit or debit card orders are instant and convenient, but more expensive due to increased chargeback risk. We recommend using the bank transfer option for larger amounts. The minimum fee is 4 USD/EUR or equivalent.",
468+
"details": "You can buy {{coinCode}} instantly via MoonPay with the following payment methods. Credit or debit card orders are instant and convenient, but more expensive due to increased chargeback risk. We recommend using the bank transfer option for larger amounts. The minimum fee is 4 USD/EUR or equivalent.",
470469
"footnote": "Please note that MoonPay's exchange rates can differ from the ones used in the BitBoxApp, resulting in slightly different amounts.",
471470
"table": {
472471
"1_description": "Lowest fees, can take up to 3 working days",
@@ -481,23 +480,27 @@
481480
},
482481
"privacyPolicy": "MoonPay privacy policy",
483482
"protection": {
484-
"description": "The BitBoxApp does not collect any data when buying {{name}}, the incoming funds are treated like a regular transaction. MoonPay needs to collect some personal data to operate. Their Privacy Policy explains in detail how that data is handled.",
485-
"descriptionGeneric": "The BitBoxApp does not collect any data when buying {{name}}, the incoming funds are treated like a regular transaction. However partner exchanges need to collect some information to operate. Please refer to their respective privacy policies to see in more detail how the data is handled.",
483+
"descriptionGeneric_bitcoin": "The BitBoxApp does not collect any data when buying Bitcoin, the incoming funds are treated like a regular transaction. However partner exchanges need to collect some information to operate. Please refer to their respective privacy policies to see in more detail how the data is handled.",
484+
"descriptionGeneric_crypto": "The BitBoxApp does not collect any data when buying crypto, the incoming funds are treated like a regular transaction. However partner exchanges need to collect some information to operate. Please refer to their respective privacy policies to see in more detail how the data is handled.",
485+
"description_bitcoin": "The BitBoxApp does not collect any data when buying Bitcoin, the incoming funds are treated like a regular transaction. MoonPay needs to collect some personal data to operate. Their Privacy Policy explains in detail how that data is handled.",
486+
"description_crypto": "The BitBoxApp does not collect any data when buying crypto, the incoming funds are treated like a regular transaction. MoonPay needs to collect some personal data to operate. Their Privacy Policy explains in detail how that data is handled.",
486487
"title": "Data protection"
487488
},
488489
"security": {
489-
"description": "When you buy {{name}} via MoonPay, you are using an external service. This service is out of scope of the BitBox02 security threat model and relies on the safety and security of the environment which the BitBoxApp software is running in.",
490-
"descriptionGeneric": "When you buy {{name}} via a partner exchange, you are using an external service. This service is out of scope of the BitBox02 security threat model and relies on the safety and security of the environment which the BitBoxApp software is running in.",
490+
"descriptionGeneric_bitcoin": "When you buy Bitcoin via a partner exchange, you are using an external service. This service is out of scope of the BitBox02 security threat model and relies on the safety and security of the environment which the BitBoxApp software is running in.",
491+
"descriptionGeneric_crypto": "When you buy crypto via a partner exchange, you are using an external service. This service is out of scope of the BitBox02 security threat model and relies on the safety and security of the environment which the BitBoxApp software is running in.",
492+
"description_bitcoin": "When you buy Bitcoin via MoonPay, you are using an external service. This service is out of scope of the BitBox02 security threat model and relies on the safety and security of the environment which the BitBoxApp software is running in.",
493+
"description_crypto": "When you buy crypto via MoonPay, you are using an external service. This service is out of scope of the BitBox02 security threat model and relies on the safety and security of the environment which the BitBoxApp software is running in.",
491494
"link": "Security threat model",
492495
"title": "Security model"
493496
},
494-
"title": "Welcome to your one stop shop for buying {{name}}"
497+
"title_bitcoin": "Welcome to your one stop shop for buying Bitcoin",
498+
"title_crypto": "Welcome to your one stop shop for buying crypto"
495499
},
496500
"next": "Next",
497501
"selectLabel": "Choose your account",
498502
"selectPlaceholder": "Select a coin",
499-
"skip": "Do not show again",
500-
"title": "Buy {{name}}"
503+
"skip": "Do not show again"
501504
},
502505
"pocket": {
503506
"data": {
@@ -529,8 +532,7 @@
529532
"p3": "With Pocket, you can also do regular buys through standing bank orders, so you can DCA (dollar-cost averaging) with ease.",
530533
"title": "Welcome to your one stop shop for buying bitcoin"
531534
}
532-
},
533-
"title": "Buy {{name}}"
535+
}
534536
},
535537
"changePin": {
536538
"newTitle": "New device password",

frontends/web/src/routes/account/info/buyReceiveCTA.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export const BuyReceiveCTA = ({
5757
const onReceiveCTA = () => {
5858
if (balanceList) {
5959
if (balanceList.length > 1) {
60-
navigate('accounts/select-receive');
60+
navigate('/accounts/select-receive');
6161
return;
6262
}
6363
navigate(`/account/${code}/receive`);

frontends/web/src/routes/account/utils.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,6 @@ export const findAccount = (
2424
return accounts.find(({ code }) => accountCode === code);
2525
};
2626

27-
export const getCryptoName = (
28-
cryptoLabel: string,
29-
account?: IAccount,
30-
): string => {
31-
if (account && isBitcoinOnly(account.coinCode)) {
32-
return 'Bitcoin';
33-
}
34-
return cryptoLabel;
35-
};
36-
3727
export const isBitcoinOnly = (coinCode: CoinCode): boolean => {
3828
switch (coinCode) {
3929
case 'btc':

frontends/web/src/routes/buy/exchange.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import * as exchangesAPI from '@/api/exchanges';
2424
import { AccountCode, IAccount } from '@/api/account';
2525
import { Header } from '@/components/layout';
2626
import { BuyGuide } from './guide';
27-
import { findAccount, getCryptoName } from '@/routes/account/utils';
27+
import { findAccount, isBitcoinOnly } from '@/routes/account/utils';
2828
import { route } from '@/utils/route';
2929
import { useLoad } from '@/hooks/api';
3030
import { getRegionNameFromLocale } from '@/i18n/utils';
@@ -64,7 +64,12 @@ export const Exchange = ({ code, accounts }: TProps) => {
6464
const config = useLoad(getConfig);
6565

6666
const account = findAccount(accounts, code);
67-
const name = getCryptoName(t('buy.info.crypto'), account);
67+
const hasOnlyBTCAccounts = accounts.every(({ coinCode }) => isBitcoinOnly(coinCode));
68+
const isBitcoin = hasOnlyBTCAccounts || (account && isBitcoinOnly(account?.coinCode));
69+
70+
const title = t('generic.buy', {
71+
context: isBitcoin ? 'bitcoin' : 'crypto',
72+
});
6873

6974
const hasOnlyOneSupportedExchange = allExchangeDeals ? allExchangeDeals.exchanges.filter(exchange => exchange.supported).length === 1 : false;
7075

@@ -191,9 +196,9 @@ export const Exchange = ({ code, accounts }: TProps) => {
191196
{info && <InfoContent info={info} cardFee={cardFee} bankTransferFee={bankTransferFee} />}
192197
</Dialog>
193198
<div className="innerContainer scrollableContainer">
194-
<Header title={<h2>{t('buy.exchange.title', { name })}</h2>} />
199+
<Header title={<h2>{title}</h2>} />
195200
<div className={[style.exchangeContainer, 'content', 'narrow', 'isVerticallyCentered'].join(' ')}>
196-
<h1 className={style.title}>{t('buy.title', { name })}</h1>
201+
<h1 className={style.title}>{title}</h1>
197202
<p className={style.label}>{t('buy.exchange.region')}</p>
198203
{regions.length ? (
199204
<>
@@ -245,7 +250,7 @@ export const Exchange = ({ code, accounts }: TProps) => {
245250
</div>
246251
</div>
247252
</div>
248-
<BuyGuide name={name} />
253+
<BuyGuide translationContext={hasOnlyBTCAccounts ? 'bitcoin' : 'crypto'} />
249254
</div>
250255
);
251256
};

frontends/web/src/routes/buy/guide.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ import { Entry } from '@/components/guide/entry';
1919
import { Guide } from '@/components/guide/guide';
2020

2121
interface BuyGuideProps {
22-
name: string;
2322
exchange?: 'pocket' | 'moonpay';
23+
translationContext: 'bitcoin' | 'crypto';
2424
}
2525

26-
export const BuyGuide = ({ name, exchange }: BuyGuideProps) => {
26+
export const BuyGuide = ({ exchange, translationContext }: BuyGuideProps) => {
2727
const { t } = useTranslation();
2828

2929
const pocketLink = {
@@ -45,12 +45,14 @@ export const BuyGuide = ({ name, exchange }: BuyGuideProps) => {
4545
text: t('buy.info.disclaimer.security.link'),
4646
url: 'https://bitbox.swiss/bitbox02/threat-model/',
4747
},
48-
text: t('buy.info.disclaimer.security.descriptionGeneric', { name }),
48+
text: t('buy.info.disclaimer.security.descriptionGeneric', {
49+
context: translationContext
50+
}),
4951
title: t('buy.info.disclaimer.security.title'),
5052
}} shown={true} />
5153
<Entry key="guide.buy.protection" entry={{
5254
link: exchange ? privacyLink : undefined,
53-
text: t('buy.info.disclaimer.protection.descriptionGeneric', { name }),
55+
text: t('buy.info.disclaimer.protection.descriptionGeneric', { context: translationContext }),
5456
title: t('buy.info.disclaimer.protection.title'),
5557
}} />
5658
</Guide>

frontends/web/src/routes/buy/info.tsx

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,34 +85,39 @@ export const BuyInfo = ({ code, accounts }: TProps) => {
8585
}
8686

8787
const hasOnlyBTCAccounts = accounts.every(({ coinCode }) => isBitcoinOnly(coinCode));
88-
const name = hasOnlyBTCAccounts ? 'Bitcoin' : t('buy.info.crypto');
88+
const translationContext = hasOnlyBTCAccounts ? 'bitcoin' : 'crypto';
8989

9090
return (
9191
<Main>
9292
<GuideWrapper>
9393
<GuidedContent>
94-
<Header title={<h2>{t('buy.info.title', { name })}</h2>}>
94+
<Header title={
95+
<h2>
96+
{t('generic.buy', { context: translationContext })}
97+
</h2>
98+
}>
9599
<HideAmountsButton />
96100
</Header>
97101
<View width="550px" verticallyCentered fullscreen={false}>
98102
<ViewContent>
99103
{ !supportedAccounts || supportedAccounts.length === 0 ? (
100104
<div className="content narrow isVerticallyCentered">{t('accountSummary.noAccount')}</div>
101105
) : (
102-
supportedAccounts &&
103-
<GroupedAccountSelector
104-
accounts={supportedAccounts}
105-
title={t('buy.title', { name })}
106-
disabled={disabled}
107-
selected={selected}
108-
onChange={setSelected}
109-
onProceed={handleProceed}
110-
/>
106+
supportedAccounts && (
107+
<GroupedAccountSelector
108+
accounts={supportedAccounts}
109+
title={t('generic.buy', { context: translationContext })}
110+
disabled={disabled}
111+
selected={selected}
112+
onChange={setSelected}
113+
onProceed={handleProceed}
114+
/>
115+
)
111116
)}
112117
</ViewContent>
113118
</View>
114119
</GuidedContent>
115-
<BuyGuide name={name} />
120+
<BuyGuide translationContext={translationContext} />
116121
</GuideWrapper>
117122
</Main>
118123
);

frontends/web/src/routes/buy/moonpay.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { getMoonpayBuyInfo } from '@/api/exchanges';
2525
import { BuyGuide } from './guide';
2626
import { Header } from '@/components/layout';
2727
import { Spinner } from '@/components/spinner/Spinner';
28-
import { findAccount, getCryptoName } from '@/routes/account/utils';
28+
import { findAccount, isBitcoinOnly } from '@/routes/account/utils';
2929
import { MoonpayTerms } from '@/components/terms/moonpay-terms';
3030
import style from './iframe.module.css';
3131

@@ -45,7 +45,6 @@ export const Moonpay = ({ accounts, code }: TProps) => {
4545
const moonpay = useLoad(getMoonpayBuyInfo(code));
4646

4747
const account = findAccount(accounts, code);
48-
const name = getCryptoName(t('buy.info.crypto'), account);
4948
const ref = createRef<HTMLDivElement>();
5049
let resizeTimerID: any;
5150

@@ -78,12 +77,19 @@ export const Moonpay = ({ accounts, code }: TProps) => {
7877
return null;
7978
}
8079

80+
const hasOnlyBTCAccounts = accounts.every(({ coinCode }) => isBitcoinOnly(coinCode));
81+
const translationContext = hasOnlyBTCAccounts ? 'bitcoin' : 'crypto';
82+
8183
return (
8284
<div className="contentWithGuide">
8385
<div className="container">
8486
<div className="innerContainer">
8587
<div className={style.header}>
86-
<Header title={<h2>{t('buy.info.title', { name })}</h2>} />
88+
<Header title={
89+
<h2>
90+
{t('generic.buy', { context: translationContext })}
91+
</h2>
92+
} />
8793
</div>
8894
<div ref={ref} className={style.container}>
8995
{ !agreedTerms ? (
@@ -114,7 +120,7 @@ export const Moonpay = ({ accounts, code }: TProps) => {
114120
</div>
115121
</div>
116122
</div>
117-
<BuyGuide name={name} exchange={'moonpay'}/>
123+
<BuyGuide exchange="moonpay" translationContext={translationContext} />
118124
</div>
119125
);
120126
};

frontends/web/src/routes/buy/pocket.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ export const Pocket = ({ code }: TProps) => {
5252
let signing = false;
5353
let resizeTimerID: any = undefined;
5454

55-
const name = 'Bitcoin';
56-
5755
useEffect(() => {
5856
if (config) {
5957
setAgreedTerms(config.frontend.skipPocketDisclaimer);
@@ -215,7 +213,11 @@ export const Pocket = ({ code }: TProps) => {
215213
<div className="contentWithGuide">
216214
<div className="container">
217215
<div className={style.header}>
218-
<Header title={<h2>{t('buy.info.title', { name })}</h2>} />
216+
<Header title={
217+
<h2>
218+
{t('generic.buy', { context: 'bitcoin' })}
219+
</h2>
220+
} />
219221
</div>
220222
<div ref={ref} className={style.container}>
221223
{ !agreedTerms ? (
@@ -249,7 +251,7 @@ export const Pocket = ({ code }: TProps) => {
249251
</Dialog>
250252
</div>
251253
</div>
252-
<BuyGuide name={name} exchange={'pocket'}/>
254+
<BuyGuide exchange="pocket" translationContext="bitcoin" />
253255
</div>
254256
);
255257
};

0 commit comments

Comments
 (0)