Add translation infra and replace english text with calls to translate
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { WebsitePaths } from 'ts/types';
|
||||
import { Deco, Key, WebsitePaths } from 'ts/types';
|
||||
import { colors } from 'ts/utils/colors';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
import { Translate } from 'ts/utils/translate';
|
||||
|
||||
interface MenuItemsBySection {
|
||||
[sectionName: string]: FooterMenuItem[];
|
||||
@@ -15,86 +16,8 @@ interface FooterMenuItem {
|
||||
isExternal?: boolean;
|
||||
}
|
||||
|
||||
enum Sections {
|
||||
Documentation = 'Documentation',
|
||||
Community = 'Community',
|
||||
Organization = 'Organization',
|
||||
}
|
||||
|
||||
const ICON_DIMENSION = 16;
|
||||
const menuItemsBySection: MenuItemsBySection = {
|
||||
Documentation: [
|
||||
{
|
||||
title: '0x.js',
|
||||
path: WebsitePaths.ZeroExJs,
|
||||
},
|
||||
{
|
||||
title: '0x Smart Contracts',
|
||||
path: WebsitePaths.SmartContracts,
|
||||
},
|
||||
{
|
||||
title: '0x Connect',
|
||||
path: WebsitePaths.Connect,
|
||||
},
|
||||
{
|
||||
title: 'Whitepaper',
|
||||
path: WebsitePaths.Whitepaper,
|
||||
isExternal: true,
|
||||
},
|
||||
{
|
||||
title: 'Wiki',
|
||||
path: WebsitePaths.Wiki,
|
||||
},
|
||||
{
|
||||
title: 'FAQ',
|
||||
path: WebsitePaths.FAQ,
|
||||
},
|
||||
],
|
||||
Community: [
|
||||
{
|
||||
title: 'Rocket.chat',
|
||||
isExternal: true,
|
||||
path: constants.URL_ZEROEX_CHAT,
|
||||
},
|
||||
{
|
||||
title: 'Blog',
|
||||
isExternal: true,
|
||||
path: constants.URL_BLOG,
|
||||
},
|
||||
{
|
||||
title: 'Twitter',
|
||||
isExternal: true,
|
||||
path: constants.URL_TWITTER,
|
||||
},
|
||||
{
|
||||
title: 'Reddit',
|
||||
isExternal: true,
|
||||
path: constants.URL_REDDIT,
|
||||
},
|
||||
{
|
||||
title: 'Forum',
|
||||
isExternal: true,
|
||||
path: constants.URL_DISCOURSE_FORUM,
|
||||
},
|
||||
],
|
||||
Organization: [
|
||||
{
|
||||
title: 'About',
|
||||
isExternal: false,
|
||||
path: WebsitePaths.About,
|
||||
},
|
||||
{
|
||||
title: 'Careers',
|
||||
isExternal: true,
|
||||
path: constants.URL_ANGELLIST,
|
||||
},
|
||||
{
|
||||
title: 'Contact',
|
||||
isExternal: true,
|
||||
path: 'mailto:team@0xproject.com',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const linkStyle = {
|
||||
color: colors.white,
|
||||
cursor: 'pointer',
|
||||
@@ -108,12 +31,90 @@ const titleToIcon: { [title: string]: string } = {
|
||||
Forum: 'discourse.png',
|
||||
};
|
||||
|
||||
export interface FooterProps {}
|
||||
export interface FooterProps {
|
||||
translate?: Translate;
|
||||
}
|
||||
|
||||
interface FooterState {}
|
||||
|
||||
export class Footer extends React.Component<FooterProps, FooterState> {
|
||||
public static defaultProps: Partial<FooterProps> = {
|
||||
translate: new Translate(),
|
||||
};
|
||||
public render() {
|
||||
const menuItemsBySection: MenuItemsBySection = {
|
||||
[Key.Documentation]: [
|
||||
{
|
||||
title: '0x.js',
|
||||
path: WebsitePaths.ZeroExJs,
|
||||
},
|
||||
{
|
||||
title: this.props.translate.get(Key.SmartContracts, Deco.Cap),
|
||||
path: WebsitePaths.SmartContracts,
|
||||
},
|
||||
{
|
||||
title: this.props.translate.get(Key.Connect, Deco.Cap),
|
||||
path: WebsitePaths.Connect,
|
||||
},
|
||||
{
|
||||
title: this.props.translate.get(Key.Whitepaper, Deco.Cap),
|
||||
path: WebsitePaths.Whitepaper,
|
||||
isExternal: true,
|
||||
},
|
||||
{
|
||||
title: this.props.translate.get(Key.Wiki, Deco.Cap),
|
||||
path: WebsitePaths.Wiki,
|
||||
},
|
||||
{
|
||||
title: this.props.translate.get(Key.FAQ, Deco.Cap),
|
||||
path: WebsitePaths.FAQ,
|
||||
},
|
||||
],
|
||||
[Key.Community]: [
|
||||
{
|
||||
title: this.props.translate.get(Key.RocketChat, Deco.Cap),
|
||||
isExternal: true,
|
||||
path: constants.URL_ZEROEX_CHAT,
|
||||
},
|
||||
{
|
||||
title: this.props.translate.get(Key.Blog, Deco.Cap),
|
||||
isExternal: true,
|
||||
path: constants.URL_BLOG,
|
||||
},
|
||||
{
|
||||
title: 'Twitter',
|
||||
isExternal: true,
|
||||
path: constants.URL_TWITTER,
|
||||
},
|
||||
{
|
||||
title: 'Reddit',
|
||||
isExternal: true,
|
||||
path: constants.URL_REDDIT,
|
||||
},
|
||||
{
|
||||
title: this.props.translate.get(Key.Forum, Deco.Cap),
|
||||
isExternal: true,
|
||||
path: constants.URL_DISCOURSE_FORUM,
|
||||
},
|
||||
],
|
||||
[Key.Organization]: [
|
||||
{
|
||||
title: this.props.translate.get(Key.About, Deco.Cap),
|
||||
isExternal: false,
|
||||
path: WebsitePaths.About,
|
||||
},
|
||||
{
|
||||
title: this.props.translate.get(Key.Careers, Deco.Cap),
|
||||
isExternal: true,
|
||||
path: constants.URL_ANGELLIST,
|
||||
},
|
||||
{
|
||||
title: this.props.translate.get(Key.Contact, Deco.Cap),
|
||||
isExternal: true,
|
||||
path: 'mailto:team@0xproject.com',
|
||||
},
|
||||
],
|
||||
};
|
||||
return (
|
||||
<div className="relative pb4 pt2" style={{ backgroundColor: colors.darkerGrey }}>
|
||||
<div className="mx-auto max-width-4 md-px2 lg-px0 py4 clearfix" style={{ color: colors.white }}>
|
||||
@@ -137,20 +138,20 @@ export class Footer extends React.Component<FooterProps, FooterState> {
|
||||
<div className="col lg-col-8 md-col-8 col-12 lg-pl4 md-pl4">
|
||||
<div className="col lg-col-4 md-col-4 col-12">
|
||||
<div className="lg-right md-right sm-center">
|
||||
{this._renderHeader(Sections.Documentation)}
|
||||
{_.map(menuItemsBySection[Sections.Documentation], this._renderMenuItem.bind(this))}
|
||||
{this._renderHeader(Key.Documentation)}
|
||||
{_.map(menuItemsBySection[Key.Documentation], this._renderMenuItem.bind(this))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="col lg-col-4 md-col-4 col-12 lg-pr2 md-pr2">
|
||||
<div className="lg-right md-right sm-center">
|
||||
{this._renderHeader(Sections.Community)}
|
||||
{_.map(menuItemsBySection[Sections.Community], this._renderMenuItem.bind(this))}
|
||||
{this._renderHeader(Key.Community)}
|
||||
{_.map(menuItemsBySection[Key.Community], this._renderMenuItem.bind(this))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="col lg-col-4 md-col-4 col-12">
|
||||
<div className="lg-right md-right sm-center">
|
||||
{this._renderHeader(Sections.Organization)}
|
||||
{_.map(menuItemsBySection[Sections.Organization], this._renderMenuItem.bind(this))}
|
||||
{this._renderHeader(Key.Organization)}
|
||||
{_.map(menuItemsBySection[Key.Organization], this._renderMenuItem.bind(this))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -195,9 +196,8 @@ export class Footer extends React.Component<FooterProps, FooterState> {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private _renderHeader(title: string) {
|
||||
private _renderHeader(key: Key) {
|
||||
const headerStyle = {
|
||||
textTransform: 'uppercase',
|
||||
color: colors.grey400,
|
||||
letterSpacing: 2,
|
||||
fontFamily: 'Roboto Mono',
|
||||
@@ -205,7 +205,7 @@ export class Footer extends React.Component<FooterProps, FooterState> {
|
||||
};
|
||||
return (
|
||||
<div className="lg-pb2 md-pb2 sm-pt4" style={headerStyle}>
|
||||
{title}
|
||||
{this.props.translate.get(key, Deco.Upper)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,9 +14,10 @@ import { Identicon } from 'ts/components/ui/identicon';
|
||||
import { DocsInfo } from 'ts/pages/documentation/docs_info';
|
||||
import { NestedSidebarMenu } from 'ts/pages/shared/nested_sidebar_menu';
|
||||
import { Dispatcher } from 'ts/redux/dispatcher';
|
||||
import { DocsMenu, MenuSubsectionsBySection, ProviderType, Styles, WebsitePaths } from 'ts/types';
|
||||
import { Deco, DocsMenu, Key, MenuSubsectionsBySection, ProviderType, Styles, WebsitePaths } from 'ts/types';
|
||||
import { colors } from 'ts/utils/colors';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
import { Translate } from 'ts/utils/translate';
|
||||
|
||||
interface TopBarProps {
|
||||
userAddress?: string;
|
||||
@@ -36,6 +37,7 @@ interface TopBarProps {
|
||||
docsInfo?: DocsInfo;
|
||||
style?: React.CSSProperties;
|
||||
isNightVersion?: boolean;
|
||||
translate?: Translate;
|
||||
}
|
||||
|
||||
interface TopBarState {
|
||||
@@ -79,6 +81,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
shouldFullWidth: false,
|
||||
style: {},
|
||||
isNightVersion: false,
|
||||
translate: new Translate(),
|
||||
};
|
||||
constructor(props: TopBarProps) {
|
||||
super(props);
|
||||
@@ -95,10 +98,16 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x.js" />
|
||||
</Link>,
|
||||
<Link key="subMenuItem-smartContracts" to={WebsitePaths.SmartContracts} className="text-decoration-none">
|
||||
<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Smart Contracts" />
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.SmartContract, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<Link key="subMenuItem-0xconnect" to={WebsitePaths.Connect} className="text-decoration-none">
|
||||
<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x Connect" />
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.Connect, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<a
|
||||
key="subMenuItem-standard-relayer-api"
|
||||
@@ -106,7 +115,10 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
className="text-decoration-none"
|
||||
href={constants.URL_STANDARD_RELAYER_API_GITHUB}
|
||||
>
|
||||
<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Standard Relayer API" />
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.StandardRelayerApi, Deco.CapWords)}
|
||||
/>
|
||||
</a>,
|
||||
<a
|
||||
key="subMenuItem-github"
|
||||
@@ -122,7 +134,10 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
className="text-decoration-none"
|
||||
href={`${WebsitePaths.Whitepaper}`}
|
||||
>
|
||||
<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="Whitepaper" />
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.Whitepaper, Deco.CapWords)}
|
||||
/>
|
||||
</a>,
|
||||
];
|
||||
const bottomBorderStyle = this._shouldDisplayBottomBar() ? styles.bottomBar : {};
|
||||
@@ -165,28 +180,28 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
style={styles.menuItem}
|
||||
/>
|
||||
<TopBarMenuItem
|
||||
title="Wiki"
|
||||
title={this.props.translate.get(Key.Wiki, Deco.Cap)}
|
||||
path={`${WebsitePaths.Wiki}`}
|
||||
style={styles.menuItem}
|
||||
isNightVersion={isNightVersion}
|
||||
isExternal={false}
|
||||
/>
|
||||
<TopBarMenuItem
|
||||
title="Blog"
|
||||
title={this.props.translate.get(Key.Blog, Deco.Cap)}
|
||||
path={constants.URL_BLOG}
|
||||
style={styles.menuItem}
|
||||
isNightVersion={isNightVersion}
|
||||
isExternal={true}
|
||||
/>
|
||||
<TopBarMenuItem
|
||||
title="About"
|
||||
title={this.props.translate.get(Key.About, Deco.Cap)}
|
||||
path={`${WebsitePaths.About}`}
|
||||
style={styles.menuItem}
|
||||
isNightVersion={isNightVersion}
|
||||
isExternal={false}
|
||||
/>
|
||||
<TopBarMenuItem
|
||||
title="Portal DApp"
|
||||
title={this.props.translate.get(Key.PortalDApp, Deco.CapWords)}
|
||||
path={`${WebsitePaths.Portal}`}
|
||||
isPrimary={true}
|
||||
style={styles.menuItem}
|
||||
@@ -233,46 +248,54 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
{this._renderDocsMenu()}
|
||||
{this._renderWiki()}
|
||||
<div className="pl1 py1 mt3" style={{ backgroundColor: colors.lightGrey }}>
|
||||
Website
|
||||
{this.props.translate.get(Key.Website, Deco.Cap)}
|
||||
</div>
|
||||
<Link to={WebsitePaths.Home} className="text-decoration-none">
|
||||
<MenuItem className="py2">Home</MenuItem>
|
||||
<MenuItem className="py2">{this.props.translate.get(Key.Home, Deco.Cap)}</MenuItem>
|
||||
</Link>
|
||||
<Link to={`${WebsitePaths.Wiki}`} className="text-decoration-none">
|
||||
<MenuItem className="py2">Wiki</MenuItem>
|
||||
<MenuItem className="py2">{this.props.translate.get(Key.Wiki, Deco.Cap)}</MenuItem>
|
||||
</Link>
|
||||
{!this._isViewing0xjsDocs() && (
|
||||
<Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
|
||||
<MenuItem className="py2">0x.js Docs</MenuItem>
|
||||
<MenuItem className="py2">0x.js {this.props.translate.get(Key.Docs, Deco.Cap)}</MenuItem>
|
||||
</Link>
|
||||
)}
|
||||
{!this._isViewingConnectDocs() && (
|
||||
<Link to={WebsitePaths.Connect} className="text-decoration-none">
|
||||
<MenuItem className="py2">0x Connect Docs</MenuItem>
|
||||
<MenuItem className="py2">
|
||||
{this.props.translate.get(Key.Connect, Deco.Cap)}{' '}
|
||||
{this.props.translate.get(Key.Docs, Deco.Cap)}
|
||||
</MenuItem>
|
||||
</Link>
|
||||
)}
|
||||
{!this._isViewingSmartContractsDocs() && (
|
||||
<Link to={WebsitePaths.SmartContracts} className="text-decoration-none">
|
||||
<MenuItem className="py2">Smart Contract Docs</MenuItem>
|
||||
<MenuItem className="py2">
|
||||
{this.props.translate.get(Key.SmartContract, Deco.Cap)}{' '}
|
||||
{this.props.translate.get(Key.Docs, Deco.Cap)}
|
||||
</MenuItem>
|
||||
</Link>
|
||||
)}
|
||||
{!this._isViewingPortal() && (
|
||||
<Link to={`${WebsitePaths.Portal}`} className="text-decoration-none">
|
||||
<MenuItem className="py2">Portal DApp</MenuItem>
|
||||
<MenuItem className="py2">
|
||||
{this.props.translate.get(Key.PortalDApp, Deco.CapWords)}
|
||||
</MenuItem>
|
||||
</Link>
|
||||
)}
|
||||
<a className="text-decoration-none" target="_blank" href={`${WebsitePaths.Whitepaper}`}>
|
||||
<MenuItem className="py2">Whitepaper</MenuItem>
|
||||
<MenuItem className="py2">{this.props.translate.get(Key.Whitepaper, Deco.Cap)}</MenuItem>
|
||||
</a>
|
||||
<Link to={`${WebsitePaths.About}`} className="text-decoration-none">
|
||||
<MenuItem className="py2">About</MenuItem>
|
||||
<MenuItem className="py2">{this.props.translate.get(Key.About, Deco.Cap)}</MenuItem>
|
||||
</Link>
|
||||
<a className="text-decoration-none" target="_blank" href={constants.URL_BLOG}>
|
||||
<MenuItem className="py2">Blog</MenuItem>
|
||||
<MenuItem className="py2">{this.props.translate.get(Key.Blog, Deco.Cap)}</MenuItem>
|
||||
</a>
|
||||
<Link to={`${WebsitePaths.FAQ}`} className="text-decoration-none">
|
||||
<MenuItem className="py2" onTouchTap={this._onMenuButtonClick.bind(this)}>
|
||||
FAQ
|
||||
{this.props.translate.get(Key.FAQ, Deco.Cap)}
|
||||
</MenuItem>
|
||||
</Link>
|
||||
</div>
|
||||
@@ -313,7 +336,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
<NestedSidebarMenu
|
||||
topLevelMenu={this.props.menuSubsectionsBySection}
|
||||
menuSubsectionsBySection={this.props.menuSubsectionsBySection}
|
||||
title="Wiki"
|
||||
title={this.props.translate.get(Key.Wiki, Deco.Cap)}
|
||||
shouldDisplaySectionHeaders={false}
|
||||
onMenuItemClick={this._onMenuButtonClick.bind(this)}
|
||||
/>
|
||||
@@ -328,7 +351,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
return (
|
||||
<div className="lg-hide md-hide">
|
||||
<div className="pl1 py1" style={{ backgroundColor: colors.lightGrey }}>
|
||||
Portal DApp
|
||||
{this.props.translate.get(Key.PortalDApp, Deco.CapWords)}
|
||||
</div>
|
||||
<PortalMenu menuItemStyle={{ color: 'black' }} onClick={this._onMenuButtonClick.bind(this)} />
|
||||
</div>
|
||||
|
||||
@@ -5,9 +5,10 @@ import DocumentTitle = require('react-document-title');
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Footer } from 'ts/components/footer';
|
||||
import { TopBar } from 'ts/components/top_bar/top_bar';
|
||||
import { ScreenWidths, WebsitePaths } from 'ts/types';
|
||||
import { Deco, Key, ScreenWidths, WebsitePaths } from 'ts/types';
|
||||
import { colors } from 'ts/utils/colors';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
import { Translate } from 'ts/utils/translate';
|
||||
import { utils } from 'ts/utils/utils';
|
||||
|
||||
interface BoxContent {
|
||||
@@ -36,35 +37,6 @@ interface Project {
|
||||
|
||||
const THROTTLE_TIMEOUT = 100;
|
||||
|
||||
const boxContents: BoxContent[] = [
|
||||
{
|
||||
title: 'Trustless exchange',
|
||||
description:
|
||||
"Built on Ethereum's distributed network with no centralized \
|
||||
point of failure and no down time, each trade is settled atomically \
|
||||
and without counterparty risk.",
|
||||
imageUrl: '/images/landing/distributed_network.png',
|
||||
classNames: '',
|
||||
},
|
||||
{
|
||||
title: 'Shared liquidity',
|
||||
description:
|
||||
'By sharing a standard API, relayers can easily aggregate liquidity pools, \
|
||||
creating network effects around liquidity that compound as more relayers come online.',
|
||||
imageUrl: '/images/landing/liquidity.png',
|
||||
classNames: 'mx-auto',
|
||||
},
|
||||
{
|
||||
title: 'Open source',
|
||||
description:
|
||||
'0x is open source, permissionless and free to use. Trade directly with a known \
|
||||
counterparty for free or pay a relayer some ZRX tokens to access their liquidity \
|
||||
pool.',
|
||||
imageUrl: '/images/landing/open_source.png',
|
||||
classNames: 'right',
|
||||
},
|
||||
];
|
||||
|
||||
const relayersAndDappProjects: Project[] = [
|
||||
{
|
||||
logoFileName: 'ethfinex.png',
|
||||
@@ -185,6 +157,7 @@ const relayerProjects: Project[] = [
|
||||
|
||||
export interface LandingProps {
|
||||
location: Location;
|
||||
translate: Translate;
|
||||
}
|
||||
|
||||
interface LandingState {
|
||||
@@ -193,11 +166,13 @@ interface LandingState {
|
||||
|
||||
export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
private _throttledScreenWidthUpdate: () => void;
|
||||
private _translate: Translate;
|
||||
constructor(props: LandingProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
screenWidth: utils.getScreenWidth(),
|
||||
};
|
||||
this._translate = new Translate();
|
||||
this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
|
||||
}
|
||||
public componentDidMount() {
|
||||
@@ -216,17 +191,28 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
location={this.props.location}
|
||||
isNightVersion={true}
|
||||
style={{ backgroundColor: colors.heroGrey, position: 'relative' }}
|
||||
translate={this._translate}
|
||||
/>
|
||||
{this._renderHero()}
|
||||
{this._renderProjects(relayersAndDappProjects, 'Projects building on 0x', colors.projectsGrey, false)}
|
||||
{this._renderProjects(
|
||||
relayersAndDappProjects,
|
||||
this._translate.get(Key.ProjectsHeader, Deco.Upper),
|
||||
colors.projectsGrey,
|
||||
false,
|
||||
)}
|
||||
{this._renderTokenizationSection()}
|
||||
{this._renderProtocolSection()}
|
||||
{this._renderProjects(relayerProjects, 'Relayers building on 0x', colors.heroGrey, true)}
|
||||
{this._renderProjects(
|
||||
relayerProjects,
|
||||
this._translate.get(Key.RelayersHeader, Deco.Upper),
|
||||
colors.heroGrey,
|
||||
true,
|
||||
)}
|
||||
{this._renderInfoBoxes()}
|
||||
{this._renderBuildingBlocksSection()}
|
||||
{this._renderUseCases()}
|
||||
{this._renderCallToAction()}
|
||||
<Footer />
|
||||
<Footer translate={this._translate} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -260,7 +246,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
fontSize: isSmallScreen ? 26 : 34,
|
||||
}}
|
||||
>
|
||||
Powering decentralized exchange
|
||||
{this._translate.get(Key.TopHeader, Deco.Cap)}
|
||||
</div>
|
||||
<div
|
||||
className="pt2 h5 sm-mx-auto"
|
||||
@@ -271,8 +257,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
fontWeight: 300,
|
||||
}}
|
||||
>
|
||||
0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the
|
||||
Ethereum blockchain.
|
||||
{this._translate.get(Key.TopTagline)}
|
||||
</div>
|
||||
<div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 342 }}>
|
||||
<div className="lg-pr2 md-pr2 col col-6 sm-center">
|
||||
@@ -281,7 +266,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
style={{ borderRadius: 6, minWidth: 157.36 }}
|
||||
buttonStyle={{ borderRadius: 6 }}
|
||||
labelStyle={buttonLabelStyle}
|
||||
label="Build on 0x"
|
||||
label={this._translate.get(Key.BuildCallToAction, Deco.Cap)}
|
||||
onClick={_.noop}
|
||||
/>
|
||||
</Link>
|
||||
@@ -298,7 +283,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
labelColor="white"
|
||||
backgroundColor={colors.heroGrey}
|
||||
labelStyle={buttonLabelStyle}
|
||||
label="Join the community"
|
||||
label={this._translate.get(Key.CommunityCallToAction, Deco.Cap)}
|
||||
onClick={_.noop}
|
||||
/>
|
||||
</a>
|
||||
@@ -346,7 +331,6 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
const titleStyle: React.CSSProperties = {
|
||||
fontFamily: 'Roboto Mono',
|
||||
color: colors.grey,
|
||||
textTransform: 'uppercase',
|
||||
fontWeight: 300,
|
||||
letterSpacing: 3,
|
||||
};
|
||||
@@ -366,13 +350,13 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
fontSize: 14,
|
||||
}}
|
||||
>
|
||||
view the{' '}
|
||||
{this._translate.get(Key.FullListPrompt)}{' '}
|
||||
<Link
|
||||
to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
|
||||
className="text-decoration-none underline"
|
||||
style={{ color: colors.landingLinkGrey }}
|
||||
>
|
||||
full list
|
||||
{this._translate.get(Key.FullListLink)}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -388,30 +372,13 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
<div className="col lg-col-6 md-col-6 col-12" style={{ color: colors.darkestGrey }}>
|
||||
<div className="mx-auto" style={{ maxWidth: 385, paddingTop: 7 }}>
|
||||
<div className="lg-h1 md-h1 sm-h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}>
|
||||
The world's value is becoming tokenized
|
||||
{this._translate.get(Key.TokenizedSectionHeader, Deco.Cap)}
|
||||
</div>
|
||||
<div
|
||||
className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 h5 sm-center"
|
||||
style={{ fontFamily: 'Roboto Mono', lineHeight: 1.7 }}
|
||||
style={{ fontFamily: 'Roboto Mono', lineHeight: 1.7, maxWidth: 370 }}
|
||||
>
|
||||
{isSmallScreen ? (
|
||||
<span>
|
||||
The Ethereum blockchain is an open, borderless financial system that represents
|
||||
a wide variety of assets as cryptographic tokens. In the future, most digital
|
||||
assets and goods will be tokenized.
|
||||
</span>
|
||||
) : (
|
||||
<div>
|
||||
<div>
|
||||
The Ethereum blockchain is an open, borderless financial system that
|
||||
represents
|
||||
</div>
|
||||
<div>
|
||||
a wide variety of assets as cryptographic tokens. In the future, most
|
||||
digital assets and goods will be tokenized.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{this._translate.get(Key.TokenizedSectionDescription, Deco.Cap)}
|
||||
</div>
|
||||
<div className="flex pt1 sm-px3">{this._renderAssetTypes()}</div>
|
||||
</div>
|
||||
@@ -437,8 +404,8 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
}}
|
||||
>
|
||||
<div className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center" style={{ fontFamily: 'Roboto Mono' }}>
|
||||
<div>Off-chain order relay</div>
|
||||
<div>On-chain settlement</div>
|
||||
<div>{this._translate.get(Key.OffChainOrderRelay, Deco.Cap)}</div>
|
||||
<div> {this._translate.get(Key.OonChainSettlement, Deco.Cap)}</div>
|
||||
</div>
|
||||
<div
|
||||
className="pb2 pt2 h5 sm-center sm-px3 sm-mx-auto"
|
||||
@@ -449,9 +416,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
maxWidth: 445,
|
||||
}}
|
||||
>
|
||||
In 0x protocol, orders are transported off-chain, massively reducing gas costs and
|
||||
eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time
|
||||
they facilitate a trade. Anyone can build a relayer.
|
||||
{this._translate.get(Key.OffChainOnChainDescription, Deco.Cap)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -485,15 +450,13 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
className="pb1 lg-pt4 md-pt4 sm-pt3 lg-h1 md-h1 sm-h2 sm-px3 sm-center"
|
||||
style={{ fontFamily: 'Roboto Mono' }}
|
||||
>
|
||||
A building block for dApps
|
||||
{this._translate.get(Key.BuildingBlockSectionHeader, Deco.Cap)}
|
||||
</div>
|
||||
<div className="pb3 pt2 sm-mx-auto sm-center" style={descriptionStyle}>
|
||||
0x protocol is a pluggable building block for dApps that require exchange functionality.
|
||||
Join the many developers that are already using 0x in their web applications and smart
|
||||
contracts.
|
||||
{this._translate.get(Key.BuildingBlockSectionDescription, Deco.Cap)}
|
||||
</div>
|
||||
<div className="sm-mx-auto sm-center" style={callToActionStyle}>
|
||||
Learn how in our{' '}
|
||||
{this._translate.get(Key.DevToolsPrompt, Deco.Cap)}{' '}
|
||||
<Link
|
||||
to={WebsitePaths.ZeroExJs}
|
||||
className="text-decoration-none underline"
|
||||
@@ -507,9 +470,9 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
className="text-decoration-none underline"
|
||||
style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
|
||||
>
|
||||
smart contract
|
||||
{this._translate.get(Key.SmartContract)}
|
||||
</Link>{' '}
|
||||
docs
|
||||
{this._translate.get(Key.Docs)}
|
||||
</div>
|
||||
</div>
|
||||
{!isSmallScreen && this._renderBlockChipImage()}
|
||||
@@ -537,11 +500,11 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
|
||||
const assetTypes: AssetType[] = [
|
||||
{
|
||||
title: 'Currency',
|
||||
title: this._translate.get(Key.Currency, Deco.Cap),
|
||||
imageUrl: '/images/landing/currency.png',
|
||||
},
|
||||
{
|
||||
title: 'Traditional assets',
|
||||
title: this._translate.get(Key.TraditionalAssets, Deco.Cap),
|
||||
imageUrl: '/images/landing/stocks.png',
|
||||
style: {
|
||||
paddingLeft: isSmallScreen ? 41 : 56,
|
||||
@@ -549,7 +512,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Digital goods',
|
||||
title: this._translate.get(Key.DigitalGoods, Deco.Cap),
|
||||
imageUrl: '/images/landing/digital_goods.png',
|
||||
},
|
||||
];
|
||||
@@ -584,6 +547,26 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
borderRadius: 5,
|
||||
padding: '10px 24px 24px',
|
||||
};
|
||||
const boxContents: BoxContent[] = [
|
||||
{
|
||||
title: this._translate.get(Key.BenefitOneTitle, Deco.Cap),
|
||||
description: this._translate.get(Key.BenefitOneDescription, Deco.Cap),
|
||||
imageUrl: '/images/landing/distributed_network.png',
|
||||
classNames: '',
|
||||
},
|
||||
{
|
||||
title: this._translate.get(Key.BenefitTwoTitle, Deco.Cap),
|
||||
description: this._translate.get(Key.BenefitTwoDescription, Deco.Cap),
|
||||
imageUrl: '/images/landing/liquidity.png',
|
||||
classNames: 'mx-auto',
|
||||
},
|
||||
{
|
||||
title: this._translate.get(Key.BenefitThreeTitle, Deco.Cap),
|
||||
description: this._translate.get(Key.BenefitThreeDescription, Deco.Cap),
|
||||
imageUrl: '/images/landing/open_source.png',
|
||||
classNames: 'right',
|
||||
},
|
||||
];
|
||||
const boxes = _.map(boxContents, (boxContent: BoxContent) => {
|
||||
return (
|
||||
<div key={`box-${boxContent.title}`} className="col lg-col-4 md-col-4 col-12 sm-pb4">
|
||||
@@ -604,14 +587,13 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
const titleStyle: React.CSSProperties = {
|
||||
fontFamily: 'Roboto Mono',
|
||||
color: colors.grey,
|
||||
textTransform: 'uppercase',
|
||||
fontWeight: 300,
|
||||
letterSpacing: 3,
|
||||
};
|
||||
return (
|
||||
<div className="clearfix" style={{ backgroundColor: colors.heroGrey }}>
|
||||
<div className="center pb3 pt4" style={titleStyle}>
|
||||
Benefits of 0x
|
||||
{this._translate.get(Key.BenefitsHeader, Deco.Upper)}
|
||||
</div>
|
||||
<div className="mx-auto pb4 sm-mt2 clearfix" style={{ maxWidth: '60em' }}>
|
||||
{boxes}
|
||||
@@ -625,41 +607,29 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
const useCases: UseCase[] = [
|
||||
{
|
||||
imageUrl: '/images/landing/governance_icon.png',
|
||||
type: 'Decentralized governance',
|
||||
description:
|
||||
'Decentralized organizations use tokens to represent ownership and \
|
||||
guide their governance logic. 0x allows decentralized organizations \
|
||||
to seamlessly and safely trade ownership for startup capital.',
|
||||
type: this._translate.get(Key.DecentralizedGovernance, Deco.Upper),
|
||||
description: this._translate.get(Key.DecentralizedGovernanceDescription, Deco.Cap),
|
||||
projectIconUrls: ['/images/landing/aragon.png'],
|
||||
classNames: 'lg-px2 md-px2',
|
||||
},
|
||||
{
|
||||
imageUrl: '/images/landing/prediction_market_icon.png',
|
||||
type: 'Prediction markets',
|
||||
description:
|
||||
'Decentralized prediction market platforms generate sets of tokens that \
|
||||
represent a financial stake in the outcomes of real-world events. 0x allows \
|
||||
these tokens to be instantly tradable.',
|
||||
type: this._translate.get(Key.PredictionMarkets, Deco.Upper),
|
||||
description: this._translate.get(Key.PredictionMarketsDescription, Deco.Cap),
|
||||
projectIconUrls: ['/images/landing/augur.png'],
|
||||
classNames: 'lg-px2 md-px2',
|
||||
},
|
||||
{
|
||||
imageUrl: '/images/landing/stable_tokens_icon.png',
|
||||
type: 'Stable tokens',
|
||||
description:
|
||||
'Novel economic constructs such as stable coins require efficient, liquid \
|
||||
markets to succeed. 0x will facilitate the underlying economic mechanisms \
|
||||
that allow these tokens to remain stable.',
|
||||
type: this._translate.get(Key.StableTokens, Deco.Upper),
|
||||
description: this._translate.get(Key.StableTokensDescription, Deco.Cap),
|
||||
projectIconUrls: ['/images/landing/maker.png'],
|
||||
classNames: 'lg-px2 md-px2',
|
||||
},
|
||||
{
|
||||
imageUrl: '/images/landing/loans_icon.png',
|
||||
type: 'Decentralized loans',
|
||||
description:
|
||||
'Efficient lending requires liquid markets where investors can buy and re-sell loans. \
|
||||
0x enables an ecosystem of lenders to self-organize and efficiently determine \
|
||||
market prices for all outstanding loans.',
|
||||
type: this._translate.get(Key.DecentralizedLoans, Deco.Upper),
|
||||
description: this._translate.get(Key.DecentralizedLoansDescription, Deco.Cap),
|
||||
projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'],
|
||||
classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6',
|
||||
style: {
|
||||
@@ -670,11 +640,8 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
},
|
||||
{
|
||||
imageUrl: '/images/landing/fund_management_icon.png',
|
||||
type: 'Fund management',
|
||||
description:
|
||||
'Decentralized fund management limits fund managers to investing in pre-agreed \
|
||||
upon asset classes. Embedding 0x into fund management smart contracts enables \
|
||||
them to enforce these security constraints.',
|
||||
type: this._translate.get(Key.FundManagement, Deco.Upper),
|
||||
description: this._translate.get(Key.FundManagementDescription, Deco.Cap),
|
||||
projectIconUrls: ['/images/landing/melonport.png'],
|
||||
classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6',
|
||||
style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 },
|
||||
@@ -685,7 +652,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style;
|
||||
const useCaseBoxStyle = {
|
||||
color: colors.grey,
|
||||
border: '1px solid #565656',
|
||||
border: `1px solid ${colors.grey750}`,
|
||||
borderRadius: 4,
|
||||
maxWidth: isSmallScreen ? 375 : 'none',
|
||||
...style,
|
||||
@@ -741,7 +708,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
};
|
||||
const lightButtonStyle: React.CSSProperties = {
|
||||
borderRadius: 6,
|
||||
border: '1px solid #a0a0a0',
|
||||
border: `1px solid ${colors.grey500}`,
|
||||
lineHeight: '33px',
|
||||
height: 49,
|
||||
};
|
||||
@@ -759,7 +726,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
lineHeight: isSmallScreen ? 1.7 : 3,
|
||||
}}
|
||||
>
|
||||
Get started on building the decentralized future
|
||||
{this._translate.get(Key.FinalCallToAction, Deco.Cap)}
|
||||
</div>
|
||||
<div className="col lg-col-4 md-col-4 col-12 sm-center sm-pt2">
|
||||
<Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
|
||||
@@ -769,7 +736,7 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
labelColor={colors.white}
|
||||
backgroundColor={colors.heroGrey}
|
||||
labelStyle={buttonLabelStyle}
|
||||
label="Build on 0x"
|
||||
label={this._translate.get(Key.BuildCallToAction, Deco.Cap)}
|
||||
onClick={_.noop}
|
||||
/>
|
||||
</Link>
|
||||
|
||||
78
packages/website/ts/translations/english.ts
Normal file
78
packages/website/ts/translations/english.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { Key } from 'ts/types';
|
||||
|
||||
export const english = {
|
||||
// Landing Page
|
||||
[Key.TopHeader]: 'powering decentralized exchange',
|
||||
[Key.TopTagline]:
|
||||
'0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the Ethereum blockchain.',
|
||||
[Key.BuildCallToAction]: 'build on 0x',
|
||||
[Key.CommunityCallToAction]: 'join the community',
|
||||
[Key.ProjectsHeader]: 'projects building on 0x',
|
||||
[Key.FullListPrompt]: 'view the',
|
||||
[Key.FullListLink]: 'full list',
|
||||
[Key.TokenizedSectionHeader]: "the world's value is becoming tokenized",
|
||||
[Key.TokenizedSectionDescription]:
|
||||
'the Ethereum blockchain is an open, borderless financial system that represents a wide variety of assets as cryptographic tokens. In the future, most digital assets and goods will be tokenized.',
|
||||
[Key.Currency]: 'currency',
|
||||
[Key.TraditionalAssets]: 'traditional assets',
|
||||
[Key.DigitalGoods]: 'digital goods',
|
||||
[Key.OffChainOrderRelay]: 'off-chain order relay',
|
||||
[Key.OonChainSettlement]: 'on-chain settlement',
|
||||
[Key.OffChainOnChainDescription]:
|
||||
'in 0x protocol, orders are transported off-chain, massively reducing gas costs and eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time they facilitate a trade. Anyone can build a relayer.',
|
||||
[Key.RelayersHeader]: 'relayers building on 0x',
|
||||
[Key.BenefitsHeader]: 'benefits of 0x',
|
||||
[Key.BenefitOneTitle]: 'trustless exchange',
|
||||
[Key.BenefitOneDescription]:
|
||||
"built on Ethereum's distributed network with no centralized point of failure and no down time, each trade is settled atomically and without counterparty risk.",
|
||||
[Key.BenefitTwoTitle]: 'shared liquidity',
|
||||
[Key.BenefitTwoDescription]:
|
||||
'by sharing a standard API, relayers can easily aggregate liquidity pools, creating network effects around liquidity that compound as more relayers come online.',
|
||||
[Key.BenefitThreeTitle]: 'open source',
|
||||
[Key.BenefitThreeDescription]:
|
||||
'0x is open source, permissionless and free to use. Trade directly with a known counterparty for free or pay a relayer some ZRX tokens to access their liquidity pool.',
|
||||
[Key.BuildingBlockSectionHeader]: 'a building block for dApps',
|
||||
[Key.BuildingBlockSectionDescription]:
|
||||
'0x protocol is a pluggable building block for dApps that require exchange functionality. Join the many developers that are already using 0x in their web applications and smart contracts.',
|
||||
[Key.DevToolsPrompt]: 'learn how in our',
|
||||
[Key.SmartContract]: 'smart contract',
|
||||
[Key.Docs]: 'docs',
|
||||
[Key.DecentralizedGovernance]: 'decentralized governance',
|
||||
[Key.DecentralizedGovernanceDescription]:
|
||||
'Decentralized organizations use tokens to represent ownership and guide their governance logic. 0x allows decentralized organizations to seamlessly and safely trade ownership for startup capital.',
|
||||
[Key.PredictionMarkets]: 'prediction markets',
|
||||
[Key.PredictionMarketsDescription]:
|
||||
'decentralized prediction market platforms generate sets of tokens that represent a financial stake in the outcomes of real-world events. 0x allows these tokens to be instantly tradable.',
|
||||
[Key.StableTokens]: 'stable tokens',
|
||||
[Key.StableTokensDescription]:
|
||||
'Novel economic constructs such as stable coins require efficient, liquid markets to succeed. 0x will facilitate the underlying economic mechanisms that allow these tokens to remain stable.',
|
||||
[Key.DecentralizedLoans]: 'decentralized loans',
|
||||
[Key.DecentralizedLoansDescription]:
|
||||
'Efficient lending requires liquid markets where investors can buy and re-sell loans. 0x enables an ecosystem of lenders to self-organize and efficiently determine market prices for all outstanding loans.',
|
||||
[Key.FundManagement]: 'fund management',
|
||||
[Key.FundManagementDescription]:
|
||||
'Decentralized fund management limits fund managers to investing in pre-agreed upon asset classes. Embedding 0x into fund management smart contracts enables them to enforce these security constraints.',
|
||||
[Key.FinalCallToAction]: 'get started on building the decentralized future',
|
||||
// Footer
|
||||
[Key.Documentation]: 'documentation',
|
||||
[Key.Community]: 'community',
|
||||
[Key.Organization]: 'organization',
|
||||
[Key.About]: 'about',
|
||||
[Key.Careers]: 'careers',
|
||||
[Key.Contact]: 'contact',
|
||||
[Key.Blog]: 'blog',
|
||||
[Key.Forum]: 'forum',
|
||||
[Key.Connect]: '0x Connect',
|
||||
[Key.Whitepaper]: 'whitepaper',
|
||||
[Key.Wiki]: 'wiki',
|
||||
[Key.Faq]: 'FAQ',
|
||||
[Key.SmartContracts]: '0x smart contracts',
|
||||
[Key.StandardRelayerApi]: 'standard relayer API',
|
||||
[Key.PortalDApp]: 'portal dApp',
|
||||
[Key.Website]: 'website',
|
||||
[Key.Home]: 'home',
|
||||
[Key.FAQ]: 'FAQ',
|
||||
[Key.RocketChat]: 'rocket.chat',
|
||||
// TopBar
|
||||
[Key.Developers]: 'developers',
|
||||
};
|
||||
@@ -667,4 +667,75 @@ export interface MaterialUIPosition {
|
||||
horizontal: 'left' | 'middle' | 'right';
|
||||
}
|
||||
|
||||
export enum Language {
|
||||
English = 'EN',
|
||||
}
|
||||
|
||||
export enum Key {
|
||||
TopHeader,
|
||||
TopTagline,
|
||||
BuildCallToAction,
|
||||
CommunityCallToAction,
|
||||
ProjectsHeader,
|
||||
FullListPrompt,
|
||||
FullListLink,
|
||||
TokenizedSectionHeader,
|
||||
TokenizedSectionDescription,
|
||||
Currency,
|
||||
TraditionalAssets,
|
||||
DigitalGoods,
|
||||
OffChainOrderRelay,
|
||||
OonChainSettlement,
|
||||
OffChainOnChainDescription,
|
||||
RelayersHeader,
|
||||
BenefitsHeader,
|
||||
BenefitOneTitle,
|
||||
BenefitOneDescription,
|
||||
BenefitTwoTitle,
|
||||
BenefitTwoDescription,
|
||||
BenefitThreeTitle,
|
||||
BenefitThreeDescription,
|
||||
BuildingBlockSectionHeader,
|
||||
BuildingBlockSectionDescription,
|
||||
DevToolsPrompt,
|
||||
SmartContract,
|
||||
Docs,
|
||||
DecentralizedGovernance,
|
||||
DecentralizedGovernanceDescription,
|
||||
PredictionMarkets,
|
||||
PredictionMarketsDescription,
|
||||
StableTokens,
|
||||
StableTokensDescription,
|
||||
DecentralizedLoans,
|
||||
DecentralizedLoansDescription,
|
||||
FundManagement,
|
||||
FundManagementDescription,
|
||||
FinalCallToAction,
|
||||
Documentation,
|
||||
Community,
|
||||
Organization,
|
||||
About,
|
||||
Careers,
|
||||
Contact,
|
||||
Blog,
|
||||
Forum,
|
||||
Connect,
|
||||
Whitepaper,
|
||||
Wiki,
|
||||
Faq,
|
||||
SmartContracts,
|
||||
StandardRelayerApi,
|
||||
PortalDApp,
|
||||
Website,
|
||||
Developers,
|
||||
Home,
|
||||
RocketChat,
|
||||
FAQ,
|
||||
}
|
||||
|
||||
export enum Deco {
|
||||
Cap,
|
||||
CapWords,
|
||||
Upper,
|
||||
}
|
||||
// tslint:disable:max-file-line-count
|
||||
|
||||
54
packages/website/ts/utils/translate.ts
Normal file
54
packages/website/ts/utils/translate.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import * as _ from 'lodash';
|
||||
import { english } from 'ts/translations/english';
|
||||
import { Deco, Key, Language } from 'ts/types';
|
||||
|
||||
const languageToTranslations = {
|
||||
[Language.English]: english,
|
||||
};
|
||||
|
||||
interface Translation {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export class Translate {
|
||||
private _selectedLanguage: Language;
|
||||
private _translation: Translation;
|
||||
constructor() {
|
||||
this.setLanguage(Language.English);
|
||||
}
|
||||
public setLanguage(language: Language) {
|
||||
const isLanguageSupported = !_.isUndefined(languageToTranslations[language]);
|
||||
if (!isLanguageSupported) {
|
||||
throw new Error(`${language} not supported`);
|
||||
}
|
||||
this._selectedLanguage = language;
|
||||
this._translation = languageToTranslations[language];
|
||||
}
|
||||
public get(key: Key, decoration?: Deco) {
|
||||
let text = this._translation[key];
|
||||
if (!_.isUndefined(decoration)) {
|
||||
switch (decoration) {
|
||||
case Deco.Cap:
|
||||
text = this._capitalize(text);
|
||||
break;
|
||||
|
||||
case Deco.Upper:
|
||||
text = text.toUpperCase();
|
||||
break;
|
||||
|
||||
case Deco.CapWords:
|
||||
const words = text.split(' ');
|
||||
const capitalizedWords = _.map(words, w => this._capitalize(w));
|
||||
text = capitalizedWords.join(' ');
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unrecognized decoration: ${decoration}`);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
private _capitalize(text: string) {
|
||||
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user