diff options
author | Francesco Agosti <francesco.agosti93@gmail.com> | 2018-12-04 06:51:27 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-04 06:51:27 +0800 |
commit | e9fe7dcf54183416e114655595be4e565811d4ed (patch) | |
tree | 748372f2f919571a7221874f627124f61f606235 /packages/website/ts/pages | |
parent | 50df67e7511460f051f91785bb4384485077ef60 (diff) | |
parent | 0f01e31cc3826df7000e0ddc35354aa9af515966 (diff) | |
download | dexon-sol-tools-e9fe7dcf54183416e114655595be4e565811d4ed.tar.gz dexon-sol-tools-e9fe7dcf54183416e114655595be4e565811d4ed.tar.zst dexon-sol-tools-e9fe7dcf54183416e114655595be4e565811d4ed.zip |
Merge pull request #1353 from 0xProject/feature/website/instant-marketing
[website] instant marketing page shell
Diffstat (limited to 'packages/website/ts/pages')
-rw-r--r-- | packages/website/ts/pages/instant/configurator.tsx | 12 | ||||
-rw-r--r-- | packages/website/ts/pages/instant/features.tsx | 146 | ||||
-rw-r--r-- | packages/website/ts/pages/instant/instant.tsx | 87 | ||||
-rw-r--r-- | packages/website/ts/pages/instant/introducing_0x_instant.tsx | 57 | ||||
-rw-r--r-- | packages/website/ts/pages/instant/need_more.tsx | 62 | ||||
-rw-r--r-- | packages/website/ts/pages/instant/screenshots.tsx | 35 |
6 files changed, 399 insertions, 0 deletions
diff --git a/packages/website/ts/pages/instant/configurator.tsx b/packages/website/ts/pages/instant/configurator.tsx new file mode 100644 index 000000000..c836739bb --- /dev/null +++ b/packages/website/ts/pages/instant/configurator.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; + +import { Container } from 'ts/components/ui/container'; +import { colors } from 'ts/style/colors'; + +export interface ConfiguratorProps { + hash: string; +} + +export const Configurator = (props: ConfiguratorProps) => ( + <Container id={props.hash} height="400px" backgroundColor={colors.instantTertiaryBackground} /> +); diff --git a/packages/website/ts/pages/instant/features.tsx b/packages/website/ts/pages/instant/features.tsx new file mode 100644 index 000000000..9c1668c1c --- /dev/null +++ b/packages/website/ts/pages/instant/features.tsx @@ -0,0 +1,146 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { Container } from 'ts/components/ui/container'; +import { Image } from 'ts/components/ui/image'; +import { Text } from 'ts/components/ui/text'; +import { colors } from 'ts/style/colors'; +import { ScreenWidths } from 'ts/types'; +import { utils } from 'ts/utils/utils'; + +export interface FeatureProps { + screenWidth: ScreenWidths; + onGetStartedClick: () => void; +} + +export const Features = (props: FeatureProps) => { + const isSmallScreen = props.screenWidth === ScreenWidths.Sm; + const getStartedLinkInfo = { + displayText: 'Get started', + onClick: props.onGetStartedClick, + }; + const exploreTheDocsLinkInfo = { + displayText: 'Explore the docs', + linkSrc: `${utils.getCurrentBaseUrl()}/wiki#Get-Started`, + }; + const tokenLinkInfos = isSmallScreen ? [getStartedLinkInfo] : [getStartedLinkInfo, exploreTheDocsLinkInfo]; + return ( + <Container backgroundColor={colors.instantSecondaryBackground} className="py3 flex flex-column px3"> + <FeatureItem + imgSrc="images/instant/feature_1.svg" + title="Support ERC-20 and ERC-721 tokens" + description="Seamlessly integrate token purchasing into your product experience by offering digital assets ranging from in-game items to stablecoins." + linkInfos={tokenLinkInfos} + screenWidth={props.screenWidth} + /> + <FeatureItem + imgSrc="images/instant/feature_2.svg" + title="Generate revenue for your business" + description="With just a few lines of code, you can earn up to 5% in affiliate fees on every transaction from your crypto wallet or dApp." + linkInfos={[ + { + displayText: 'Learn about affiliate fees', + linkSrc: `${utils.getCurrentBaseUrl()}/wiki#Learn-About-Affiliate-Fees`, + }, + ]} + screenWidth={props.screenWidth} + /> + <FeatureItem + imgSrc="images/instant/feature_3.svg" + title="Easy and Flexible Integration" + description="Use our out-of-the-box design or customize the user interface by integrating the AssetBuyer engine. You can also tap into 0x networked liquidity or choose your own liquidity pool." + linkInfos={[ + { + displayText: 'Explore AssetBuyer', + linkSrc: `${utils.getCurrentBaseUrl()}/docs/asset-buyer`, + }, + ]} + screenWidth={props.screenWidth} + /> + </Container> + ); +}; + +interface LinkInfo { + displayText: string; + linkSrc?: string; + onClick?: () => void; +} + +interface FeatureItemProps { + imgSrc: string; + title: string; + description: string; + linkInfos: LinkInfo[]; + screenWidth: ScreenWidths; +} + +const FeatureItem = (props: FeatureItemProps) => { + const { imgSrc, title, description, linkInfos, screenWidth } = props; + const isLargeScreen = screenWidth === ScreenWidths.Lg; + const maxWidth = isLargeScreen ? '500px' : undefined; + const image = ( + <Container className="center" minWidth="435px" maxHeight="225px"> + <Image src={imgSrc} additionalStyle={{ filter: 'drop-shadow(0px 4px 4px rgba(0,0,0,.25))' }} /> + </Container> + ); + const info = ( + <Container maxWidth={maxWidth}> + <Text fontSize="24px" lineHeight="34px" fontColor={colors.white} fontWeight={500}> + {title} + </Text> + <Container marginTop="28px"> + <Text fontFamily="Roboto Mono" fontSize="14px" lineHeight="2em" fontColor={colors.grey500}> + {description} + </Text> + </Container> + <Container className="flex" marginTop="28px"> + {_.map(linkInfos, linkInfo => { + const onClick = (event: React.MouseEvent<HTMLElement>) => { + if (!_.isUndefined(linkInfo.onClick)) { + linkInfo.onClick(); + } else if (!_.isUndefined(linkInfo.linkSrc)) { + utils.openUrl(linkInfo.linkSrc); + } + }; + return ( + <Container + key={linkInfo.linkSrc} + className="flex items-center" + marginRight="32px" + onClick={onClick} + cursor="pointer" + > + <Container> + <Text fontSize="16px" fontColor={colors.white}> + {linkInfo.displayText} + </Text> + </Container> + <Container paddingTop="1px" paddingLeft="6px"> + <i + className="zmdi zmdi-chevron-right bold" + style={{ fontSize: 16, color: colors.white }} + /> + </Container> + </Container> + ); + })} + </Container> + </Container> + ); + return ( + <Container className="flex flex-column items-center py4 px3"> + {isLargeScreen ? ( + <Container className="flex"> + {image} + <Container marginLeft="115px">{info}</Container> + </Container> + ) : ( + <Container className="flex flex-column items-center" width="100%"> + {image} + <Container marginTop="48px">{info}</Container> + </Container> + )} + </Container> + ); +}; diff --git a/packages/website/ts/pages/instant/instant.tsx b/packages/website/ts/pages/instant/instant.tsx new file mode 100644 index 000000000..fa6bd1c33 --- /dev/null +++ b/packages/website/ts/pages/instant/instant.tsx @@ -0,0 +1,87 @@ +import { utils as sharedUtils } from '@0x/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; +import * as DocumentTitle from 'react-document-title'; + +import { Footer } from 'ts/components/footer'; +import { MetaTags } from 'ts/components/meta_tags'; +import { TopBar } from 'ts/components/top_bar/top_bar'; +import { Container } from 'ts/components/ui/container'; +import { Configurator } from 'ts/pages/instant/configurator'; +import { Features } from 'ts/pages/instant/features'; +import { Introducing0xInstant } from 'ts/pages/instant/introducing_0x_instant'; +import { NeedMore } from 'ts/pages/instant/need_more'; +import { Screenshots } from 'ts/pages/instant/screenshots'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { colors } from 'ts/style/colors'; +import { ScreenWidths } from 'ts/types'; +import { Translate } from 'ts/utils/translate'; +import { utils } from 'ts/utils/utils'; + +export interface InstantProps { + location: Location; + translate: Translate; + dispatcher: Dispatcher; + screenWidth: ScreenWidths; +} + +export interface InstantState {} + +const CONFIGURATOR_HASH = 'configure'; +const THROTTLE_TIMEOUT = 100; +const DOCUMENT_TITLE = '0x Instant'; +const DOCUMENT_DESCRIPTION = '0x Instant'; + +export class Instant extends React.Component<InstantProps, InstantState> { + // TODO: consolidate this small screen scaffolding into one place (its being used in portal and docs as well) + private readonly _throttledScreenWidthUpdate: () => void; + public constructor(props: InstantProps) { + super(props); + this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT); + } + public componentDidMount(): void { + window.addEventListener('resize', this._throttledScreenWidthUpdate); + window.scrollTo(0, 0); + } + public render(): React.ReactNode { + return ( + <Container overflowX="hidden"> + <MetaTags title={DOCUMENT_TITLE} description={DOCUMENT_DESCRIPTION} /> + <DocumentTitle title={DOCUMENT_TITLE} /> + <TopBar + blockchainIsLoaded={false} + location={this.props.location} + style={{ backgroundColor: colors.instantPrimaryBackground, position: 'relative' }} + translate={this.props.translate} + isNightVersion={true} + /> + <Container backgroundColor={colors.instantPrimaryBackground} /> + <Introducing0xInstant screenWidth={this.props.screenWidth} onCTAClick={this._onGetStartedClick} /> + <Screenshots screenWidth={this.props.screenWidth} /> + <Features screenWidth={this.props.screenWidth} onGetStartedClick={this._onGetStartedClick} /> + {!this._isSmallScreen() && <Configurator hash={CONFIGURATOR_HASH} />} + <NeedMore screenWidth={this.props.screenWidth} /> + <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} /> + </Container> + ); + } + private readonly _onGetStartedClick = () => { + if (this._isSmallScreen()) { + utils.openUrl(`${utils.getCurrentBaseUrl()}/wiki#Get-Started`); + } else { + this._scrollToConfigurator(); + } + }; + private _isSmallScreen(): boolean { + const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm; + return isSmallScreen; + } + private _scrollToConfigurator(): void { + sharedUtils.setUrlHash(CONFIGURATOR_HASH); + sharedUtils.scrollToHash(CONFIGURATOR_HASH, ''); + } + private _updateScreenWidth(): void { + const newScreenWidth = utils.getScreenWidth(); + this.props.dispatcher.updateScreenWidth(newScreenWidth); + } +} diff --git a/packages/website/ts/pages/instant/introducing_0x_instant.tsx b/packages/website/ts/pages/instant/introducing_0x_instant.tsx new file mode 100644 index 000000000..da3f09faa --- /dev/null +++ b/packages/website/ts/pages/instant/introducing_0x_instant.tsx @@ -0,0 +1,57 @@ +import * as React from 'react'; + +import { Button } from 'ts/components/ui/button'; +import { Container } from 'ts/components/ui/container'; +import { Text } from 'ts/components/ui/text'; +import { colors } from 'ts/style/colors'; +import { ScreenWidths } from 'ts/types'; + +export interface Introducing0xInstantProps { + screenWidth: ScreenWidths; + onCTAClick: () => void; +} + +export const Introducing0xInstant = (props: Introducing0xInstantProps) => { + const isSmallScreen = props.screenWidth === ScreenWidths.Sm; + const zero = ( + <Text fontColor={colors.white} fontSize="42px" fontWeight="600" fontFamily="Roboto Mono" Tag="span"> + 0 + </Text> + ); + const title = isSmallScreen ? ( + <div> + Introducing<br /> + {zero}x Instant + </div> + ) : ( + <div>Introducing {zero}x Instant</div> + ); + return ( + <div className="clearfix center lg-pt4 md-pt4" style={{ backgroundColor: colors.instantPrimaryBackground }}> + <div className="mx-auto inline-block align-middle py4" style={{ lineHeight: '44px', textAlign: 'center' }}> + <Container className="sm-center sm-pt3"> + <Text fontColor={colors.white} fontSize="42px" lineHeight="52px" fontWeight="600"> + {title} + </Text> + </Container> + <Container className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 sm-center" maxWidth="600px"> + <Text fontColor={colors.grey500} fontSize="20px" lineHeight="32px" fontFamily="Roboto Mono"> + A free and flexible way to offer simple crypto + <br /> purchasing in any app or website. + </Text> + </Container> + <div className="py3"> + <Button + type="button" + backgroundColor={colors.mediumBlue} + fontColor={colors.white} + fontSize="18px" + onClick={props.onCTAClick} + > + Get Started + </Button> + </div> + </div> + </div> + ); +}; diff --git a/packages/website/ts/pages/instant/need_more.tsx b/packages/website/ts/pages/instant/need_more.tsx new file mode 100644 index 000000000..e6d5c3694 --- /dev/null +++ b/packages/website/ts/pages/instant/need_more.tsx @@ -0,0 +1,62 @@ +import * as React from 'react'; + +import { Button } from 'ts/components/ui/button'; +import { Container } from 'ts/components/ui/container'; +import { Text } from 'ts/components/ui/text'; +import { colors } from 'ts/style/colors'; +import { ScreenWidths } from 'ts/types'; +import { constants } from 'ts/utils/constants'; +import { utils } from 'ts/utils/utils'; + +export interface NeedMoreProps { + screenWidth: ScreenWidths; +} +export const NeedMore = (props: NeedMoreProps) => { + const isSmallScreen = props.screenWidth === ScreenWidths.Sm; + const backgroundColor = isSmallScreen ? colors.instantTertiaryBackground : colors.instantSecondaryBackground; + const className = isSmallScreen ? 'flex flex-column items-center' : 'flex'; + const marginRight = isSmallScreen ? undefined : '200px'; + return ( + <Container className="flex flex-column items-center py4 px3" backgroundColor={backgroundColor}> + <Container className={className}> + <Container className="sm-center" marginRight={marginRight}> + <Text fontColor={colors.white} fontSize="32px" lineHeight="45px"> + Need more flexibility? + </Text> + <Text fontColor={colors.grey500} fontSize="18px" lineHeight="27px"> + View our full documentation or reach out if you have any questions. + </Text> + </Container> + <Container className="py3 flex"> + <Container marginRight="20px"> + <Button + type="button" + backgroundColor={colors.white} + fontColor={backgroundColor} + fontSize="18px" + onClick={onGetInTouchClick} + > + Get in Touch + </Button> + </Container> + <Button + type="button" + backgroundColor={colors.mediumBlue} + fontColor={colors.white} + fontSize="18px" + onClick={onDocsClick} + > + Explore the Docs + </Button> + </Container> + </Container> + </Container> + ); +}; + +const onGetInTouchClick = () => { + utils.openUrl(constants.URL_ZEROEX_CHAT); +}; +const onDocsClick = () => { + utils.openUrl(`${utils.getCurrentBaseUrl()}/wiki#Get-Started`); +}; diff --git a/packages/website/ts/pages/instant/screenshots.tsx b/packages/website/ts/pages/instant/screenshots.tsx new file mode 100644 index 000000000..7dcf17fd1 --- /dev/null +++ b/packages/website/ts/pages/instant/screenshots.tsx @@ -0,0 +1,35 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { Container } from 'ts/components/ui/container'; +import { colors } from 'ts/style/colors'; +import { ScreenWidths } from 'ts/types'; + +export interface ScreenshotsProps { + screenWidth: ScreenWidths; +} + +export const Screenshots = (props: ScreenshotsProps) => { + const isSmallScreen = props.screenWidth === ScreenWidths.Sm; + const images = isSmallScreen + ? [ + 'images/instant/rep_screenshot.png', + 'images/instant/dai_screenshot.png', + 'images/instant/gods_screenshot.png', + ] + : [ + 'images/instant/nmr_screenshot.png', + 'images/instant/kitty_screenshot.png', + 'images/instant/rep_screenshot.png', + 'images/instant/dai_screenshot.png', + 'images/instant/gods_screenshot.png', + 'images/instant/gnt_screenshot.png', + ]; + return ( + <Container backgroundColor={colors.instantPrimaryBackground} className="py3 flex justify-center"> + {_.map(images, image => { + return <img className="px1 flex-none" width="300px" height="420px" src={image} key={image} />; + })} + </Container> + ); +}; |