chore(trading): i18n-friendly referrals (#5113)

This commit is contained in:
Art 2023-10-24 17:43:33 +02:00 committed by GitHub
parent 82fb29d541
commit 6c9272cd53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 115 additions and 83 deletions

View File

@ -81,7 +81,7 @@ export const ApplyCodeForm = () => {
if (!res) { if (!res) {
setError('code', { setError('code', {
type: 'required', type: 'required',
message: 'The transaction could not be sent', message: t('The transaction could not be sent'),
}); });
} }
if (res) { if (res) {
@ -98,7 +98,7 @@ export const ApplyCodeForm = () => {
message: message:
err instanceof Error err instanceof Error
? err.message ? err.message
: 'Your code has been rejected', : t('Your code has been rejected'),
}); });
} }
}); });
@ -152,7 +152,7 @@ export const ApplyCodeForm = () => {
<span className="text-vega-green-500"> <span className="text-vega-green-500">
<VegaIcon name={VegaIconNames.TICK} size={20} /> <VegaIcon name={VegaIconNames.TICK} size={20} />
</span>{' '} </span>{' '}
<span className="pt-1">Code applied</span> <span className="pt-1">{t('Code applied')}</span>
</h3> </h3>
</div> </div>
); );
@ -162,7 +162,7 @@ export const ApplyCodeForm = () => {
if (!pubKey) { if (!pubKey) {
return { return {
disabled: false, disabled: false,
children: 'Connect wallet', children: t('Connect wallet'),
type: 'button' as ButtonHTMLAttributes<HTMLButtonElement>['type'], type: 'button' as ButtonHTMLAttributes<HTMLButtonElement>['type'],
onClick: ((event) => { onClick: ((event) => {
event.preventDefault(); event.preventDefault();
@ -174,7 +174,7 @@ export const ApplyCodeForm = () => {
if (isReadOnly) { if (isReadOnly) {
return { return {
disabled: true, disabled: true,
children: 'Apply a code', children: t('Apply a code'),
type: 'submit' as ButtonHTMLAttributes<HTMLButtonElement>['type'], type: 'submit' as ButtonHTMLAttributes<HTMLButtonElement>['type'],
}; };
} }
@ -182,14 +182,14 @@ export const ApplyCodeForm = () => {
if (status === 'requested') { if (status === 'requested') {
return { return {
disabled: true, disabled: true,
children: 'Confirm in wallet...', children: t('Confirm in wallet...'),
type: 'submit' as ButtonHTMLAttributes<HTMLButtonElement>['type'], type: 'submit' as ButtonHTMLAttributes<HTMLButtonElement>['type'],
}; };
} }
return { return {
disabled: false, disabled: false,
children: 'Apply a code', children: t('Apply a code'),
type: 'submit' as ButtonHTMLAttributes<HTMLButtonElement>['type'], type: 'submit' as ButtonHTMLAttributes<HTMLButtonElement>['type'],
}; };
}; };
@ -198,10 +198,10 @@ export const ApplyCodeForm = () => {
<> <>
<div className="w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg"> <div className="w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg">
<h3 className="mb-4 text-2xl text-center calt"> <h3 className="mb-4 text-2xl text-center calt">
Apply a referral code {t('Apply a referral code')}
</h3> </h3>
<p className="mb-4 text-center text-base"> <p className="mb-4 text-center text-base">
Enter a referral code to get trading discounts. {t('Enter a referral code to get trading discounts.')}
</p> </p>
<form <form
className={classNames('w-full flex flex-col gap-4', { className={classNames('w-full flex flex-col gap-4', {
@ -210,11 +210,11 @@ export const ApplyCodeForm = () => {
onSubmit={handleSubmit(onSubmit)} onSubmit={handleSubmit(onSubmit)}
> >
<label> <label>
<span className="sr-only">Your referral code</span> <span className="sr-only">{t('Your referral code')}</span>
<Input <Input
hasError={Boolean(errors.code)} hasError={Boolean(errors.code)}
{...register('code', { {...register('code', {
required: 'You have to provide a code to apply it.', required: t('You have to provide a code to apply it.'),
validate: validateCode, validate: validateCode,
})} })}
placeholder="Enter a code" placeholder="Enter a code"
@ -236,7 +236,7 @@ export const ApplyCodeForm = () => {
) : null} ) : null}
{previewData ? ( {previewData ? (
<div className="mt-10"> <div className="mt-10">
<h2 className="text-2xl mb-5">You are joining</h2> <h2 className="text-2xl mb-5">{t('You are joining')}</h2>
<Statistics data={previewData} as="referee" /> <Statistics data={previewData} as="referee" />
</div> </div>
) : null} ) : null}

View File

@ -24,6 +24,7 @@ import {
DISCLAIMER_REFERRAL_DOCS_LINK, DISCLAIMER_REFERRAL_DOCS_LINK,
} from './constants'; } from './constants';
import { useReferral } from './hooks/use-referral'; import { useReferral } from './hooks/use-referral';
import { t } from '@vegaprotocol/i18n';
export const CreateCodeContainer = () => { export const CreateCodeContainer = () => {
return <CreateCodeForm />; return <CreateCodeForm />;
@ -38,10 +39,13 @@ export const CreateCodeForm = () => {
return ( return (
<div className="w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg"> <div className="w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg">
<h3 className="mb-4 text-2xl text-center calt">Create a referral code</h3> <h3 className="mb-4 text-2xl text-center calt">
{t('Create a referral code')}
</h3>
<p className="mb-4 text-center text-base"> <p className="mb-4 text-center text-base">
Generate a referral code to share with your friends and start earning {t(
commission. 'Generate a referral code to share with your friends and start earning commission.'
)}
</p> </p>
<div className="w-full flex flex-col"> <div className="w-full flex flex-col">
@ -56,12 +60,12 @@ export const CreateCodeForm = () => {
} }
}} }}
> >
{pubKey ? 'Create a referral code' : 'Connect wallet'} {pubKey ? t('Create a referral code') : t('Connect wallet')}
</RainbowButton> </RainbowButton>
</div> </div>
<Dialog <Dialog
title="Create a referral code" title={t('Create a referral code')}
open={dialogOpen} open={dialogOpen}
onChange={() => setDialogOpen(false)} onChange={() => setDialogOpen(false)}
size="small" size="small"
@ -124,21 +128,21 @@ const CreateCodeDialog = ({
const getButtonProps = () => { const getButtonProps = () => {
if (status === 'idle' || status === 'error') { if (status === 'idle' || status === 'error') {
return { return {
children: 'Generate code', children: t('Generate code'),
onClick: () => onSubmit(), onClick: () => onSubmit(),
}; };
} }
if (status === 'loading') { if (status === 'loading') {
return { return {
children: 'Confirm in wallet...', children: t('Confirm in wallet...'),
disabled: true, disabled: true,
}; };
} }
if (status === 'success') { if (status === 'success') {
return { return {
children: 'Close', children: t('Close'),
intent: Intent.Success, intent: Intent.Success,
onClick: () => { onClick: () => {
refetch(); refetch();
@ -151,12 +155,12 @@ const CreateCodeDialog = ({
if (!pubKey || currentStakeAvailable == null || requiredStake == null) { if (!pubKey || currentStakeAvailable == null || requiredStake == null) {
return ( return (
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<p>You must be connected to the Vega wallet.</p> <p>{t('You must be connected to the Vega wallet.')}</p>
<TradingButton <TradingButton
intent={Intent.Primary} intent={Intent.Primary}
onClick={() => setDialogOpen(false)} onClick={() => setDialogOpen(false)}
> >
Close {t('Close')}
</TradingButton> </TradingButton>
</div> </div>
); );
@ -166,16 +170,18 @@ const CreateCodeDialog = ({
return ( return (
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<p> <p>
You need at least{' '} {t('You need at least')}{' '}
{addDecimalsFormatNumber(requiredStake.toString(), 18)} VEGA staked to {addDecimalsFormatNumber(requiredStake.toString(), 18)}{' '}
generate a referral code and participate in the referral program. {t(
'VEGA staked to generate a referral code and participate in the referral program.'
)}
</p> </p>
<TradingAnchorButton <TradingAnchorButton
href={createLink(TokenStaticLinks.ASSOCIATE)} href={createLink(TokenStaticLinks.ASSOCIATE)}
intent={Intent.Primary} intent={Intent.Primary}
target="_blank" target="_blank"
> >
Stake some $VEGA now {t('Stake some $VEGA now')}
</TradingAnchorButton> </TradingAnchorButton>
</div> </div>
); );
@ -185,8 +191,9 @@ const CreateCodeDialog = ({
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
{(status === 'idle' || status === 'loading' || status === 'error') && ( {(status === 'idle' || status === 'loading' || status === 'error') && (
<p> <p>
Generate a referral code to share with your friends and start earning {t(
commission. 'Generate a referral code to share with your friends and start earning commission.'
)}
</p> </p>
)} )}
{status === 'success' && code && ( {status === 'success' && code && (
@ -201,7 +208,7 @@ const CreateCodeDialog = ({
className="text-sm no-underline" className="text-sm no-underline"
icon={<VegaIcon name={VegaIconNames.COPY} />} icon={<VegaIcon name={VegaIconNames.COPY} />}
> >
<span>Copy</span> <span>{t('Copy')}</span>
</TradingButton> </TradingButton>
</CopyWithTooltip> </CopyWithTooltip>
</div> </div>
@ -214,10 +221,10 @@ const CreateCodeDialog = ({
{err && <InputError>{err}</InputError>} {err && <InputError>{err}</InputError>}
<div className="flex justify-center pt-5 mt-2 text-sm border-t gap-4 text-default border-default"> <div className="flex justify-center pt-5 mt-2 text-sm border-t gap-4 text-default border-default">
<ExternalLink href={ABOUT_REFERRAL_DOCS_LINK}> <ExternalLink href={ABOUT_REFERRAL_DOCS_LINK}>
About the referral program {t('About the referral program')}
</ExternalLink> </ExternalLink>
<ExternalLink href={DISCLAIMER_REFERRAL_DOCS_LINK}> <ExternalLink href={DISCLAIMER_REFERRAL_DOCS_LINK}>
Disclaimer {t('Disclaimer')}
</ExternalLink> </ExternalLink>
</div> </div>
</div> </div>

View File

@ -3,6 +3,7 @@ import { RainbowButton } from './buttons';
import { AnimatedDudeWithWire } from './graphics/dude'; import { AnimatedDudeWithWire } from './graphics/dude';
import { LayoutWithSky } from './layout'; import { LayoutWithSky } from './layout';
import { Routes } from '../../lib/links'; import { Routes } from '../../lib/links';
import { t } from '@vegaprotocol/i18n';
export const ErrorBoundary = () => { export const ErrorBoundary = () => {
const error = useRouteError(); const error = useRouteError();
@ -39,7 +40,7 @@ export const ErrorBoundary = () => {
variant="border" variant="border"
className="text-xs" className="text-xs"
> >
Go back and try again {t('Go back and try again')}
</RainbowButton> </RainbowButton>
</p> </p>
</LayoutWithSky> </LayoutWithSky>
@ -60,7 +61,7 @@ export const NotFound = () => {
<h1 className="text-6xl font-alpha calt mb-10">{'Not found'}</h1> <h1 className="text-6xl font-alpha calt mb-10">{'Not found'}</h1>
<p className="text-lg mb-10"> <p className="text-lg mb-10">
{"The page you're looking for doesn't exists."} {t("The page you're looking for doesn't exists.")}
</p> </p>
<p className="text-lg mb-10"> <p className="text-lg mb-10">
@ -69,7 +70,7 @@ export const NotFound = () => {
variant="border" variant="border"
className="text-xs" className="text-xs"
> >
Go back and try again {t('Go back and try again')}
</RainbowButton> </RainbowButton>
</p> </p>
</div> </div>

View File

@ -1,3 +1,4 @@
import { t } from '@vegaprotocol/i18n';
import { Table } from './table'; import { Table } from './table';
export const HowItWorksTable = () => ( export const HowItWorksTable = () => (
@ -13,7 +14,9 @@ export const HowItWorksTable = () => (
1 1
</span> </span>
), ),
step: 'Referrers generate a code assigned to their key via an on chain transaction', step: t(
'Referrers generate a code assigned to their key via an on chain transaction'
),
}, },
{ {
number: ( number: (
@ -21,7 +24,9 @@ export const HowItWorksTable = () => (
2 2
</span> </span>
), ),
step: 'Anyone with the referral link can apply it to their key(s) of choice via an on chain transaction', step: t(
'Anyone with the referral link can apply it to their key(s) of choice via an on chain transaction'
),
}, },
{ {
number: ( number: (
@ -29,7 +34,9 @@ export const HowItWorksTable = () => (
3 3
</span> </span>
), ),
step: 'Discounts are applied automatically during trading based on the key(s) used', step: t(
'Discounts are applied automatically during trading based on the key(s) used'
),
}, },
{ {
number: ( number: (
@ -37,7 +44,9 @@ export const HowItWorksTable = () => (
4 4
</span> </span>
), ),
step: 'Referrers earn commission based on a percentage of the taker fees their referees pay', step: t(
'Referrers earn commission based on a percentage of the taker fees their referees pay'
),
}, },
{ {
number: ( number: (
@ -45,7 +54,9 @@ export const HowItWorksTable = () => (
5 5
</span> </span>
), ),
step: 'The commission is taken from the infrastructure fee, maker fee, and liquidity provider fee, not from the referee', step: t(
'The commission is taken from the infrastructure fee, maker fee, and liquidity provider fee, not from the referee'
),
}, },
]} ]}
></Table> ></Table>

View File

@ -1,5 +1,6 @@
import classNames from 'classnames'; import classNames from 'classnames';
import { AnimatedDudeWithWire } from './graphics/dude'; import { AnimatedDudeWithWire } from './graphics/dude';
import { t } from '@vegaprotocol/i18n';
export const LandingBanner = () => { export const LandingBanner = () => {
return ( return (
@ -13,16 +14,17 @@ export const LandingBanner = () => {
</div> </div>
<div className="pt-32 sm:w-[50%]"> <div className="pt-32 sm:w-[50%]">
<h1 className="text-6xl font-alpha calt mb-10"> <h1 className="text-6xl font-alpha calt mb-10">
Earn commission & stake rewards {t('Earn commission & stake rewards')}
</h1> </h1>
<p className="text-lg mb-10"> <p className="text-lg mb-10">
Invite friends and earn commission in the form of Vega rewards from {t(
the trading fees they pay. Stake those rewards to earn multipliers 'Invite friends and earn commission in the form of Vega rewards from the trading fees they pay. Stake those rewards to earn multipliers on future rewards.'
on future rewards. )}
</p> </p>
<p className="text-lg"> <p className="text-lg">
Any friends that join using the code will receive discounts off {t(
trading fees. 'Any friends that join using the code will receive discounts off trading fees.'
)}
</p> </p>
</div> </div>
</div> </div>

View File

@ -26,6 +26,7 @@ import sortBy from 'lodash/sortBy';
import { useLayoutEffect, useRef, useState } from 'react'; import { useLayoutEffect, useRef, useState } from 'react';
import { useCurrentEpochInfoQuery } from './hooks/__generated__/Epoch'; import { useCurrentEpochInfoQuery } from './hooks/__generated__/Epoch';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { t } from '@vegaprotocol/i18n';
export const ReferralStatistics = () => { export const ReferralStatistics = () => {
const { pubKey } = useVegaWallet(); const { pubKey } = useVegaWallet();
@ -116,34 +117,34 @@ export const Statistics = ({
: 0; : 0;
const baseCommissionTile = ( const baseCommissionTile = (
<StatTile title="Base commission rate"> <StatTile title={t('Base commission rate')}>
{baseCommissionValue * 100}% {baseCommissionValue * 100}%
</StatTile> </StatTile>
); );
const stakingMultiplierTile = ( const stakingMultiplierTile = (
<StatTile <StatTile
title="Staking multiplier" title={t('Staking multiplier')}
description={`(${addDecimalsFormatNumber( description={`(${addDecimalsFormatNumber(
stakeAvailable?.toString() || 0, stakeAvailable?.toString() || 0,
18 18
)} $VEGA staked)`} )} $VEGA staked)`}
> >
{multiplier || 'None'} {multiplier || t('None')}
</StatTile> </StatTile>
); );
const finalCommissionTile = ( const finalCommissionTile = (
<StatTile title="Final commission rate"> <StatTile title={t('Final commission rate')}>
{finalCommissionValue * 100}% {finalCommissionValue * 100}%
</StatTile> </StatTile>
); );
const numberOfTradersValue = data.referees.length; const numberOfTradersValue = data.referees.length;
const numberOfTradersTile = ( const numberOfTradersTile = (
<StatTile title="Number of traders">{numberOfTradersValue}</StatTile> <StatTile title={t('Number of traders')}>{numberOfTradersValue}</StatTile>
); );
const codeTile = <CodeTile code={data?.code} />; const codeTile = <CodeTile code={data?.code} />;
const createdAtTile = ( const createdAtTile = (
<StatTile title="Created at"> <StatTile title={t('Created at')}>
<span className="text-3xl"> <span className="text-3xl">
{getDateFormat().format(new Date(data.createdAt))} {getDateFormat().format(new Date(data.createdAt))}
</span> </span>
@ -154,7 +155,10 @@ export const Statistics = ({
.map((r) => new BigNumber(r.totalRefereeGeneratedRewards)) .map((r) => new BigNumber(r.totalRefereeGeneratedRewards))
.reduce((all, r) => all.plus(r), new BigNumber(0)); .reduce((all, r) => all.plus(r), new BigNumber(0));
const totalCommissionTile = ( const totalCommissionTile = (
<StatTile title="Total commission (last 30 days)" description="(Quantum)"> <StatTile
title={t('Total commission (last 30 days)')}
description={t('(qUSD)')}
>
{getNumberFormat(0).format(Number(totalCommissionValue))} {getNumberFormat(0).format(Number(totalCommissionValue))}
</StatTile> </StatTile>
); );
@ -184,29 +188,31 @@ export const Statistics = ({
}); });
const currentBenefitTierTile = ( const currentBenefitTierTile = (
<StatTile title="Current tier"> <StatTile title={t('Current tier')}>
{currentBenefitTierValue?.tier || '-'} {currentBenefitTierValue?.tier || '-'}
</StatTile> </StatTile>
); );
const discountFactorTile = ( const discountFactorTile = (
<StatTile title="Discount">{discountFactorValue * 100}%</StatTile> <StatTile title={t('Discount')}>{discountFactorValue * 100}%</StatTile>
); );
const runningVolumeTile = ( const runningVolumeTile = (
<StatTile title="Combined volume"> <StatTile title={t('Combined volume')}>
{compactNumFormat.format(runningVolumeValue)} {compactNumFormat.format(runningVolumeValue)}
</StatTile> </StatTile>
); );
const epochsTile = <StatTile title="Epochs in set">{epochsValue}</StatTile>; const epochsTile = (
<StatTile title={t('Epochs in set')}>{epochsValue}</StatTile>
);
const nextTierVolumeTile = ( const nextTierVolumeTile = (
<StatTile title="Volume to next tier"> <StatTile title={t('Volume to next tier')}>
{nextBenefitTierVolumeValue <= 0 {nextBenefitTierVolumeValue <= 0
? '-' ? '0'
: compactNumFormat.format(nextBenefitTierVolumeValue)} : compactNumFormat.format(nextBenefitTierVolumeValue)}
</StatTile> </StatTile>
); );
const nextTierEpochsTile = ( const nextTierEpochsTile = (
<StatTile title="Epochs to next tier"> <StatTile title={t('Epochs to next tier')}>
{nextBenefitTierEpochsValue <= 0 ? '-' : nextBenefitTierEpochsValue} {nextBenefitTierEpochsValue <= 0 ? '0' : nextBenefitTierEpochsValue}
</StatTile> </StatTile>
); );
@ -249,7 +255,7 @@ export const Statistics = ({
{/* Referees (only for referrer view) */} {/* Referees (only for referrer view) */}
{as === 'referrer' && data.referees.length > 0 && ( {as === 'referrer' && data.referees.length > 0 && (
<div className="mt-20 mb-20"> <div className="mt-20 mb-20">
<h2 className="text-2xl mb-5">Referees</h2> <h2 className="text-2xl mb-5">{t('Referees')}</h2>
<div <div
className={classNames( className={classNames(
collapsed && [ collapsed && [
@ -273,12 +279,12 @@ export const Statistics = ({
<Table <Table
ref={tableRef} ref={tableRef}
columns={[ columns={[
{ name: 'party', displayName: 'Trader' }, { name: 'party', displayName: t('Trader') },
{ name: 'joined', displayName: 'Date Joined' }, { name: 'joined', displayName: t('Date Joined') },
{ name: 'volume', displayName: 'Volume (last 30 days)' }, { name: 'volume', displayName: t('Volume (last 30 days)') },
{ {
name: 'commission', name: 'commission',
displayName: 'Commission earned (last 30 days)', displayName: t('Commission earned (last 30 days)'),
}, },
]} ]}
data={sortBy( data={sortBy(

View File

@ -22,9 +22,9 @@ import { t } from '@vegaprotocol/i18n';
const Nav = () => ( const Nav = () => (
<div className="flex justify-center border-b border-vega-cdark-500"> <div className="flex justify-center border-b border-vega-cdark-500">
<TabLink end to={Routes.REFERRALS}> <TabLink end to={Routes.REFERRALS}>
I want a code {t('I want a code')}
</TabLink> </TabLink>
<TabLink to={Routes.REFERRALS_APPLY_CODE}>I have a code</TabLink> <TabLink to={Routes.REFERRALS_APPLY_CODE}>{t('I have a code')}</TabLink>
</div> </div>
); );
@ -77,7 +77,7 @@ export const Referrals = () => {
</div> </div>
) : error ? ( ) : error ? (
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-center"> <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-center">
<p>Something went wrong</p> <p>{t('Something went wrong')}</p>
<span className="text-xs">{error.message}</span> <span className="text-xs">{error.message}</span>
</div> </div>
) : ( ) : (
@ -88,7 +88,7 @@ export const Referrals = () => {
<TiersContainer /> <TiersContainer />
<div className="mt-10 mb-5 text-center"> <div className="mt-10 mb-5 text-center">
<h2 className="text-2xl">How it works</h2> <h2 className="text-2xl">{t('How it works')}</h2>
</div> </div>
<div className="md:w-[60%] mx-auto"> <div className="md:w-[60%] mx-auto">
<HowItWorksTable /> <HowItWorksTable />
@ -98,7 +98,8 @@ export const Referrals = () => {
href={REFERRAL_DOCS_LINK} href={REFERRAL_DOCS_LINK}
target="_blank" target="_blank"
> >
Read the terms <VegaIcon name={VegaIconNames.OPEN_EXTERNAL} /> {t('Read the terms')}{' '}
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
</TradingAnchorButton> </TradingAnchorButton>
</div> </div>
</div> </div>

View File

@ -7,6 +7,7 @@ import { Tag } from './tag';
import type { ComponentProps, ReactNode } from 'react'; import type { ComponentProps, ReactNode } from 'react';
import { ExternalLink } from '@vegaprotocol/ui-toolkit'; import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { DApp, TOKEN_PROPOSALS, useLinks } from '@vegaprotocol/environment'; import { DApp, TOKEN_PROPOSALS, useLinks } from '@vegaprotocol/environment';
import { t } from '@vegaprotocol/i18n';
const Loading = ({ variant }: { variant: 'large' | 'inline' }) => ( const Loading = ({ variant }: { variant: 'large' | 'inline' }) => (
<div <div
@ -61,7 +62,7 @@ const StakingTier = ({
<Tag color={color[tier]}>Multiplier {referralRewardMultiplier}x</Tag> <Tag color={color[tier]}>Multiplier {referralRewardMultiplier}x</Tag>
<h3 className="mt-1 mb-1 text-base">{label}</h3> <h3 className="mt-1 mb-1 text-base">{label}</h3>
<p className="text-sm text-vega-clight-100 dark:text-vega-cdark-100"> <p className="text-sm text-vega-clight-100 dark:text-vega-cdark-100">
Stake a minimum of {minimumStakedTokens} $VEGA tokens {t('Stake a minimum of')} {minimumStakedTokens} {t('$VEGA tokens')}
</p> </p>
</div> </div>
</div> </div>
@ -81,9 +82,12 @@ export const TiersContainer = () => {
if ((!loading && !details) || error) { if ((!loading && !details) || error) {
return ( return (
<div className="text-base px-5 py-10 text-center"> <div className="text-base px-5 py-10 text-center">
We&apos;re sorry but we don&apos;t have an active referral programme {t(
currently running. You can propose a new programme{' '} "We're sorry but we don't have an active referral programme currently running. You can propose a new programme"
<ExternalLink href={governanceLink(TOKEN_PROPOSALS)}>here</ExternalLink> )}{' '}
<ExternalLink href={governanceLink(TOKEN_PROPOSALS)}>
{t('here')}
</ExternalLink>
. .
</div> </div>
); );
@ -93,10 +97,10 @@ export const TiersContainer = () => {
<> <>
{/* Benefit tiers */} {/* Benefit tiers */}
<div className="flex flex-col items-baseline justify-between mt-10 mb-5"> <div className="flex flex-col items-baseline justify-between mt-10 mb-5">
<h2 className="text-2xl">Referral tiers</h2> <h2 className="text-2xl">{t('Referral tiers')}</h2>
{ends && ( {ends && (
<span className="text-sm text-vega-clight-200 dark:text-vega-cdark-200"> <span className="text-sm text-vega-clight-200 dark:text-vega-cdark-200">
Program ends: {ends} {t('Program ends:')} {ends}
</span> </span>
)} )}
</div> </div>
@ -119,7 +123,7 @@ export const TiersContainer = () => {
{/* Staking tiers */} {/* Staking tiers */}
<div className="flex flex-row items-baseline justify-between mb-5"> <div className="flex flex-row items-baseline justify-between mb-5">
<h2 className="text-2xl">Staking multipliers</h2> <h2 className="text-2xl">{t('Staking multipliers')}</h2>
</div> </div>
<div className="mb-20 flex flex-col justify-items-stretch lg:flex-row gap-5"> <div className="mb-20 flex flex-col justify-items-stretch lg:flex-row gap-5">
{loading || !stakingTiers || stakingTiers.length === 0 ? ( {loading || !stakingTiers || stakingTiers.length === 0 ? (
@ -170,15 +174,15 @@ const TiersTable = ({
return ( return (
<Table <Table
columns={[ columns={[
{ name: 'tierElement', displayName: 'Tier' }, { name: 'tierElement', displayName: t('Tier') },
{ {
name: 'commission', name: 'commission',
displayName: 'Referrer commission', displayName: t('Referrer commission'),
tooltip: 'A percentage of commission earned by the referrer', tooltip: t('A percentage of commission earned by the referrer'),
}, },
{ name: 'discount', displayName: 'Referrer trading discount' }, { name: 'discount', displayName: t('Referrer trading discount') },
{ name: 'volume', displayName: 'Min. trading volume' }, { name: 'volume', displayName: t('Min. trading volume') },
{ name: 'epochs', displayName: 'Min. epochs' }, { name: 'epochs', displayName: t('Min. epochs') },
]} ]}
data={data.map((d) => ({ data={data.map((d) => ({
...d, ...d,