Implement small open positions

This commit is contained in:
Brandon Millman
2018-06-12 10:38:41 -07:00
parent 679d60cd5a
commit 7080f0c35a
8 changed files with 232 additions and 120 deletions

View File

@@ -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%' }}>

View File

@@ -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>
);
};

View File

@@ -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>
);

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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;
}
`;

View File

@@ -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>
);
};

View File

@@ -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>
);
};