From 3660ba28d73d70d08bf14c33ef680e5ef3ec7f3b Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 21 Nov 2017 14:03:08 -0600 Subject: Add website to mono repo, update packages to align with existing sub-packages, use new subscribeAsync 0x.js method --- packages/website/ts/pages/landing/landing.tsx | 843 ++++++++++++++++++++++++++ 1 file changed, 843 insertions(+) create mode 100644 packages/website/ts/pages/landing/landing.tsx (limited to 'packages/website/ts/pages/landing/landing.tsx') diff --git a/packages/website/ts/pages/landing/landing.tsx b/packages/website/ts/pages/landing/landing.tsx new file mode 100644 index 000000000..32ea86736 --- /dev/null +++ b/packages/website/ts/pages/landing/landing.tsx @@ -0,0 +1,843 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import DocumentTitle = require('react-document-title'); +import {Link} from 'react-router-dom'; +import RaisedButton from 'material-ui/RaisedButton'; +import {colors} from 'material-ui/styles'; +import {configs} from 'ts/utils/configs'; +import {constants} from 'ts/utils/constants'; +import {Styles, WebsitePaths, ScreenWidths} from 'ts/types'; +import {utils} from 'ts/utils/utils'; +import {TopBar} from 'ts/components/top_bar'; +import {Footer} from 'ts/components/footer'; + +interface BoxContent { + title: string; + description: string; + imageUrl: string; + classNames: string; +} +interface AssetType { + title: string; + imageUrl: string; + style?: React.CSSProperties; +} +interface UseCase { + imageUrl: string; + type: string; + description: string; + classNames: string; + style?: React.CSSProperties; + projectIconUrls: string[]; +} +interface Project { + logoFileName: string; + projectUrl: string; +} + +const THROTTLE_TIMEOUT = 100; +const CUSTOM_HERO_BACKGROUND_COLOR = '#404040'; +const CUSTOM_PROJECTS_BACKGROUND_COLOR = '#343333'; +const CUSTOM_WHITE_BACKGROUND = 'rgb(245, 245, 245)'; +const CUSTOM_WHITE_TEXT = '#E4E4E4'; +const CUSTOM_GRAY_TEXT = '#919191'; + +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 projects: Project[] = [ + { + logoFileName: 'ethfinex-top.png', + projectUrl: constants.ETHFINEX_URL, + }, + { + logoFileName: 'radar_relay_top.png', + projectUrl: constants.RADAR_RELAY_URL, + }, + { + logoFileName: 'paradex_top.png', + projectUrl: constants.PARADEX_URL, + }, + { + logoFileName: 'the_ocean.png', + projectUrl: constants.OCEAN_URL, + }, + { + logoFileName: 'dydx.png', + projectUrl: constants.DYDX_URL, + }, + { + logoFileName: 'melonport.png', + projectUrl: constants.MELONPORT_URL, + }, + { + logoFileName: 'maker.png', + projectUrl: constants.MAKER_URL, + }, + { + logoFileName: 'dharma.png', + projectUrl: constants.DHARMA_URL, + }, + { + logoFileName: 'lendroid.png', + projectUrl: constants.LENDROID_URL, + }, + { + logoFileName: 'district0x.png', + projectUrl: constants.DISTRICT_0X_URL, + }, + { + logoFileName: 'aragon.png', + projectUrl: constants.ARAGON_URL, + }, + { + logoFileName: 'blocknet.png', + projectUrl: constants.BLOCKNET_URL, + }, + { + logoFileName: 'status.png', + projectUrl: constants.STATUS_URL, + }, + { + logoFileName: 'augur.png', + projectUrl: constants.AUGUR_URL, + }, + { + logoFileName: 'anx.png', + projectUrl: constants.OPEN_ANX_URL, + }, + { + logoFileName: 'auctus.png', + projectUrl: constants.AUCTUS_URL, + }, +]; + +export interface LandingProps { + location: Location; +} + +interface LandingState { + screenWidth: ScreenWidths; +} + +export class Landing extends React.Component { + private throttledScreenWidthUpdate: () => void; + constructor(props: LandingProps) { + super(props); + this.state = { + screenWidth: utils.getScreenWidth(), + }; + this.throttledScreenWidthUpdate = _.throttle(this.updateScreenWidth.bind(this), THROTTLE_TIMEOUT); + } + public componentDidMount() { + window.addEventListener('resize', this.throttledScreenWidthUpdate); + window.scrollTo(0, 0); + } + public componentWillUnmount() { + window.removeEventListener('resize', this.throttledScreenWidthUpdate); + } + public render() { + return ( +
+ + + {this.renderHero()} + {this.renderProjects()} + {this.renderTokenizationSection()} + {this.renderProtocolSection()} + {this.renderInfoBoxes()} + {this.renderBuildingBlocksSection()} + {this.renderUseCases()} + {this.renderCallToAction()} +
+
+ ); + } + private renderHero() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + const buttonLabelStyle: React.CSSProperties = { + textTransform: 'none', + fontSize: isSmallScreen ? 12 : 14, + fontWeight: 400, + }; + const lightButtonStyle: React.CSSProperties = { + borderRadius: 6, + border: '1px solid #D8D8D8', + lineHeight: '33px', + height: 38, + }; + const left = 'col lg-col-7 md-col-7 col-12 lg-pt4 md-pt4 sm-pt0 mt1 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center'; + return ( +
+
+
+
+ +
+
+
+
+ Powering decentralized exchange +
+
+ 0x is an open, permissionless protocol allowing for ERC20 tokens to + be traded on the Ethereum blockchain. +
+
+
+ + + +
+
+ + + +
+
+
+
+
+
+
+ ); + } + private renderProjects() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + const isMediumScreen = this.state.screenWidth === ScreenWidths.MD; + const projectList = _.map(projects, (project: Project, i: number) => { + const colWidth = isSmallScreen ? 3 : isMediumScreen ? 4 : 2 - (i % 2); + return ( +
+
+ + + +
+
+ ); + }); + const titleStyle: React.CSSProperties = { + fontFamily: 'Roboto Mono', + color: '#A4A4A4', + textTransform: 'uppercase', + fontWeight: 300, + letterSpacing: 3, + }; + return ( +
+
+
+ Projects building on 0x +
+
+ {projectList} +
+
+ view the{' '} + + full list + +
+
+
+ ); + } + private renderTokenizationSection() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + return ( +
+
+ {isSmallScreen && + this.renderTokenCloud() + } +
+
+
+ The world's value is becoming tokenized +
+
+ {isSmallScreen ? + + 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. + : +
+
+ 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. +
+
+ } +
+
+ {this.renderAssetTypes()} +
+
+
+ {!isSmallScreen && + this.renderTokenCloud() + } +
+
+ ); + } + private renderProtocolSection() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + return ( +
+
+
+ +
+
+
+
+ Off-chain order relay +
+
+ On-chain settlement +
+
+
+ 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. +
+
+
+
+ RELAYERS BUILDING ON 0X +
+
+ + view all + +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+ ); + } + private renderBuildingBlocksSection() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + const underlineStyle: React.CSSProperties = { + height: isSmallScreen ? 18 : 23, + lineHeight: 'none', + borderBottom: '2px solid #979797', + }; + const descriptionStyle: React.CSSProperties = { + fontFamily: 'Roboto Mono', + lineHeight: isSmallScreen ? 1.5 : 2, + fontWeight: 300, + fontSize: 15, + maxWidth: isSmallScreen ? 375 : 'none', + }; + const callToActionStyle: React.CSSProperties = { + fontFamily: 'Roboto Mono', + fontSize: 15, + fontWeight: 300, + maxWidth: isSmallScreen ? 375 : 441, + }; + return ( +
+
+ {isSmallScreen && + this.renderBlockChipImage() + } +
+
+ A building block for dApps +
+
+ 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. +
+
+ Learn how in our{' '} + + 0x.js + + {' '}and{' '} + + smart contract + + {' '}docs +
+
+ {!isSmallScreen && + this.renderBlockChipImage() + } +
+
+ ); + } + private renderBlockChipImage() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + return ( +
+ +
+ ); + } + private renderTokenCloud() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + return ( +
+ +
+ ); + } + private renderAssetTypes() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + const assetTypes: AssetType[] = [ + { + title: 'Currency', + imageUrl: '/images/landing/currency.png', + }, + { + title: 'Traditional assets', + imageUrl: '/images/landing/stocks.png', + style: {paddingLeft: isSmallScreen ? 41 : 56, paddingRight: isSmallScreen ? 41 : 56}, + }, + { + title: 'Digital goods', + imageUrl: '/images/landing/digital_goods.png', + }, + ]; + const assets = _.map(assetTypes, (assetType: AssetType) => { + const style = _.isUndefined(assetType.style) ? {} : assetType.style; + return ( +
+
+ +
+
+ {assetType.title} +
+
+ ); + }); + return assets; + } + private renderLink(label: string, path: string, color: string, style?: React.CSSProperties) { + return ( +
+ + {label} + +
+ ); + } + private renderInfoBoxes() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + const boxStyle: React.CSSProperties = { + maxWidth: 252, + height: 386, + backgroundColor: '#F9F9F9', + borderRadius: 5, + padding: '10px 24px 24px', + }; + const boxes = _.map(boxContents, (boxContent: BoxContent) => { + return ( +
+
+
+ +
+
+ {boxContent.title} +
+
+ {boxContent.description} +
+
+
+ ); + + }); + return ( +
+
+ {boxes} +
+
+ ); + } + private renderUseCases() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + const isMediumScreen = this.state.screenWidth === ScreenWidths.MD; + + 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.', + 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.', + 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.', + 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.', + projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'], + 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: '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.', + projectIconUrls: ['/images/landing/melonport.png'], + classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6', + style: {width: 291, marginTop: !isSmallScreen ? 38 : 0}, + }, + ]; + + const cases = _.map(useCases, (useCase: UseCase) => { + const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style; + const useCaseBoxStyle = { + color: '#A2A2A2', + border: '1px solid #565656', + borderRadius: 4, + maxWidth: isSmallScreen ? 375 : 'none', + ...style, + }; + const typeStyle: React.CSSProperties = { + color: '#EBEBEB', + fontSize: 13, + textTransform: 'uppercase', + fontFamily: 'Roboto Mono', + fontWeight: 300, + }; + return ( +
+
+
+ +
+
+ {useCase.type} +
+
+ {useCase.description} +
+
+
+ ); + }); + return ( +
+
+ {cases} +
+
+ ); + } + private renderCallToAction() { + const isSmallScreen = this.state.screenWidth === ScreenWidths.SM; + const buttonLabelStyle: React.CSSProperties = { + textTransform: 'none', + fontSize: 15, + fontWeight: 400, + }; + const lightButtonStyle: React.CSSProperties = { + borderRadius: 6, + border: '1px solid #a0a0a0', + lineHeight: '33px', + height: 49, + }; + const callToActionClassNames = 'col lg-col-8 md-col-8 col-12 lg-pr3 md-pr3 \ + lg-right-align md-right-align sm-center sm-px3 h4'; + return ( +
+
+
+ Get started on building the decentralized future +
+
+ + + +
+
+
+ ); + } + private updateScreenWidth() { + const newScreenWidth = utils.getScreenWidth(); + if (newScreenWidth !== this.state.screenWidth) { + this.setState({ + screenWidth: newScreenWidth, + }); + } + } +} -- cgit