diff options
author | Jacob Evans <dekz@dekz.net> | 2018-06-18 19:50:35 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-18 19:50:35 +0800 |
commit | 190eafc30e2e444ed15b76217a6162ec04b33f73 (patch) | |
tree | b20cbad73ff7a069dc0f0ef43ebc0373c714ad02 /packages/website/ts/pages | |
parent | d4ee0e862297c16f8ee62efccd31f1193052c64e (diff) | |
parent | 0c238448fda99c4d7997901d0fe4d72cb06b79cc (diff) | |
download | dexon-sol-tools-190eafc30e2e444ed15b76217a6162ec04b33f73.tar dexon-sol-tools-190eafc30e2e444ed15b76217a6162ec04b33f73.tar.gz dexon-sol-tools-190eafc30e2e444ed15b76217a6162ec04b33f73.tar.bz2 dexon-sol-tools-190eafc30e2e444ed15b76217a6162ec04b33f73.tar.lz dexon-sol-tools-190eafc30e2e444ed15b76217a6162ec04b33f73.tar.xz dexon-sol-tools-190eafc30e2e444ed15b76217a6162ec04b33f73.tar.zst dexon-sol-tools-190eafc30e2e444ed15b76217a6162ec04b33f73.zip |
Merge branch 'v2-prototype' into bug/contracts/eip712-191-prefix
Diffstat (limited to 'packages/website/ts/pages')
-rw-r--r-- | packages/website/ts/pages/about/about.tsx | 1 | ||||
-rw-r--r-- | packages/website/ts/pages/documentation/doc_page.tsx | 5 | ||||
-rw-r--r-- | packages/website/ts/pages/faq/question.tsx | 1 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/benefits.tsx | 109 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/jobs.tsx | 81 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/join_0x.tsx | 41 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/list/header_item.tsx | 26 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/list/list_item.tsx | 15 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/mission.tsx | 56 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/open_positions.tsx | 192 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/photo_rail.tsx | 22 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/teams.tsx | 90 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/values.tsx | 60 | ||||
-rw-r--r-- | packages/website/ts/pages/landing/landing.tsx | 77 | ||||
-rw-r--r-- | packages/website/ts/pages/not_found.tsx | 4 | ||||
-rw-r--r-- | packages/website/ts/pages/wiki/wiki.tsx | 10 |
16 files changed, 719 insertions, 71 deletions
diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx index ac67ca968..3136dbca3 100644 --- a/packages/website/ts/pages/about/about.tsx +++ b/packages/website/ts/pages/about/about.tsx @@ -8,7 +8,6 @@ import { TopBar } from 'ts/components/top_bar/top_bar'; import { Profile } from 'ts/pages/about/profile'; import { Dispatcher } from 'ts/redux/dispatcher'; import { ProfileInfo, WebsitePaths } from 'ts/types'; -import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; import { utils } from 'ts/utils/utils'; diff --git a/packages/website/ts/pages/documentation/doc_page.tsx b/packages/website/ts/pages/documentation/doc_page.tsx index 17efc56ed..8159bbd49 100644 --- a/packages/website/ts/pages/documentation/doc_page.tsx +++ b/packages/website/ts/pages/documentation/doc_page.tsx @@ -1,5 +1,4 @@ -import { DocAgnosticFormat, DocsInfo, Documentation, DoxityDocObj } from '@0xproject/react-docs'; -import { MenuSubsectionsBySection } from '@0xproject/react-shared'; +import { DocAgnosticFormat, DocsInfo, Documentation } from '@0xproject/react-docs'; import findVersions = require('find-versions'); import * as _ from 'lodash'; import * as React from 'react'; @@ -9,7 +8,6 @@ import { SidebarHeader } from 'ts/components/sidebar_header'; import { TopBar } from 'ts/components/top_bar/top_bar'; import { Dispatcher } from 'ts/redux/dispatcher'; import { DocPackages } from 'ts/types'; -import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { docUtils } from 'ts/utils/doc_utils'; import { Translate } from 'ts/utils/translate'; @@ -35,6 +33,7 @@ const docIdToSubpackageName: { [id: string]: string } = { [DocPackages.SolCov]: 'sol-cov', [DocPackages.Subproviders]: 'subproviders', [DocPackages.OrderUtils]: 'order-utils', + [DocPackages.EthereumTypes]: 'ethereum-types', }; export interface DocPageProps { diff --git a/packages/website/ts/pages/faq/question.tsx b/packages/website/ts/pages/faq/question.tsx index 28ea6881a..f80985257 100644 --- a/packages/website/ts/pages/faq/question.tsx +++ b/packages/website/ts/pages/faq/question.tsx @@ -1,5 +1,4 @@ import { colors } from '@0xproject/react-shared'; -import * as _ from 'lodash'; import { Card, CardHeader, CardText } from 'material-ui/Card'; import * as React from 'react'; diff --git a/packages/website/ts/pages/jobs/benefits.tsx b/packages/website/ts/pages/jobs/benefits.tsx new file mode 100644 index 000000000..006facc83 --- /dev/null +++ b/packages/website/ts/pages/jobs/benefits.tsx @@ -0,0 +1,109 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { FilledImage } from 'ts/components/ui/filled_image'; +import { HeaderItem } from 'ts/pages/jobs/list/header_item'; +import { ListItem } from 'ts/pages/jobs/list/list_item'; +import { colors } from 'ts/style/colors'; +import { ScreenWidths } from 'ts/types'; + +const IMAGE_PATHS = ['/images/jobs/location1.png', '/images/jobs/location2.png', '/images/jobs/location3.png']; +const BENEFIT_ITEM_PROPS_LIST: BenefitItemProps[] = [ + { + bulletColor: '#6FCF97', + description: + 'Donec eget auctor mauris, a imperdiet ante. Ut a tellus ullamcorper, pharetra nibh sed, dignissim mauris. Quisque vel magna vitae nisi scelerisque commodo sed eget dolor. Maecenas vehicula orci', + }, + { + bulletColor: '#56CCF2', + description: + 'Donec eget auctor mauris, a imperdiet ante. Ut a tellus ullamcorper, pharetra nibh sed, dignissim mauris. Quisque vel magna vitae nisi scelerisque commodo sed eget dolor. Maecenas vehicula orci', + }, + { + bulletColor: '#EB5757', + description: + 'Donec eget auctor mauris, a imperdiet ante. Ut a tellus ullamcorper, pharetra nibh sed, dignissim mauris. Quisque vel magna vitae nisi scelerisque commodo sed eget dolor. Maecenas vehicula orci', + }, + { + bulletColor: '#6FCF97', + description: + 'Donec eget auctor mauris, a imperdiet ante. Ut a tellus ullamcorper, pharetra nibh sed, dignissim mauris. Quisque vel magna vitae nisi scelerisque commodo sed eget dolor. Maecenas vehicula orci', + }, + { + bulletColor: '#56CCF2', + description: + 'Donec eget auctor mauris, a imperdiet ante. Ut a tellus ullamcorper, pharetra nibh sed, dignissim mauris. Quisque vel magna vitae nisi scelerisque commodo sed eget dolor. Maecenas vehicula orci', + }, +]; +const LARGE_LAYOUT_HEIGHT = 937; +const LARGE_LAYOUT_BENEFITS_LIST_PADDING_LEFT = 205; +const HEADER_TEXT = 'Benefits'; +const BENEFIT_ITEM_MIN_HEIGHT = 150; + +export interface BenefitsProps { + screenWidth: ScreenWidths; +} + +export const Benefits = (props: BenefitsProps) => ( + <div style={{ backgroundColor: colors.jobsPageBackground }}> + {props.screenWidth === ScreenWidths.Sm ? <SmallLayout /> : <LargeLayout />} + </div> +); + +const LargeLayout = () => ( + <div className="flex" style={{ height: LARGE_LAYOUT_HEIGHT }}> + <div style={{ width: '43%', height: '100%' }}> + <ImageGrid /> + </div> + <div + className="pr4" + style={{ paddingLeft: LARGE_LAYOUT_BENEFITS_LIST_PADDING_LEFT, width: '57%', height: '100%' }} + > + <BenefitsList /> + </div> + </div> +); + +const SmallLayout = () => ( + <div> + <FilledImage src={_.head(IMAGE_PATHS)} /> + <BenefitsList /> + </div> +); + +export const BenefitsList = () => { + return ( + <div> + <HeaderItem headerText={HEADER_TEXT} /> + {_.map(BENEFIT_ITEM_PROPS_LIST, valueItemProps => <BenefitItem {...valueItemProps} />)} + </div> + ); +}; +interface BenefitItemProps { + bulletColor: string; + description: string; +} + +const BenefitItem: React.StatelessComponent<BenefitItemProps> = ({ bulletColor, description }) => ( + <div style={{ minHeight: BENEFIT_ITEM_MIN_HEIGHT }}> + <ListItem bulletColor={bulletColor}> + <div style={{ fontSize: 16, lineHeight: 1.5 }}>{description}</div> + </ListItem> + </div> +); + +const ImageGrid = () => ( + <div style={{ width: '100%', height: '100%' }}> + <div className="flex" style={{ height: '67%' }}> + <FilledImage src={IMAGE_PATHS[0]} /> + </div> + <div className="clearfix" style={{ height: '33%' }}> + <div className="col lg-col-6 md-col-6 col-12" style={{ height: '100%' }}> + <FilledImage src={IMAGE_PATHS[1]} /> + </div> + <div className="col lg-col-6 md-col-6 col-12" style={{ height: '100%' }}> + <FilledImage src={IMAGE_PATHS[2]} /> + </div> + </div> + </div> +); diff --git a/packages/website/ts/pages/jobs/jobs.tsx b/packages/website/ts/pages/jobs/jobs.tsx new file mode 100644 index 000000000..314669ee9 --- /dev/null +++ b/packages/website/ts/pages/jobs/jobs.tsx @@ -0,0 +1,81 @@ +import { colors, utils as sharedUtils } from '@0xproject/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 { TopBar } from 'ts/components/top_bar/top_bar'; +import { FilledImage } from 'ts/components/ui/filled_image'; +import { Benefits } from 'ts/pages/jobs/benefits'; +import { Join0x } from 'ts/pages/jobs/join_0x'; +import { Mission } from 'ts/pages/jobs/mission'; +import { OpenPositions } from 'ts/pages/jobs/open_positions'; +import { PhotoRail } from 'ts/pages/jobs/photo_rail'; +import { Teams } from 'ts/pages/jobs/teams'; +import { Values } from 'ts/pages/jobs/values'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { ScreenWidths } from 'ts/types'; +import { Translate } from 'ts/utils/translate'; +import { utils } from 'ts/utils/utils'; + +const OPEN_POSITIONS_HASH = 'positions'; +const THROTTLE_TIMEOUT = 100; +const PHOTO_RAIL_IMAGES = ['/images/jobs/office1.png', '/images/jobs/office2.png', '/images/jobs/office3.png']; + +export interface JobsProps { + location: Location; + translate: Translate; + dispatcher: Dispatcher; + screenWidth: ScreenWidths; +} + +export interface JobsState {} + +export class Jobs extends React.Component<JobsProps, JobsState> { + // TODO: consolidate this small screen scaffolding into one place (its being used in portal and docs as well) + private _throttledScreenWidthUpdate: () => void; + public constructor(props: JobsProps) { + 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 ( + <div> + <DocumentTitle title="Jobs" /> + <TopBar + blockchainIsLoaded={false} + location={this.props.location} + style={{ backgroundColor: colors.white, position: 'relative' }} + translate={this.props.translate} + /> + <Join0x onCallToActionClick={this._onJoin0xCallToActionClick.bind(this)} /> + <Mission screenWidth={this.props.screenWidth} /> + {this._isSmallScreen() ? ( + <FilledImage src={_.head(PHOTO_RAIL_IMAGES)} /> + ) : ( + <PhotoRail images={PHOTO_RAIL_IMAGES} /> + )} + <Values /> + <Benefits screenWidth={this.props.screenWidth} /> + <Teams screenWidth={this.props.screenWidth} /> + <OpenPositions hash={OPEN_POSITIONS_HASH} screenWidth={this.props.screenWidth} /> + <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} /> + </div> + ); + } + private _onJoin0xCallToActionClick(): void { + sharedUtils.setUrlHash(OPEN_POSITIONS_HASH); + } + private _updateScreenWidth(): void { + const newScreenWidth = utils.getScreenWidth(); + this.props.dispatcher.updateScreenWidth(newScreenWidth); + } + private _isSmallScreen(): boolean { + const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm; + return isSmallScreen; + } +} diff --git a/packages/website/ts/pages/jobs/join_0x.tsx b/packages/website/ts/pages/jobs/join_0x.tsx new file mode 100644 index 000000000..72cce3b89 --- /dev/null +++ b/packages/website/ts/pages/jobs/join_0x.tsx @@ -0,0 +1,41 @@ +import { colors } from '@0xproject/react-shared'; + +import * as React from 'react'; + +import { Button } from 'ts/components/ui/button'; + +const BUTTON_TEXT = 'view open positions'; + +export interface Join0xProps { + onCallToActionClick: () => void; +} + +export const Join0x = (props: Join0xProps) => ( + <div className="clearfix center lg-py4 md-py4" style={{ backgroundColor: colors.white, color: colors.black }}> + <div className="mx-auto inline-block align-middle py4" style={{ lineHeight: '44px', textAlign: 'center' }}> + <div className="h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}> + Join 0x + </div> + <div + className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 h4 sm-center" + style={{ fontFamily: 'Roboto', lineHeight: 2, maxWidth: 537 }} + > + 0x is transforming the way that value is exchanged on a global scale. Come join us in San Francisco or + work remotely anywhere in the world to help create the infrastructure of a new tokenized economy. + </div> + <div className="py3"> + <Button + type="button" + backgroundColor={colors.black} + width="290px" + fontColor={colors.white} + fontSize="18px" + fontFamily="Roboto Mono" + onClick={props.onCallToActionClick} + > + {BUTTON_TEXT} + </Button> + </div> + </div> + </div> +); diff --git a/packages/website/ts/pages/jobs/list/header_item.tsx b/packages/website/ts/pages/jobs/list/header_item.tsx new file mode 100644 index 000000000..ac214904c --- /dev/null +++ b/packages/website/ts/pages/jobs/list/header_item.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; + +import { Text } from 'ts/components/ui/text'; +import { ListItem } from 'ts/pages/jobs/list/list_item'; +import { colors } from 'ts/style/colors'; + +export interface HeaderItemProps { + headerText?: string; +} +export const HeaderItem: React.StatelessComponent<HeaderItemProps> = ({ headerText }) => { + return ( + <div className="h2 lg-py4 md-py4 sm-py3"> + <ListItem> + <Text + fontFamily="Roboto Mono" + fontSize="24px" + lineHeight="1.25" + minHeight="1.25em" + fontColor={colors.black} + > + {headerText} + </Text> + </ListItem> + </div> + ); +}; diff --git a/packages/website/ts/pages/jobs/list/list_item.tsx b/packages/website/ts/pages/jobs/list/list_item.tsx new file mode 100644 index 000000000..d7838bc01 --- /dev/null +++ b/packages/website/ts/pages/jobs/list/list_item.tsx @@ -0,0 +1,15 @@ +import * as React from 'react'; + +export interface ListItemProps { + bulletColor?: string; +} +export const ListItem: React.StatelessComponent<ListItemProps> = ({ bulletColor, children }) => { + return ( + <div className="flex items-center"> + <svg className="flex-none lg-px2 md-px2 sm-pl2" height="26" width="26"> + <circle cx="13" cy="13" r="13" fill={bulletColor || 'transparent'} /> + </svg> + <div className="flex-auto px2">{children}</div> + </div> + ); +}; diff --git a/packages/website/ts/pages/jobs/mission.tsx b/packages/website/ts/pages/jobs/mission.tsx new file mode 100644 index 000000000..f7f874e04 --- /dev/null +++ b/packages/website/ts/pages/jobs/mission.tsx @@ -0,0 +1,56 @@ +import * as React from 'react'; + +import { colors } from 'ts/style/colors'; +import { ScreenWidths } from 'ts/types'; + +export interface MissionProps { + screenWidth: ScreenWidths; +} +export const Mission = (props: MissionProps) => { + const isSmallScreen = props.screenWidth === ScreenWidths.Sm; + const image = ( + <div className="col lg-col-6 md-col-6 col-12 sm-py2 px2 center"> + <img src="/images/jobs/map.png" style={{ width: '100%' }} /> + </div> + ); + const missionStatementStyle = !isSmallScreen ? { height: 364, lineHeight: '364px' } : undefined; + const missionStatement = ( + <div className="col lg-col-6 md-col-6 col-12 center" style={missionStatementStyle}> + <div + className="mx-auto inline-block align-middle" + style={{ maxWidth: 385, lineHeight: '44px', textAlign: 'center' }} + > + <div className="h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}> + Our Mission + </div> + <div + className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 h4 sm-center" + style={{ fontFamily: 'Roboto', lineHeight: 2, maxWidth: 537 }} + > + We believe a system can exist in which all world value is accessible to anyone, anywhere, regardless + of where you happen to be born. + </div> + </div> + </div> + ); + return ( + <div + className="container lg-py4 md-py4" + style={{ backgroundColor: colors.jobsPageBackground, color: colors.black }} + > + <div className="mx-auto clearfix sm-py4"> + {isSmallScreen ? ( + <div> + {missionStatement} + {image} + </div> + ) : ( + <div> + {image} + {missionStatement} + </div> + )} + </div> + </div> + ); +}; diff --git a/packages/website/ts/pages/jobs/open_positions.tsx b/packages/website/ts/pages/jobs/open_positions.tsx new file mode 100644 index 000000000..f3d980315 --- /dev/null +++ b/packages/website/ts/pages/jobs/open_positions.tsx @@ -0,0 +1,192 @@ +import * as _ from 'lodash'; +import CircularProgress from 'material-ui/CircularProgress'; +import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table'; +import * as React from 'react'; + +import { Retry } from 'ts/components/ui/retry'; +import { Text } from 'ts/components/ui/text'; +import { HeaderItem } from 'ts/pages/jobs/list/header_item'; +import { ListItem } from 'ts/pages/jobs/list/list_item'; +import { colors } from 'ts/style/colors'; +import { styled } from 'ts/style/theme'; +import { ScreenWidths, WebsiteBackendJobInfo } from 'ts/types'; +import { backendClient } from 'ts/utils/backend_client'; + +const labelStyle = { fontFamily: 'Roboto Mono', fontSize: 18 }; +const HEADER_TEXT = 'Open Positions'; +const TABLE_ROW_MIN_HEIGHT = 100; + +export interface OpenPositionsProps { + hash: string; + screenWidth: ScreenWidths; +} +export interface OpenPositionsState { + jobInfos?: WebsiteBackendJobInfo[]; + error?: Error; +} + +export class OpenPositions extends React.Component<OpenPositionsProps, OpenPositionsState> { + private _isUnmounted: boolean; + constructor(props: OpenPositionsProps) { + super(props); + this._isUnmounted = false; + this.state = { + jobInfos: undefined, + error: undefined, + }; + } + public componentWillMount(): void { + // tslint:disable-next-line:no-floating-promises + this._fetchJobInfosAsync(); + } + public componentWillUnmount(): void { + this._isUnmounted = true; + } + public render(): React.ReactNode { + const isReadyToRender = _.isUndefined(this.state.error) && !_.isUndefined(this.state.jobInfos); + return ( + <div id={this.props.hash} className="mx-auto max-width-4"> + {isReadyToRender ? this._renderBody() : this._renderLoading()} + </div> + ); + } + private _renderBody(): React.ReactNode { + const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm; + return isSmallScreen ? this._renderList() : this._renderTable(); + } + private _renderLoading(): React.ReactNode { + return ( + // TODO: consolidate this loading component with the one in portal and RelayerIndex + // TODO: possibly refactor into a generic loading container with spinner and retry UI + <div className="center"> + {_.isUndefined(this.state.error) ? ( + <CircularProgress size={40} thickness={5} /> + ) : ( + <Retry onRetry={this._fetchJobInfosAsync.bind(this)} /> + )} + </div> + ); + } + private _renderList(): React.ReactNode { + return ( + <div style={{ backgroundColor: colors.jobsPageBackground }}> + <HeaderItem headerText={HEADER_TEXT} /> + {_.map(this.state.jobInfos, jobInfo => ( + <JobInfoListItem + key={jobInfo.id} + title={jobInfo.title} + description={jobInfo.department} + onClick={this._openJobInfoUrl.bind(this, jobInfo)} + /> + ))} + </div> + ); + } + private _renderTable(): React.ReactNode { + return ( + <div> + <HeaderItem headerText={HEADER_TEXT} /> + <Table selectable={false} onCellClick={this._onCellClick.bind(this)}> + <TableHeader displaySelectAll={false} adjustForCheckbox={false}> + <TableRow> + <TableHeaderColumn colSpan={5} style={labelStyle}> + Position + </TableHeaderColumn> + <TableHeaderColumn colSpan={3} style={labelStyle}> + Department + </TableHeaderColumn> + <TableHeaderColumn colSpan={4} style={labelStyle}> + Office + </TableHeaderColumn> + </TableRow> + </TableHeader> + <TableBody displayRowCheckbox={false} showRowHover={true}> + {_.map(this.state.jobInfos, jobInfo => { + return this._renderJobInfoTableRow(jobInfo); + })} + </TableBody> + </Table> + </div> + ); + } + private _renderJobInfoTableRow(jobInfo: WebsiteBackendJobInfo): React.ReactNode { + return ( + <TableRow + key={jobInfo.id} + hoverable={true} + displayBorder={false} + style={{ height: TABLE_ROW_MIN_HEIGHT, border: 2 }} + > + <TableRowColumn colSpan={5} style={labelStyle}> + {jobInfo.title} + </TableRowColumn> + <TableRowColumn colSpan={3} style={labelStyle}> + {jobInfo.department} + </TableRowColumn> + <TableRowColumn colSpan={4} style={labelStyle}> + {jobInfo.office} + </TableRowColumn> + </TableRow> + ); + } + private async _fetchJobInfosAsync(): Promise<void> { + try { + if (!this._isUnmounted) { + this.setState({ + jobInfos: undefined, + error: undefined, + }); + } + const jobInfos = await backendClient.getJobInfosAsync(); + if (!this._isUnmounted) { + this.setState({ + jobInfos, + }); + } + } catch (error) { + if (!this._isUnmounted) { + this.setState({ + error, + }); + } + } + } + private _onCellClick(rowNumber: number): void { + if (_.isUndefined(this.state.jobInfos)) { + return; + } + const jobInfo = this.state.jobInfos[rowNumber]; + this._openJobInfoUrl(jobInfo); + } + + private _openJobInfoUrl(jobInfo: WebsiteBackendJobInfo): void { + const url = jobInfo.url; + window.open(url, '_blank'); + } +} + +export interface JobInfoListItemProps { + title?: string; + description?: string; + onClick?: (event: React.MouseEvent<HTMLElement>) => void; +} + +const PlainJobInfoListItem: React.StatelessComponent<JobInfoListItemProps> = ({ title, description, onClick }) => ( + <div className="mb3" onClick={onClick}> + <ListItem> + <Text fontWeight="bold" fontSize="16px" fontColor={colors.mediumBlue}> + {title + ' ›'} + </Text> + <Text className="pt1" fontSize="16px" fontColor={colors.darkGrey}> + {description} + </Text> + </ListItem> + </div> +); + +export const JobInfoListItem = styled(PlainJobInfoListItem)` + cursor: pointer; + &:hover { + opacity: 0.5; + } +`; diff --git a/packages/website/ts/pages/jobs/photo_rail.tsx b/packages/website/ts/pages/jobs/photo_rail.tsx new file mode 100644 index 000000000..acc9dcb91 --- /dev/null +++ b/packages/website/ts/pages/jobs/photo_rail.tsx @@ -0,0 +1,22 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { FilledImage } from 'ts/components/ui/filled_image'; + +export interface PhotoRailProps { + images: string[]; +} + +export const PhotoRail = (props: PhotoRailProps) => { + return ( + <div className="clearfix" style={{ height: 490 }}> + {_.map(props.images, (image: string) => { + return ( + <div key={image} className="col lg-col-4 md-col-4 col-12 center" style={{ height: '100%' }}> + <FilledImage src={image} /> + </div> + ); + })} + </div> + ); +}; diff --git a/packages/website/ts/pages/jobs/teams.tsx b/packages/website/ts/pages/jobs/teams.tsx new file mode 100644 index 000000000..80b036396 --- /dev/null +++ b/packages/website/ts/pages/jobs/teams.tsx @@ -0,0 +1,90 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { Text } from 'ts/components/ui/text'; +import { HeaderItem } from 'ts/pages/jobs/list/header_item'; +import { ListItem } from 'ts/pages/jobs/list/list_item'; +import { colors } from 'ts/style/colors'; +import { ScreenWidths } from 'ts/types'; + +const TEAM_ITEM_PROPS_COLUMN1: TeamItemProps[] = [ + { + bulletColor: '#EB5757', + title: 'User Growth', + description: + 'Donec eget auctor mauris, a imperdiet ante. Ut a tellus ullamcorper, pharetra nibh sed, dignissim mauris. Quisque vel magna vitae nisi scelerisque commodo sed eget dolor. Maecenas vehicula orci', + }, + { + bulletColor: '#EB5757', + title: 'Governance', + description: + 'Donec eget auctor mauris, a imperdiet ante. Ut a tellus ullamcorper, pharetra nibh sed, dignissim mauris. Quisque vel magna vitae nisi scelerisque commodo sed eget dolor. Maecenas vehicula orci', + }, +]; +const TEAM_ITEM_PROPS_COLUMN2: TeamItemProps[] = [ + { + bulletColor: '#EB5757', + title: 'Developer Tools', + description: + 'Donec eget auctor mauris, a imperdiet ante. Ut a tellus ullamcorper, pharetra nibh sed, dignissim mauris. Quisque vel magna vitae nisi scelerisque commodo sed eget dolor. Maecenas vehicula orci', + }, + { + bulletColor: '#EB5757', + title: 'Marketing', + description: + 'Donec eget auctor mauris, a imperdiet ante. Ut a tellus ullamcorper, pharetra nibh sed, dignissim mauris. Quisque vel magna vitae nisi scelerisque commodo sed eget dolor. Maecenas vehicula orci', + }, +]; +const HEADER_TEXT = 'Our Teams'; +const MINIMUM_ITEM_HEIGHT = 240; + +export interface TeamsProps { + screenWidth: ScreenWidths; +} + +export const Teams = (props: TeamsProps) => (props.screenWidth === ScreenWidths.Sm ? <SmallLayout /> : <LargeLayout />); + +const LargeLayout = () => ( + <div className="mx-auto max-width-4 clearfix pb4"> + <div className="col lg-col-6 md-col-6 col-12"> + <HeaderItem headerText={HEADER_TEXT} /> + {_.map(TEAM_ITEM_PROPS_COLUMN1, teamItemProps => <TeamItem {...teamItemProps} />)} + </div> + <div className="col lg-col-6 md-col-6 col-12"> + <HeaderItem headerText=" " /> + {_.map(TEAM_ITEM_PROPS_COLUMN2, teamItemProps => <TeamItem {...teamItemProps} />)} + </div> + </div> +); + +const SmallLayout = () => ( + <div> + <HeaderItem headerText={HEADER_TEXT} /> + {_.map(_.concat(TEAM_ITEM_PROPS_COLUMN1, TEAM_ITEM_PROPS_COLUMN2), teamItemProps => ( + <TeamItem {...teamItemProps} /> + ))} + </div> +); + +interface TeamItemProps { + bulletColor: string; + title: string; + description: string; +} + +export const TeamItem: React.StatelessComponent<TeamItemProps> = ({ bulletColor, title, description }) => { + return ( + <div style={{ minHeight: MINIMUM_ITEM_HEIGHT }}> + <ListItem bulletColor={bulletColor}> + <Text fontWeight="bold" fontSize="16px" fontColor={colors.black}> + {title} + </Text> + </ListItem> + <ListItem> + <Text className="pt1" fontSize="16px" lineHeight="2em" fontColor={colors.black}> + {description} + </Text> + </ListItem> + </div> + ); +}; diff --git a/packages/website/ts/pages/jobs/values.tsx b/packages/website/ts/pages/jobs/values.tsx new file mode 100644 index 000000000..c7c4d5726 --- /dev/null +++ b/packages/website/ts/pages/jobs/values.tsx @@ -0,0 +1,60 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { Text } from 'ts/components/ui/text'; +import { HeaderItem } from 'ts/pages/jobs/list/header_item'; +import { ListItem } from 'ts/pages/jobs/list/list_item'; +import { colors } from 'ts/style/colors'; + +const VALUE_ITEM_PROPS_LIST: ValueItemProps[] = [ + { + bulletColor: '#6FCF97', + title: 'Ethics/Doing the right thing', + description: 'orem ipsum dolor sit amet, consectetur adipiscing elit.', + }, + { + bulletColor: '#56CCF2', + title: 'Consistently ship', + description: 'orem ipsum dolor sit amet, consectetur adipiscing elit.', + }, + { + bulletColor: '#EB5757', + title: 'Focus on long term impact', + description: 'orem ipsum dolor sit amet, consectetur adipiscing elit.', + }, +]; + +const HEADER_TEXT = 'Our Values'; +const VALUE_ITEM_MIN_HEIGHT = 150; + +export const Values = () => { + return ( + <div className="mx-auto max-width-4"> + <HeaderItem headerText={HEADER_TEXT} /> + {_.map(VALUE_ITEM_PROPS_LIST, valueItemProps => <ValueItem {...valueItemProps} />)} + </div> + ); +}; + +interface ValueItemProps { + bulletColor: string; + title: string; + description: string; +} + +export const ValueItem: React.StatelessComponent<ValueItemProps> = ({ bulletColor, title, description }) => { + return ( + <div style={{ minHeight: VALUE_ITEM_MIN_HEIGHT }}> + <ListItem bulletColor={bulletColor}> + <Text fontWeight="bold" fontSize="16x" fontColor={colors.black}> + {title} + </Text> + </ListItem> + <ListItem> + <Text className="pt1" fontSize="16x" lineHeight="2em" fontColor={colors.black}> + {description} + </Text> + </ListItem> + </div> + ); +}; diff --git a/packages/website/ts/pages/landing/landing.tsx b/packages/website/ts/pages/landing/landing.tsx index 02ecfa117..f091778f4 100644 --- a/packages/website/ts/pages/landing/landing.tsx +++ b/packages/website/ts/pages/landing/landing.tsx @@ -1,11 +1,13 @@ import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; -import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; import DocumentTitle = require('react-document-title'); import { Link } from 'react-router-dom'; 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 { Dispatcher } from 'ts/redux/dispatcher'; import { Deco, Key, Language, ScreenWidths, WebsitePaths } from 'ts/types'; import { constants } from 'ts/utils/constants'; @@ -220,23 +222,12 @@ export class Landing extends React.Component<LandingProps, LandingState> { } private _renderHero(): React.ReactNode { 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-pl4 md-pl4 sm-pl0 sm-px3 sm-center'; return ( <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}> <div className="mx-auto max-width-4 clearfix"> {this._renderWhatsNew()} - <div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-my4 md-my4 sm-mt2 sm-mb4 clearfix"> + <div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-mt4 md-mt4 sm-mt2 sm-mb4 clearfix"> <div className="col lg-col-5 md-col-5 col-12 sm-center"> <img src="/images/landing/hero_chip_image.png" height={isSmallScreen ? 300 : 395} /> </div> @@ -268,40 +259,31 @@ export class Landing extends React.Component<LandingProps, LandingState> { > {this.props.translate.get(Key.TopTagline)} </div> - <div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 389 }}> - <div className="lg-pr2 md-pr2 col col-6 sm-center"> + <Container className="pt3 clearfix sm-mx-auto" maxWidth="390px"> + <div className="lg-pr2 md-pr2 lg-col lg-col-6 sm-center sm-col sm-col-12 mb2"> <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none"> - <RaisedButton - style={{ borderRadius: 6, minWidth: 157.36 }} - buttonStyle={{ borderRadius: 6 }} - labelStyle={buttonLabelStyle} - label={this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} - onClick={_.noop} - /> + <CallToAction width="175px" type="light"> + {this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} + </CallToAction> </Link> </div> - <div className="col col-6 sm-center"> + <div className="lg-col lg-col-6 sm-center sm-col sm-col-12"> <a href={constants.URL_ZEROEX_CHAT} target="_blank" className="text-decoration-none" > - <RaisedButton - style={{ borderRadius: 6, minWidth: 150 }} - buttonStyle={lightButtonStyle} - labelColor="white" - backgroundColor={colors.heroGrey} - labelStyle={buttonLabelStyle} - label={this.props.translate.get(Key.CommunityCallToAction, Deco.Cap)} - onClick={_.noop} - /> + <CallToAction width="175px"> + {this.props.translate.get(Key.CommunityCallToAction, Deco.Cap)} + </CallToAction> </a> </div> - </div> + </Container> </div> </div> </div> </div> + {this.props.translate.getLanguage() === Language.English && <SubscribeForm />} </div> ); } @@ -349,6 +331,9 @@ export class Landing extends React.Component<LandingProps, LandingState> { 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`}> @@ -753,17 +738,6 @@ export class Landing extends React.Component<LandingProps, LandingState> { } private _renderCallToAction(): React.ReactNode { 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 ${colors.grey500}`, - lineHeight: '33px', - height: 49, - }; const callToActionClassNames = 'lg-pr3 md-pr3 lg-right-align md-right-align sm-center sm-px3 h4 lg-table-cell md-table-cell'; return ( @@ -782,15 +756,9 @@ export class Landing extends React.Component<LandingProps, LandingState> { </div> <div className="sm-center sm-pt2 lg-table-cell md-table-cell"> <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none"> - <RaisedButton - style={{ borderRadius: 6, minWidth: 150 }} - buttonStyle={lightButtonStyle} - labelColor={colors.white} - backgroundColor={colors.heroGrey} - labelStyle={buttonLabelStyle} - label={this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} - onClick={_.noop} - /> + <CallToAction fontSize="15px"> + {this.props.translate.get(Key.BuildCallToAction, Deco.Cap)} + </CallToAction> </Link> </div> </div> @@ -806,7 +774,4 @@ export class Landing extends React.Component<LandingProps, LandingState> { }); } } - private _onLanguageSelected(language: Language): void { - this.props.dispatcher.updateSelectedLanguage(language); - } } // tslint:disable:max-file-line-count diff --git a/packages/website/ts/pages/not_found.tsx b/packages/website/ts/pages/not_found.tsx index 674271636..2fe3b1f45 100644 --- a/packages/website/ts/pages/not_found.tsx +++ b/packages/website/ts/pages/not_found.tsx @@ -1,5 +1,3 @@ -import { Styles } from '@0xproject/react-shared'; -import * as _ from 'lodash'; import * as React from 'react'; import { Footer } from 'ts/components/footer'; import { TopBar } from 'ts/components/top_bar/top_bar'; @@ -13,7 +11,7 @@ export interface NotFoundProps { dispatcher: Dispatcher; } -export const NotFound = (props: NotFoundProps) => { +export const NotFound = (_props: NotFoundProps) => { return ( <div> <TopBar blockchainIsLoaded={false} location={this.props.location} translate={this.props.translate} /> diff --git a/packages/website/ts/pages/wiki/wiki.tsx b/packages/website/ts/pages/wiki/wiki.tsx index 720c1cc37..9659900be 100644 --- a/packages/website/ts/pages/wiki/wiki.tsx +++ b/packages/website/ts/pages/wiki/wiki.tsx @@ -4,23 +4,19 @@ import { HeaderSizes, MarkdownSection, NestedSidebarMenu, - SectionHeader, Styles, utils as sharedUtils, } from '@0xproject/react-shared'; -import { logUtils } from '@0xproject/utils'; import * as _ from 'lodash'; import CircularProgress from 'material-ui/CircularProgress'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; import DocumentTitle = require('react-document-title'); -import { scroller } from 'react-scroll'; import { SidebarHeader } from 'ts/components/sidebar_header'; import { TopBar } from 'ts/components/top_bar/top_bar'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { Article, ArticlesBySection, WebsitePaths } from 'ts/types'; +import { Article, ArticlesBySection } from 'ts/types'; import { backendClient } from 'ts/utils/backend_client'; -import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; import { utils } from 'ts/utils/utils'; @@ -237,7 +233,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> { } return menuSubsectionsBySection; } - private _onSidebarHover(event: React.FormEvent<HTMLInputElement>): void { + private _onSidebarHover(_event: React.FormEvent<HTMLInputElement>): void { this.setState({ isHoveringSidebar: true, }); @@ -247,7 +243,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> { isHoveringSidebar: false, }); } - private _onHashChanged(event: any): void { + private _onHashChanged(_event: any): void { const hash = window.location.hash.slice(1); sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID); } |