diff options
Diffstat (limited to 'packages/website/ts/pages/landing/landing.tsx')
-rw-r--r-- | packages/website/ts/pages/landing/landing.tsx | 620 |
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 bb76efe21..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 the 0x Launch Kit'; -const WHATS_NEW_URL = 'https://blog.0xproject.com/introducing-the-0x-launch-kit-4acdc3453585'; -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} target="_blank" 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 |