diff options
Diffstat (limited to 'packages/website/ts')
-rw-r--r-- | packages/website/ts/components/footer.tsx | 2 | ||||
-rw-r--r-- | packages/website/ts/components/ui/container.tsx | 7 | ||||
-rw-r--r-- | packages/website/ts/index.tsx | 12 | ||||
-rw-r--r-- | packages/website/ts/pages/about/about.tsx | 2 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/benefits.tsx | 181 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/jobs.tsx | 18 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/join_0x.tsx | 32 | ||||
-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 | 63 | ||||
-rw-r--r-- | packages/website/ts/pages/jobs/open_positions.tsx | 159 | ||||
-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/types.ts | 3 | ||||
-rw-r--r-- | packages/website/ts/utils/constants.ts | 1 |
15 files changed, 236 insertions, 435 deletions
diff --git a/packages/website/ts/components/footer.tsx b/packages/website/ts/components/footer.tsx index 9fb332a98..6dcb5a0e9 100644 --- a/packages/website/ts/components/footer.tsx +++ b/packages/website/ts/components/footer.tsx @@ -115,7 +115,7 @@ export class Footer extends React.Component<FooterProps, FooterState> { { title: this.props.translate.get(Key.Careers, Deco.Cap), isExternal: false, - path: WebsitePaths.Jobs, + path: WebsitePaths.Careers, }, { title: this.props.translate.get(Key.Contact, Deco.Cap), diff --git a/packages/website/ts/components/ui/container.tsx b/packages/website/ts/components/ui/container.tsx index 427cc6cc7..502069dee 100644 --- a/packages/website/ts/components/ui/container.tsx +++ b/packages/website/ts/components/ui/container.tsx @@ -9,6 +9,7 @@ export interface ContainerProps { marginBottom?: StringOrNum; marginRight?: StringOrNum; marginLeft?: StringOrNum; + padding?: StringOrNum; paddingTop?: StringOrNum; paddingBottom?: StringOrNum; paddingRight?: StringOrNum; @@ -31,13 +32,15 @@ export interface ContainerProps { bottom?: string; zIndex?: number; Tag?: ContainerTag; + id?: string; + onClick?: (event: React.MouseEvent<HTMLElement>) => void; } export const Container: React.StatelessComponent<ContainerProps> = props => { - const { children, className, Tag, isHidden, ...style } = props; + const { children, className, Tag, isHidden, id, onClick, ...style } = props; const visibility = isHidden ? 'hidden' : undefined; return ( - <Tag style={{ ...style, visibility }} className={className}> + <Tag id={id} style={{ ...style, visibility }} className={className} onClick={onClick}> {children} </Tag> ); diff --git a/packages/website/ts/index.tsx b/packages/website/ts/index.tsx index 2a5c5e4f1..904a5f6df 100644 --- a/packages/website/ts/index.tsx +++ b/packages/website/ts/index.tsx @@ -77,10 +77,8 @@ render( <Route exact={true} path="/" component={Landing as any} /> <Redirect from="/otc" to={`${WebsitePaths.Portal}`} /> {/* TODO: Remove this once we ship the jobs page*/} - {utils.shouldShowJobsPage() ? ( - <Route path={WebsitePaths.Jobs} component={Jobs as any} /> - ) : ( - <Route path={WebsitePaths.Jobs} component={Redirector as any} /> + {utils.shouldShowJobsPage() && ( + <Route path={WebsitePaths.Careers} component={Jobs as any} /> )} <Route path={WebsitePaths.Portal} component={LazyPortal} /> <Route path={WebsitePaths.FAQ} component={FAQ as any} /> @@ -131,6 +129,12 @@ render( path={`${WebsiteLegacyPaths.Deployer}/:version?`} component={LazySolCompilerDocumentation} /> + {/* TODO: Remove this once we ship the jobs page*/} + {utils.shouldShowJobsPage() ? ( + <Route path={WebsiteLegacyPaths.Jobs} component={Jobs as any} /> + ) : ( + <Route path={WebsiteLegacyPaths.Jobs} component={Redirector as any} /> + )} <Route path={`${WebsitePaths.Docs}`} component={LazyZeroExJSDocumentation} /> <Route component={NotFound as any} /> diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx index 33581c938..b9bc906bd 100644 --- a/packages/website/ts/pages/about/about.tsx +++ b/packages/website/ts/pages/about/about.tsx @@ -314,7 +314,7 @@ export class About extends React.Component<AboutProps, AboutState> { }} > We are seeking outstanding candidates to{' '} - <Link to={WebsitePaths.Jobs} style={{ color: 'black' }}> + <Link to={WebsitePaths.Careers} style={{ color: 'black' }}> join our team </Link> . We value passion, diversity and unique perspectives. diff --git a/packages/website/ts/pages/jobs/benefits.tsx b/packages/website/ts/pages/jobs/benefits.tsx index 006facc83..87412ed22 100644 --- a/packages/website/ts/pages/jobs/benefits.tsx +++ b/packages/website/ts/pages/jobs/benefits.tsx @@ -1,109 +1,134 @@ 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 { Circle } from 'ts/components/ui/circle'; +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 { constants } from 'ts/utils/constants'; -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', - }, +const BENEFITS = [ + 'Comprehensive insurance. Medical, dental, and vision coverage for you and your family.', + 'Unlimited vacation. Three weeks per year minimum.', + 'Flexible hours and liberal work-from-home-policy.', + 'Relocation Assistance.', + 'Whole team offsites and community / hackathon events (often international).', + 'Monthly transportation and phone reimbursement.', + 'Meals and snacks provided in-office daily.', +]; + +interface Value { + iconSrc: string; + text: string; +} +const VALUES: Value[] = [ { - 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', + iconSrc: 'images/jobs/heart-icon.svg', + text: 'Do the right thing', }, { - 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', + iconSrc: 'images/jobs/ship-icon.svg', + text: 'Consistently ship', }, { - 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', + iconSrc: 'images/jobs/calendar-icon.svg', + text: 'Focus on long term impact', }, ]; -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> -); +export const Benefits = (props: BenefitsProps) => { + const isSmallScreen = props.screenWidth === ScreenWidths.Sm; + return ( + <Container className="flex flex-column items-center py4 sm-px3" backgroundColor={colors.white}> + {!isSmallScreen ? ( + <Container className="flex" maxWidth="800px"> + <BenefitsList /> + <Container marginLeft="215px"> + <ValuesList /> + </Container> + </Container> + ) : ( + <Container className="flex-column"> + <BenefitsList /> + <Container marginTop="50px"> + <ValuesList /> + </Container> + </Container> + )} + </Container> + ); +}; -const SmallLayout = () => ( - <div> - <FilledImage src={_.head(IMAGE_PATHS)} /> - <BenefitsList /> - </div> +const Header: React.StatelessComponent = ({ children }) => ( + <Container marginBottom="51px"> + <Text fontFamily="Roboto Mono" fontSize="24px" fontColor={colors.black}> + {children} + </Text> + </Container> ); -export const BenefitsList = () => { +const BenefitsList = () => { return ( - <div> - <HeaderItem headerText={HEADER_TEXT} /> - {_.map(BENEFIT_ITEM_PROPS_LIST, valueItemProps => <BenefitItem {...valueItemProps} />)} - </div> + <Container maxWidth="360px"> + <Header>Benefits</Header> + {_.map(BENEFITS, benefit => <BenefitItem key={benefit} description={benefit} />)} + </Container> ); }; 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]} /> +const BenefitItem: React.StatelessComponent<BenefitItemProps> = ({ description }) => ( + <Container marginBottom="30px"> + <div className="flex"> + <Circle className="flex-none pr2 pt1" diameter={8} fillColor={colors.black} /> + <div className="flex-auto"> + <Text fontSize="14px" lineHeight="24px"> + {description} + </Text> </div> </div> - </div> + </Container> ); + +const ValuesList = () => { + return ( + <Container maxWidth="360px"> + <Header>Our Values</Header> + {_.map(VALUES, value => <ValueItem key={value.text} {...value} />)} + <Text fontSize="14px" lineHeight="26px"> + We care deeply about our mission and encourage you to{' '} + <a + style={{ color: colors.mediumBlue }} + target="_blank" + href={constants.URL_MISSION_AND_VALUES_BLOG_POST} + > + read more here + </a>. + </Text> + </Container> + ); +}; + +type ValueItemProps = Value; +const ValueItem: React.StatelessComponent<ValueItemProps> = ({ iconSrc, text }) => { + return ( + <Container marginBottom="45px"> + <div className="flex items-center"> + <Image className="flex-none pr2" width="20px" src={iconSrc} /> + <div className="flex-auto"> + <Text fontSize="14px" lineHeight="24px" fontWeight="bold"> + {text} + </Text> + </div> + </div> + </Container> + ); +}; diff --git a/packages/website/ts/pages/jobs/jobs.tsx b/packages/website/ts/pages/jobs/jobs.tsx index 38cefa832..ed285799e 100644 --- a/packages/website/ts/pages/jobs/jobs.tsx +++ b/packages/website/ts/pages/jobs/jobs.tsx @@ -5,14 +5,10 @@ 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'; @@ -20,7 +16,6 @@ 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; @@ -45,7 +40,7 @@ export class Jobs extends React.Component<JobsProps, JobsState> { public render(): React.ReactNode { return ( <div> - <DocumentTitle title="Jobs" /> + <DocumentTitle title="Careers at 0x" /> <TopBar blockchainIsLoaded={false} location={this.props.location} @@ -54,14 +49,7 @@ export class Jobs extends React.Component<JobsProps, JobsState> { /> <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> @@ -74,8 +62,4 @@ export class Jobs extends React.Component<JobsProps, JobsState> { 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 index 72cce3b89..5aebdf5fc 100644 --- a/packages/website/ts/pages/jobs/join_0x.tsx +++ b/packages/website/ts/pages/jobs/join_0x.tsx @@ -3,8 +3,11 @@ import { colors } from '@0xproject/react-shared'; import * as React from 'react'; import { Button } from 'ts/components/ui/button'; +import { Container } from 'ts/components/ui/container'; +import { Image } from 'ts/components/ui/image'; +import { Text } from 'ts/components/ui/text'; -const BUTTON_TEXT = 'view open positions'; +const BUTTON_TEXT = 'View open positions'; export interface Join0xProps { onCallToActionClick: () => void; @@ -12,17 +15,28 @@ export interface Join0xProps { 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="mx-auto inline-block align-middle py4" + style={{ lineHeight: '44px', textAlign: 'center', position: 'relative' }} + > + <Container className="sm-hide" position="absolute" left="100%" marginLeft="80px"> + <Image src="images/jobs/hero-dots-right.svg" width="400px" /> + </Container> + <Container className="sm-hide" position="absolute" right="100%" marginRight="80px"> + <Image src="images/jobs/hero-dots-left.svg" width="400px" /> + </Container> <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> + <Container className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 sm-center" maxWidth="537px"> + <Text fontSize="14px" lineHeight="30px"> + 0x exists to create a tokenized world where all value can flow freely. We’re building an open and + globally accessible economy where blockchain based digital assets are accessible to anyone, + anywhere. We’re passionate about open-source software and decentralized technology’s potential to + act as an equalizing force in the world. Come join us and help transform the way that value is + exchanged on a global scale. + </Text> + </Container> <div className="py3"> <Button type="button" diff --git a/packages/website/ts/pages/jobs/list/header_item.tsx b/packages/website/ts/pages/jobs/list/header_item.tsx deleted file mode 100644 index ac214904c..000000000 --- a/packages/website/ts/pages/jobs/list/header_item.tsx +++ /dev/null @@ -1,26 +0,0 @@ -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 deleted file mode 100644 index 192433d39..000000000 --- a/packages/website/ts/pages/jobs/list/list_item.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; - -import { Circle } from 'ts/components/ui/circle'; - -export interface ListItemProps { - bulletColor?: string; -} -export const ListItem: React.StatelessComponent<ListItemProps> = ({ bulletColor, children }) => { - return ( - <div className="flex items-center"> - <Circle className="flex-none lg-px2 md-px2 sm-pl2" diameter={26} fillColor={bulletColor || 'transparent'} /> - <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 index f7f874e04..daec1e62a 100644 --- a/packages/website/ts/pages/jobs/mission.tsx +++ b/packages/website/ts/pages/jobs/mission.tsx @@ -1,5 +1,7 @@ import * as React from 'react'; +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'; @@ -8,49 +10,36 @@ export interface MissionProps { } 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 image = <img src="/images/jobs/world-map.svg" style={{ maxWidth: 500, maxHeight: 280 }} />; + const missionStatementClassName = isSmallScreen ? 'center' : 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> + <Container className={missionStatementClassName} maxWidth="388px"> + <Text fontFamily="Roboto Mono" fontSize="22px" lineHeight="31px"> + Globally Distributed<br />Purposefully Aligned + </Text> + <Container marginTop="32px"> + <Text fontSize="14px" lineHeight="2em"> + We’re a highly technical team with diverse backgrounds in engineering, science, business, finance, + and research. While headquartered in San Francisco, we’ve designed our workflows to empower + teammates to stay informed and execute on their objectives from anywhere in the world. If you’re + passionate about our mission, we’re excited to talk to you, regardless of where you might live. + </Text> + </Container> + </Container> ); return ( <div - className="container lg-py4 md-py4" + className="flex flex-column items-center py4 sm-px3" style={{ backgroundColor: colors.jobsPageBackground, color: colors.black }} > - <div className="mx-auto clearfix sm-py4"> - {isSmallScreen ? ( - <div> - {missionStatement} - {image} - </div> - ) : ( - <div> - {image} - {missionStatement} - </div> - )} - </div> + {!isSmallScreen ? ( + <Container className="flex items-center" maxWidth="1200px"> + {image} + <Container marginLeft="115px">{missionStatement}</Container> + </Container> + ) : ( + <Container className="flex flex-column items-center">{missionStatement}</Container> + )} </div> ); }; diff --git a/packages/website/ts/pages/jobs/open_positions.tsx b/packages/website/ts/pages/jobs/open_positions.tsx index e789795c1..99242c6c5 100644 --- a/packages/website/ts/pages/jobs/open_positions.tsx +++ b/packages/website/ts/pages/jobs/open_positions.tsx @@ -1,20 +1,16 @@ 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 { Container } from 'ts/components/ui/container'; 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'; import { utils } from 'ts/utils/utils'; -const labelStyle = { fontFamily: 'Roboto Mono', fontSize: 18 }; -const HEADER_TEXT = 'Open Positions'; const TABLE_ROW_MIN_HEIGHT = 100; export interface OpenPositionsProps { @@ -45,16 +41,21 @@ 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; return ( - <div id={this.props.hash} className="mx-auto max-width-4"> - {isReadyToRender ? this._renderBody() : this._renderLoading()} - </div> + <Container id={this.props.hash} className="mx-auto pb4 px3" maxWidth="1200px"> + {!isSmallScreen && ( + <hr style={{ border: 0, borderTop: 1, borderStyle: 'solid', borderColor: colors.beigeWhite }} /> + )} + <Container marginTop="64px" marginBottom="50px"> + <Text fontFamily="Roboto Mono" fontSize="24px" fontColor={colors.black}> + Open Positions + </Text> + </Container> + {isReadyToRender ? this._renderTable() : this._renderLoading()} + </Container> ); } - 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 @@ -68,66 +69,20 @@ export class OpenPositions extends React.Component<OpenPositionsProps, OpenPosit </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> + <Container width="100%"> + {_.map(this.state.jobInfos, jobInfo => { + return ( + <JobInfoTableRow + key={jobInfo.id} + screenWidth={this.props.screenWidth} + jobInfo={jobInfo} + onClick={this._openJobInfoUrl.bind(this, jobInfo)} + /> + ); + })} + </Container> ); } private async _fetchJobInfosAsync(): Promise<void> { @@ -152,41 +107,57 @@ export class OpenPositions extends React.Component<OpenPositionsProps, OpenPosit } } } - 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; utils.openUrl(url); } } -export interface JobInfoListItemProps { - title?: string; - description?: string; +export interface JobInfoTableRowProps { + className?: string; + screenWidth: ScreenWidths; + jobInfo: WebsiteBackendJobInfo; 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> -); +const PlainJobInfoTableRow: React.StatelessComponent<JobInfoTableRowProps> = ({ + className, + screenWidth, + jobInfo, + onClick, +}) => { + const isSmallScreen = screenWidth === ScreenWidths.Sm; + const titleClassName = isSmallScreen ? 'col col-12 center' : 'col col-5'; + const paddingLeft = isSmallScreen ? undefined : '30px'; + return ( + <Container className={className} onClick={onClick} marginBottom="30px" paddingLeft={paddingLeft}> + <Container className="flex items-center" minHeight={TABLE_ROW_MIN_HEIGHT} width="100%"> + <Container className="clearfix container" width="100%"> + <Container className={titleClassName}> + <Text fontSize="16px" fontWeight="bold" fontColor={colors.mediumBlue}> + {jobInfo.title} + </Text> + </Container> + {!isSmallScreen && ( + <Container className="col col-3"> + <Text fontSize="16px">{jobInfo.department}</Text> + </Container> + )} + {!isSmallScreen && ( + <Container className="col col-4 center"> + <Text fontSize="16px">{jobInfo.office}</Text> + </Container> + )} + </Container> + </Container> + </Container> + ); +}; -export const JobInfoListItem = styled(PlainJobInfoListItem)` +export const JobInfoTableRow = styled(PlainJobInfoTableRow)` cursor: pointer; + background-color: ${colors.grey100}; + border-radius: 7px; &:hover { opacity: 0.5; } diff --git a/packages/website/ts/pages/jobs/teams.tsx b/packages/website/ts/pages/jobs/teams.tsx deleted file mode 100644 index 80b036396..000000000 --- a/packages/website/ts/pages/jobs/teams.tsx +++ /dev/null @@ -1,90 +0,0 @@ -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 deleted file mode 100644 index c7c4d5726..000000000 --- a/packages/website/ts/pages/jobs/values.tsx +++ /dev/null @@ -1,60 +0,0 @@ -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/types.ts b/packages/website/ts/types.ts index 4d0496f6c..e1b5be39a 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -356,6 +356,7 @@ export enum WebsiteLegacyPaths { ZeroExJs = '/docs/0xjs', Web3Wrapper = '/docs/web3_wrapper', Deployer = '/docs/deployer', + Jobs = '/jobs', } export enum WebsitePaths { @@ -376,7 +377,7 @@ export enum WebsitePaths { Subproviders = '/docs/subproviders', OrderUtils = '/docs/order-utils', EthereumTypes = '/docs/ethereum-types', - Jobs = '/jobs', + Careers = '/careers', } export enum DocPackages { diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts index 20441cd75..c708c9c5b 100644 --- a/packages/website/ts/utils/constants.ts +++ b/packages/website/ts/utils/constants.ts @@ -92,4 +92,5 @@ export const constants = { URL_WEB3_LOG_ENTRY_EVENT: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L127', URL_WEB3_PROVIDER_DOCS: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L150', URL_BIGNUMBERJS_GITHUB: 'http://mikemcl.github.io/bignumber.js', + URL_MISSION_AND_VALUES_BLOG_POST: 'https://blog.0xproject.com/the-0x-mission-and-values-181a58706f9f', }; |