diff options
-rw-r--r-- | packages/website/ts/pages/jobs/benefits.tsx | 57 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/bulleted_item_list.tsx | 62 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/jobs.tsx | 2 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/list/header_item.tsx | 24 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/list/list_item.tsx | 15 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/open_positions.tsx | 112 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/teams.tsx | 42 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/values.tsx | 38 |
8 files changed, 232 insertions, 120 deletions
diff --git a/packages/website/ts/pages/jobs/benefits.tsx b/packages/website/ts/pages/jobs/benefits.tsx index a7cc23503..b27c68a5b 100644 --- a/packages/website/ts/pages/jobs/benefits.tsx +++ b/packages/website/ts/pages/jobs/benefits.tsx @@ -1,40 +1,45 @@ import * as _ from 'lodash'; import * as React from 'react'; -import { BulletedItemInfo, BulletedItemList } from 'ts/pages/jobs/bulleted_item_list'; import { FilledImage } from 'ts/pages/jobs/filled_image'; import { FloatingImage } from 'ts/pages/jobs/floating_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 BULLETED_ITEM_INFOS: BulletedItemInfo[] = [ +const BENEFIT_ITEM_PROPS_LIST: BenefitItemProps[] = [ { bulletColor: '#6FCF97', - title: 'Ethics/Doing the right thing', - description: 'orem ipsum dolor sit amet, consectetur adipiscing elit.', + 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', - title: 'Consistently ship', - description: 'orem ipsum dolor sit amet, consectetur adipiscing elit.', + 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: 'Focus on long term impact', - description: 'orem ipsum dolor sit amet, consectetur adipiscing elit.', + 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', - title: 'Test test yo', - description: 'orem ipsum dolor sit amet, consectetur adipiscing elit.', + 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', - title: 'Waddle Waddle', - description: 'orem ipsum dolor sit amet, consectetur adipiscing elit.', + 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; @@ -47,11 +52,14 @@ export const Benefits = (props: BenefitsProps) => ( ); const LargeLayout = () => ( - <div className="flex" style={{ height: 937 }}> + <div className="flex" style={{ height: LARGE_LAYOUT_HEIGHT }}> <div style={{ width: '43%', height: '100%' }}> <ImageGrid /> </div> - <div style={{ paddingLeft: 205, width: '57%', height: '100%' }}> + <div + className="pr4" + style={{ paddingLeft: LARGE_LAYOUT_BENEFITS_LIST_PADDING_LEFT, width: '57%', height: '100%' }} + > <BenefitsList /> </div> </div> @@ -64,7 +72,26 @@ const SmallLayout = () => ( </div> ); -const BenefitsList = () => <BulletedItemList headerText="Benefits" bulletedItemInfos={BULLETED_ITEM_INFOS} />; +export const BenefitsList = () => { + return ( + <div> + <HeaderItem headerText={HEADER_TEXT} /> + {_.map(BENEFIT_ITEM_PROPS_LIST, valueItemProps => React.createElement(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%' }}> diff --git a/packages/website/ts/pages/jobs/bulleted_item_list.tsx b/packages/website/ts/pages/jobs/bulleted_item_list.tsx deleted file mode 100644 index a00290418..000000000 --- a/packages/website/ts/pages/jobs/bulleted_item_list.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { colors } from '@0xproject/react-shared'; -import * as _ from 'lodash'; -import * as React from 'react'; - -export type BulletedItemInfo = BulletedItemProps; -export interface BulletedItemListProps { - headerText?: string; - bulletedItemInfos: BulletedItemInfo[]; -} -export const BulletedItemList = (props: BulletedItemListProps) => { - return ( - <div className="mx-auto max-width-4"> - {!_.isUndefined(props.headerText) && ( - <div - className="h2 lg-py4 md-py4 sm-py3" - style={{ - paddingLeft: 90, - fontFamily: 'Roboto Mono', - minHeight: '1.25em', - lineHeight: 1.25, - }} - > - {props.headerText} - </div> - )} - - <div className="px2"> - {_.map(props.bulletedItemInfos, bulletedItemProps => { - return ( - <BulletedItem - key={bulletedItemProps.title} - bulletColor={bulletedItemProps.bulletColor} - title={bulletedItemProps.title} - description={bulletedItemProps.description} - /> - ); - })} - </div> - </div> - ); -}; - -interface BulletedItemProps { - bulletColor: string; - title: string; - description: string; - height?: number; -} -const BulletedItem = (props: BulletedItemProps) => { - const minHeight = props.height || 150; - return ( - <div className="flex" style={{ minHeight }}> - <svg className="flex-none px2" height="26" width="26"> - <circle cx="13" cy="13" r="13" fill={props.bulletColor} /> - </svg> - <div className="flex-auto px2"> - <div style={{ paddingTop: 3, fontWeight: 'bold', fontSize: 16 }}>{props.title}</div> - <div style={{ paddingTop: 12, fontSize: 16, lineHeight: 2 }}>{props.description}</div> - </div> - </div> - ); -}; diff --git a/packages/website/ts/pages/jobs/jobs.tsx b/packages/website/ts/pages/jobs/jobs.tsx index f3b455379..9fd305972 100644 --- a/packages/website/ts/pages/jobs/jobs.tsx +++ b/packages/website/ts/pages/jobs/jobs.tsx @@ -63,7 +63,7 @@ export class Jobs extends React.Component<JobsProps, JobsState> { <Values /> <Benefits screenWidth={this.props.screenWidth} /> <Teams screenWidth={this.props.screenWidth} /> - <OpenPositions hash={OPEN_POSITIONS_HASH} /> + <OpenPositions hash={OPEN_POSITIONS_HASH} screenWidth={this.props.screenWidth} /> <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} /> </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..b130cb0c4 --- /dev/null +++ b/packages/website/ts/pages/jobs/list/header_item.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; + +import { ListItem } from 'ts/pages/jobs/list/list_item'; + +export interface HeaderItemProps { + headerText?: string; +} +export const HeaderItem: React.StatelessComponent<HeaderItemProps> = ({ headerText }) => { + return ( + <div className="h2 lg-py4 md-py4 sm-py3"> + <ListItem> + <div + style={{ + fontFamily: 'Roboto Mono', + minHeight: '1.25em', + lineHeight: 1.25, + }} + > + {headerText} + </div> + </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/open_positions.tsx b/packages/website/ts/pages/jobs/open_positions.tsx index 5eb8e429d..f6dbc38a0 100644 --- a/packages/website/ts/pages/jobs/open_positions.tsx +++ b/packages/website/ts/pages/jobs/open_positions.tsx @@ -4,14 +4,20 @@ import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowCol import * as React from 'react'; import { Retry } from 'ts/components/ui/retry'; +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 { WebsiteBackendJobInfo } from 'ts/types'; +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 LIST_ITEM_MIN_HEIGHT = 80; export interface OpenPositionsProps { hash: string; + screenWidth: ScreenWidths; } export interface OpenPositionsState { jobInfos?: WebsiteBackendJobInfo[]; @@ -37,6 +43,7 @@ export class OpenPositions extends React.Component<OpenPositionsProps, OpenPosit } public render(): React.ReactNode { const isReadyToRender = _.isUndefined(this.state.error) && !_.isUndefined(this.state.jobInfos); + const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm; if (!isReadyToRender) { return ( // TODO: consolidate this loading component with the one in portal and RelayerIndex @@ -52,32 +59,54 @@ export class OpenPositions extends React.Component<OpenPositionsProps, OpenPosit } else { return ( <div id={this.props.hash} className="mx-auto max-width-4"> - <Title /> - <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._renderJobInfo(jobInfo); - })} - </TableBody> - </Table> + {isSmallScreen ? this._renderList() : this._renderTable()} </div> ); } } - private _renderJobInfo(jobInfo: WebsiteBackendJobInfo): React.ReactNode { + 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: 100, border: 2 }}> <TableRowColumn colSpan={5} style={labelStyle}> @@ -118,19 +147,36 @@ export class OpenPositions extends React.Component<OpenPositionsProps, OpenPosit if (_.isUndefined(this.state.jobInfos)) { return; } - const url = this.state.jobInfos[rowNumber].url; + const jobInfo = this.state.jobInfos[rowNumber]; + this._openJobInfoUrl(jobInfo); + } + + private _openJobInfoUrl(jobInfo: WebsiteBackendJobInfo): void { + const url = jobInfo.url; window.open(url, '_blank'); } } -const Title = () => ( - <div - className="h2 lg-py4 md-py4 sm-py3" - style={{ - paddingLeft: 90, - fontFamily: 'Roboto Mono', - }} - > - {'Open Positions'} +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> + <div style={{ fontWeight: 'bold', fontSize: 16, color: colors.mediumBlue }}>{title + ' ›'}</div> + <div className="pt1" style={{ fontSize: 16, color: colors.darkGrey }}> + {description} + </div> + </ListItem> </div> ); + +export const JobInfoListItem = styled(PlainJobInfoListItem)` + cursor: pointer; + &:hover { + opacity: 0.5; + } +`; diff --git a/packages/website/ts/pages/jobs/teams.tsx b/packages/website/ts/pages/jobs/teams.tsx index 465bae7f4..dcb457d06 100644 --- a/packages/website/ts/pages/jobs/teams.tsx +++ b/packages/website/ts/pages/jobs/teams.tsx @@ -2,10 +2,11 @@ import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; -import { BulletedItemInfo, BulletedItemList } from 'ts/pages/jobs/bulleted_item_list'; +import { HeaderItem } from 'ts/pages/jobs/list/header_item'; +import { ListItem } from 'ts/pages/jobs/list/list_item'; import { ScreenWidths } from 'ts/types'; -const ITEMS_COLUMN1: BulletedItemInfo[] = [ +const TEAM_ITEM_PROPS_COLUMN1: TeamItemProps[] = [ { bulletColor: '#EB5757', title: 'User Growth', @@ -19,7 +20,7 @@ const ITEMS_COLUMN1: BulletedItemInfo[] = [ '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 ITEMS_COLUMN2: BulletedItemInfo[] = [ +const TEAM_ITEM_PROPS_COLUMN2: TeamItemProps[] = [ { bulletColor: '#EB5757', title: 'Developer Tools', @@ -34,6 +35,7 @@ const ITEMS_COLUMN2: BulletedItemInfo[] = [ }, ]; const HEADER_TEXT = 'Our Teams'; +const MINIMUM_ITEM_HEIGHT = 240; export interface TeamsProps { screenWidth: ScreenWidths; @@ -44,14 +46,42 @@ export const Teams = (props: TeamsProps) => (props.screenWidth === ScreenWidths. const LargeLayout = () => ( <div className="mx-auto max-width-4 clearfix pb4"> <div className="col lg-col-6 md-col-6 col-12"> - <BulletedItemList headerText={HEADER_TEXT} bulletedItemInfos={ITEMS_COLUMN1} /> + <HeaderItem headerText={HEADER_TEXT} /> + {_.map(TEAM_ITEM_PROPS_COLUMN1, teamItemProps => React.createElement(TeamItem, teamItemProps))} </div> <div className="col lg-col-6 md-col-6 col-12"> - <BulletedItemList headerText=" " bulletedItemInfos={ITEMS_COLUMN2} /> + <HeaderItem headerText=" " /> + {_.map(TEAM_ITEM_PROPS_COLUMN2, teamItemProps => React.createElement(TeamItem, teamItemProps))} </div> </div> ); const SmallLayout = () => ( - <BulletedItemList headerText={HEADER_TEXT} bulletedItemInfos={_.concat(ITEMS_COLUMN1, ITEMS_COLUMN2)} /> + <div> + <HeaderItem headerText={HEADER_TEXT} /> + {_.map(_.concat(TEAM_ITEM_PROPS_COLUMN1, TEAM_ITEM_PROPS_COLUMN2), teamItemProps => + React.createElement(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}> + <div style={{ fontWeight: 'bold', fontSize: 16 }}>{title}</div> + </ListItem> + <ListItem> + <div className="pt1" style={{ fontSize: 16, lineHeight: 2 }}> + {description} + </div> + </ListItem> + </div> + ); +}; diff --git a/packages/website/ts/pages/jobs/values.tsx b/packages/website/ts/pages/jobs/values.tsx index 45bbf950f..abacafdba 100644 --- a/packages/website/ts/pages/jobs/values.tsx +++ b/packages/website/ts/pages/jobs/values.tsx @@ -2,9 +2,10 @@ import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; -import { BulletedItemInfo, BulletedItemList } from 'ts/pages/jobs/bulleted_item_list'; +import { HeaderItem } from 'ts/pages/jobs/list/header_item'; +import { ListItem } from 'ts/pages/jobs/list/list_item'; -const BULLETED_ITEM_INFOS: BulletedItemInfo[] = [ +const VALUE_ITEM_PROPS_LIST: ValueItemProps[] = [ { bulletColor: '#6FCF97', title: 'Ethics/Doing the right thing', @@ -22,4 +23,35 @@ const BULLETED_ITEM_INFOS: BulletedItemInfo[] = [ }, ]; -export const Values = () => <BulletedItemList headerText="Our Values" bulletedItemInfos={BULLETED_ITEM_INFOS} />; +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 => React.createElement(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}> + <div style={{ fontWeight: 'bold', fontSize: 16 }}>{title}</div> + </ListItem> + <ListItem> + <div className="pt1" style={{ fontSize: 16, lineHeight: 2 }}> + {description} + </div> + </ListItem> + </div> + ); +}; |