aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/pages/landing/landing.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website/ts/pages/landing/landing.tsx')
-rw-r--r--packages/website/ts/pages/landing/landing.tsx620
1 files changed, 0 insertions, 620 deletions
diff --git a/packages/website/ts/pages/landing/landing.tsx b/packages/website/ts/pages/landing/landing.tsx
deleted file mode 100644
index b75b55edb..000000000
--- a/packages/website/ts/pages/landing/landing.tsx
+++ /dev/null
@@ -1,620 +0,0 @@
-import { colors, Link } from '@0x/react-shared';
-import * as _ from 'lodash';
-import * as React from 'react';
-import DocumentTitle from 'react-document-title';
-import { Footer } from 'ts/components/footer';
-import { SubscribeForm } from 'ts/components/forms/subscribe_form';
-import { TopBar } from 'ts/components/top_bar/top_bar';
-import { CallToAction } from 'ts/components/ui/button';
-import { Container } from 'ts/components/ui/container';
-import { Image } from 'ts/components/ui/image';
-import { Text } from 'ts/components/ui/text';
-import { TypedText } from 'ts/components/ui/typed_text';
-import { Dispatcher } from 'ts/redux/dispatcher';
-import { Deco, Key, Language, ScreenWidths, WebsitePaths } from 'ts/types';
-import { constants } from 'ts/utils/constants';
-import { Translate } from 'ts/utils/translate';
-import { utils } from 'ts/utils/utils';
-
-interface BoxContent {
- title: string;
- description: string;
- imageUrl: string;
- classNames: string;
- maxWidth: number;
-}
-interface UseCase {
- imageUrl: string;
- type: string;
- description: string;
- classNames: string;
- style?: React.CSSProperties;
-}
-interface Project {
- logoFileName: string;
- projectUrl: string;
-}
-
-const THROTTLE_TIMEOUT = 100;
-const WHATS_NEW_TITLE = 'Introducing 0x Instant';
-const WHATS_NEW_URL = WebsitePaths.Instant;
-const TITLE_STYLE: React.CSSProperties = {
- fontFamily: 'Roboto Mono',
- color: colors.grey,
- fontWeight: 300,
- letterSpacing: 3,
-};
-const ROTATING_LIST = [
- 'tokens',
- 'game items',
- 'digital art',
- 'futures',
- 'stocks',
- 'derivatives',
- 'loans',
- 'cats',
- 'everything',
-];
-
-const relayerProjects: Project[] = [
- {
- logoFileName: 'ethfinex.png',
- projectUrl: constants.PROJECT_URL_ETHFINEX,
- },
- {
- logoFileName: 'radar_relay.png',
- projectUrl: constants.PROJECT_URL_RADAR_RELAY,
- },
- {
- logoFileName: 'paradex.png',
- projectUrl: constants.PROJECT_URL_PARADEX,
- },
- {
- logoFileName: 'the_ocean.png',
- projectUrl: constants.PROJECT_URL_0CEAN,
- },
- {
- logoFileName: 'amadeus.png',
- projectUrl: constants.PROJECT_URL_AMADEUS,
- },
- {
- logoFileName: 'ddex.png',
- projectUrl: constants.PROJECT_URL_DDEX,
- },
- {
- logoFileName: 'decent_ex.png',
- projectUrl: constants.PROJECT_URL_DECENT_EX,
- },
- {
- logoFileName: 'dextroid.png',
- projectUrl: constants.PROJECT_URL_DEXTROID,
- },
- {
- logoFileName: 'ercdex.png',
- projectUrl: constants.PROJECT_URL_ERC_DEX,
- },
- {
- logoFileName: 'open_relay.png',
- projectUrl: constants.PROJECT_URL_OPEN_RELAY,
- },
- {
- logoFileName: 'idt.png',
- projectUrl: constants.PROJECT_URL_IDT,
- },
- {
- logoFileName: 'imtoken.png',
- projectUrl: constants.PROJECT_URL_IMTOKEN,
- },
-];
-
-export interface LandingProps {
- location: Location;
- translate: Translate;
- dispatcher: Dispatcher;
-}
-
-interface LandingState {
- screenWidth: ScreenWidths;
-}
-
-export class Landing extends React.Component<LandingProps, LandingState> {
- private readonly _throttledScreenWidthUpdate: () => void;
- constructor(props: LandingProps) {
- super(props);
- this.state = {
- screenWidth: utils.getScreenWidth(),
- };
- this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
- }
- public componentDidMount(): void {
- window.addEventListener('resize', this._throttledScreenWidthUpdate);
- window.scrollTo(0, 0);
- }
- public componentWillUnmount(): void {
- window.removeEventListener('resize', this._throttledScreenWidthUpdate);
- }
- public render(): React.ReactNode {
- return (
- <div id="landing" className="clearfix" style={{ color: colors.grey500 }}>
- <DocumentTitle title="0x Protocol" />
- <TopBar
- blockchainIsLoaded={false}
- location={this.props.location}
- isNightVersion={true}
- style={{ backgroundColor: colors.heroGrey, position: 'relative' }}
- translate={this.props.translate}
- />
- {this._renderHero()}
- {this._renderProjects(
- relayerProjects,
- this.props.translate.get(Key.RelayersHeader, Deco.Upper),
- colors.projectsGrey,
- true,
- )}
- {this._renderInfoBoxes()}
- {this._renderTokenizationSection()}
- {this._renderUseCases()}
- {this._renderCallToAction()}
- <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} />
- </div>
- );
- }
- private _renderHero(): React.ReactNode {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const left = 'col lg-col-6 md-col-6 col-12 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center';
- const flexClassName = isSmallScreen
- ? 'flex items-center flex-column justify-center'
- : 'flex items-center justify-center';
- return (
- <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}>
- <div className="mx-auto max-width-4 clearfix">
- {this._renderWhatsNew()}
- <div className={`${flexClassName} lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-mt4 md-mt4 sm-mt2 sm-mb4`}>
- <Container marginTop="30px" marginBottom="30px" marginLeft="15px" marginRight="15px">
- <Image src="/images/landing/0x_homepage.svg" maxWidth="100%" height="auto" />
- </Container>
- <div className={left} style={{ color: colors.white, height: 390, lineHeight: '390px' }}>
- <div
- className="inline-block lg-align-middle md-align-middle sm-align-top"
- style={{
- paddingLeft: isSmallScreen ? 0 : 12,
- lineHeight: '36px',
- }}
- >
- <Text
- className="sm-pb2"
- fontFamily="Roboto"
- display="inline-block"
- fontColor={colors.grey300}
- fontWeight={500}
- lineHeight="1.3em"
- fontSize={isSmallScreen ? '28px' : '36px'}
- >
- {this.props.translate.get(Key.TopHeader, Deco.Cap)}
- {this.props.translate.getLanguage() === Language.English && (
- <React.Fragment>
- {' '}
- for{' '}
- <TypedText
- fontFamily="Roboto"
- display="inline-block"
- fontColor={colors.white}
- fontWeight={700}
- lineHeight="1.3em"
- fontSize={isSmallScreen ? '28px' : '36px'}
- textList={ROTATING_LIST}
- shouldRepeat={true}
- />
- </React.Fragment>
- )}
- </Text>
- <Container
- className={`pt3 flex clearfix sm-mx-auto ${isSmallScreen ? 'justify-center' : ''}`}
- >
- <Container paddingRight="20px">
- <Link to={WebsitePaths.Docs}>
- <CallToAction type="light">
- {this.props.translate.get(Key.BuildCallToAction, Deco.Cap)}
- </CallToAction>
- </Link>
- </Container>
- <div>
- <Link to={WebsitePaths.Portal}>
- <CallToAction>
- {this.props.translate.get(Key.TradeCallToAction, Deco.Cap)}
- </CallToAction>
- </Link>
- </div>
- </Container>
- </div>
- </div>
- </div>
- </div>
- {this.props.translate.getLanguage() === Language.English && <SubscribeForm />}
- </div>
- );
- }
- private _renderWhatsNew(): React.ReactNode {
- return (
- <div className="sm-center sm-px1">
- <a href={WHATS_NEW_URL} className="inline-block text-decoration-none">
- <div className="flex items-center sm-pl0 md-pl2 lg-pl0">
- <Container
- paddingTop="3px"
- paddingLeft="8px"
- paddingBottom="3px"
- paddingRight="8px"
- backgroundColor={colors.white}
- borderRadius={6}
- >
- <Text fontSize="14px" fontWeight={500} fontColor={colors.heroGrey}>
- New
- </Text>
- </Container>
- <Container marginLeft="12px">
- <Text fontSize="16px" fontWeight={500} fontColor={colors.grey300}>
- {WHATS_NEW_TITLE}
- </Text>
- </Container>
- </div>
- </a>
- </div>
- );
- }
- private _renderProjects(
- projects: Project[],
- title: string,
- backgroundColor: string,
- isTitleCenter: boolean,
- ): React.ReactNode {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const projectList = _.map(projects, (project: Project, i: number) => {
- const isRelayersOnly = projects.length === 12;
- let colWidth: number;
- switch (this.state.screenWidth) {
- case ScreenWidths.Sm:
- colWidth = 4;
- break;
-
- case ScreenWidths.Md:
- colWidth = 3;
- break;
-
- case ScreenWidths.Lg:
- colWidth = isRelayersOnly ? 2 : 2 - i % 2;
- break;
-
- default:
- throw new Error(`Encountered unknown ScreenWidths value: ${this.state.screenWidth}`);
- }
- return (
- <div key={`project-${project.logoFileName}`} className={`col col-${colWidth} center`}>
- <div>
- <a href={project.projectUrl} target="_blank" className="text-decoration-none">
- <img
- src={`/images/landing/project_logos/${project.logoFileName}`}
- height={isSmallScreen ? 60 : 92}
- />
- </a>
- </div>
- </div>
- );
- });
- return (
- <div className={`clearfix py4 ${isTitleCenter && 'center'}`} style={{ backgroundColor }}>
- <div className="mx-auto max-width-4 clearfix sm-px3">
- <div className="h4 pb3 lg-pl0 md-pl3 sm-pl2" style={TITLE_STYLE}>
- {title}
- </div>
- <div className="clearfix">{projectList}</div>
- <div
- className="pt3 mx-auto center"
- style={{
- color: colors.landingLinkGrey,
- fontFamily: 'Roboto Mono',
- maxWidth: 300,
- fontSize: 14,
- }}
- >
- {this.props.translate.get(Key.FullListPrompt)}{' '}
- <Link to={WebsitePaths.Portal} textDecoration="underline" fontColor={colors.landingLinkGrey}>
- {this.props.translate.get(Key.FullListLink)}
- </Link>
- </div>
- </div>
- </div>
- );
- }
- private _renderTokenizationSection(): React.ReactNode {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- return (
- <div className="clearfix lg-py4 md-py4 sm-pb4 sm-pt2" style={{ backgroundColor: colors.grey100 }}>
- <div className="mx-auto max-width-4 py4 clearfix">
- {isSmallScreen && this._renderTokenCloud()}
- <div
- className="col lg-col-6 md-col-6 col-12 center"
- style={{ color: colors.darkestGrey, height: 364, lineHeight: '364px' }}
- >
- <div
- className="mx-auto inline-block lg-align-middle md-align-middle sm-align-top"
- style={{ maxWidth: 385, lineHeight: '44px', textAlign: 'left' }}
- >
- <div className="lg-h1 md-h1 sm-h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}>
- {this.props.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, maxWidth: 370 }}
- >
- {this.props.translate.get(Key.TokenizedSectionDescription, Deco.Cap)}
- </div>
- <div className="flex pt1 sm-px3">{this._renderMissionAndValuesButton()}</div>
- </div>
- </div>
- {!isSmallScreen && this._renderTokenCloud()}
- </div>
- </div>
- );
- }
- private _renderTokenCloud(): React.ReactNode {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- return (
- <div className="col lg-col-6 md-col-6 col-12 center">
- <img src="/images/landing/tokenized_world.png" height={isSmallScreen ? 280 : 364.5} />
- </div>
- );
- }
- private _renderMissionAndValuesButton(): React.ReactNode {
- return (
- <a
- href={constants.URL_MISSION_AND_VALUES_BLOG_POST}
- target="_blank"
- className="inline-block text-decoration-none"
- >
- <CallToAction>{this.props.translate.get(Key.OurMissionAndValues, Deco.CapWords)}</CallToAction>
- </a>
- );
- }
- private _renderInfoBoxes(): React.ReactNode {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const boxStyle: React.CSSProperties = {
- maxWidth: 253,
- height: 402,
- backgroundColor: colors.grey50,
- borderRadius: 5,
- padding: '10px 24px 24px',
- };
- const boxContents: BoxContent[] = [
- {
- title: this.props.translate.get(Key.BenefitOneTitle, Deco.Cap),
- description: this.props.translate.get(Key.BenefitOneDescription, Deco.Cap),
- imageUrl: '/images/landing/distributed_network.png',
- classNames: '',
- maxWidth: 160,
- },
- {
- title: this.props.translate.get(Key.BenefitTwoTitle, Deco.Cap),
- description: this.props.translate.get(Key.BenefitTwoDescription, Deco.Cap),
- imageUrl: '/images/landing/liquidity.png',
- classNames: 'mx-auto',
- maxWidth: 160,
- },
- {
- title: this.props.translate.get(Key.BenefitThreeTitle, Deco.Cap),
- description: this.props.translate.get(Key.BenefitThreeDescription, Deco.Cap),
- imageUrl: '/images/landing/exchange_everywhere.png',
- classNames: 'right',
- maxWidth: 130,
- },
- ];
- const boxes = _.map(boxContents, (boxContent: BoxContent) => {
- return (
- <div key={`box-${boxContent.title}`} className="col lg-col-4 md-col-4 col-12 sm-pb4">
- <div className={`center sm-mx-auto ${!isSmallScreen && boxContent.classNames}`} style={boxStyle}>
- <Container className="flex items-center" height="210px">
- <img
- className="mx-auto"
- src={boxContent.imageUrl}
- style={{ height: 'auto', maxWidth: boxContent.maxWidth }}
- />
- </Container>
- <div className="h3" style={{ color: 'black', fontFamily: 'Roboto Mono' }}>
- {boxContent.title}
- </div>
- <div className="pt2 pb2" style={{ fontFamily: 'Roboto Mono', fontSize: 14 }}>
- {boxContent.description}
- </div>
- </div>
- </div>
- );
- });
- return (
- <div className="clearfix" style={{ backgroundColor: colors.heroGrey }}>
- <div className="center pb3 pt4" style={TITLE_STYLE}>
- {this.props.translate.get(Key.BenefitsHeader, Deco.Upper)}
- </div>
- <div className="mx-auto pb4 sm-mt2 clearfix" style={{ maxWidth: '60em' }}>
- {boxes}
- </div>
- </div>
- );
- }
- private _getUseCases(): UseCase[] {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const isEnglish = this.props.translate.getLanguage() === Language.English;
- if (isEnglish) {
- return [
- {
- imageUrl: '/images/landing/governance_icon.png',
- type: this.props.translate.get(Key.GamingAndCollectables, Deco.Upper),
- description: this.props.translate.get(Key.GamingAndCollectablesDescription, Deco.Cap),
- classNames: 'lg-px2 md-px2',
- },
- {
- imageUrl: '/images/landing/prediction_market_icon.png',
- type: this.props.translate.get(Key.PredictionMarkets, Deco.Upper),
- description: this.props.translate.get(Key.PredictionMarketsDescription, Deco.Cap),
- classNames: 'lg-px2 md-px2',
- },
- {
- imageUrl: '/images/landing/fund_management_icon.png',
- type: this.props.translate.get(Key.OrderBooks, Deco.Upper),
- description: this.props.translate.get(Key.OrderBooksDescription, Deco.Cap),
- classNames: 'lg-px2 md-px2',
- },
- {
- imageUrl: '/images/landing/loans_icon.png',
- type: this.props.translate.get(Key.DecentralizedLoans, Deco.Upper),
- description: this.props.translate.get(Key.DecentralizedLoansDescription, Deco.Cap),
- classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6',
- style: {
- width: 291,
- float: 'right',
- marginTop: !isSmallScreen ? 38 : 0,
- },
- },
- {
- imageUrl: '/images/landing/stable_tokens_icon.png',
- type: this.props.translate.get(Key.StableTokens, Deco.Upper),
- description: this.props.translate.get(Key.StableTokensDescription, Deco.Cap),
- classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6',
- style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 },
- },
- ];
- } else {
- return [
- {
- imageUrl: '/images/landing/governance_icon.png',
- type: this.props.translate.get(Key.DecentralizedGovernance, Deco.Upper),
- description: this.props.translate.get(Key.DecentralizedGovernanceDescription, Deco.Cap),
- classNames: 'lg-px2 md-px2',
- },
- {
- imageUrl: '/images/landing/prediction_market_icon.png',
- type: this.props.translate.get(Key.PredictionMarkets, Deco.Upper),
- description: this.props.translate.get(Key.PredictionMarketsDescription, Deco.Cap),
- classNames: 'lg-px2 md-px2',
- },
- {
- imageUrl: '/images/landing/stable_tokens_icon.png',
- type: this.props.translate.get(Key.StableTokens, Deco.Upper),
- description: this.props.translate.get(Key.StableTokensDescription, Deco.Cap),
- classNames: 'lg-px2 md-px2',
- },
- {
- imageUrl: '/images/landing/loans_icon.png',
- type: this.props.translate.get(Key.DecentralizedLoans, Deco.Upper),
- description: this.props.translate.get(Key.DecentralizedLoansDescription, Deco.Cap),
- classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6',
- style: {
- width: 291,
- float: 'right',
- marginTop: !isSmallScreen ? 38 : 0,
- },
- },
- {
- imageUrl: '/images/landing/fund_management_icon.png',
- type: this.props.translate.get(Key.FundManagement, Deco.Upper),
- description: this.props.translate.get(Key.FundManagementDescription, Deco.Cap),
- classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6',
- style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 },
- },
- ];
- }
- }
- private _renderUseCases(): React.ReactNode {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const useCases = this._getUseCases();
- const cases = _.map(useCases, (useCase: UseCase) => {
- const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style;
- const useCaseBoxStyle = {
- color: colors.grey,
- border: `1px solid ${colors.grey750}`,
- borderRadius: 4,
- maxWidth: isSmallScreen ? 375 : 'none',
- ...style,
- };
- const typeStyle: React.CSSProperties = {
- color: colors.lightGrey,
- fontSize: 13,
- textTransform: 'uppercase',
- fontFamily: 'Roboto Mono',
- fontWeight: 300,
- };
- return (
- <div
- key={`useCase-${useCase.type}`}
- className={`col lg-col-4 md-col-4 col-12 sm-pt3 sm-px3 sm-pb3 ${useCase.classNames}`}
- >
- <div className="relative p2 pb2 sm-mx-auto" style={useCaseBoxStyle}>
- <div className="absolute center" style={{ top: -35, width: 'calc(100% - 32px)' }}>
- <img src={useCase.imageUrl} style={{ height: 50 }} />
- </div>
- <div className="pt2 center" style={typeStyle}>
- {useCase.type}
- </div>
- <div
- className="pt2"
- style={{
- lineHeight: 1.5,
- fontSize: 14,
- overflow: 'hidden',
- height: 124,
- }}
- >
- {useCase.description}
- </div>
- </div>
- </div>
- );
- });
- return (
- <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}>
- <div className="center h4 pb3 lg-pl0 md-pl3 sm-pl2" style={TITLE_STYLE}>
- {this.props.translate.get(Key.UseCasesHeader, Deco.Upper)}
- </div>
- <div className="mx-auto pb4 pt3 mt1 sm-mt2 clearfix" style={{ maxWidth: '67em' }}>
- {cases}
- </div>
- </div>
- );
- }
- private _renderCallToAction(): React.ReactNode {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const callToActionClassNames =
- 'lg-pr3 md-pr3 lg-right-align md-right-align sm-center sm-px3 h4 lg-table-cell md-table-cell';
- return (
- <div className="clearfix pb4" style={{ backgroundColor: colors.heroGrey }}>
- <div className="mx-auto max-width-4 pb4 mb3 clearfix center">
- <div className="center inline-block" style={{ textAlign: 'left' }}>
- <div
- className={callToActionClassNames}
- style={{
- fontFamily: 'Roboto Mono',
- color: colors.white,
- lineHeight: isSmallScreen ? 1.7 : 3,
- }}
- >
- {this.props.translate.get(Key.FinalCallToAction, Deco.Cap)}
- </div>
- <div className="sm-center sm-pt2 lg-table-cell md-table-cell">
- <Link to={WebsitePaths.Docs}>
- <CallToAction fontSize="15px">
- {this.props.translate.get(Key.BuildCallToAction, Deco.Cap)}
- </CallToAction>
- </Link>
- </div>
- </div>
- </div>
- </div>
- );
- }
- private _updateScreenWidth(): void {
- const newScreenWidth = utils.getScreenWidth();
- if (newScreenWidth !== this.state.screenWidth) {
- this.setState({
- screenWidth: newScreenWidth,
- });
- }
- }
-} // tslint:disable:max-file-line-count