diff options
Diffstat (limited to 'packages/website/ts/components/footer.tsx')
-rw-r--r-- | packages/website/ts/components/footer.tsx | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/packages/website/ts/components/footer.tsx b/packages/website/ts/components/footer.tsx new file mode 100644 index 000000000..99f97292e --- /dev/null +++ b/packages/website/ts/components/footer.tsx @@ -0,0 +1,255 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import {HashLink} from 'react-router-hash-link'; +import {Styles, WebsitePaths} from 'ts/types'; +import { + Link, +} from 'react-router-dom'; +import { + Link as ScrollLink, +} from 'react-scroll'; +import {constants} from 'ts/utils/constants'; + +interface MenuItemsBySection { + [sectionName: string]: FooterMenuItem[]; +} + +interface FooterMenuItem { + title: string; + path?: string; + isExternal?: boolean; + fileName?: string; +} + +enum Sections { + Documentation = 'Documentation', + Community = 'Community', + Organization = 'Organization', +} + +const ICON_DIMENSION = 16; +const CUSTOM_DARK_GRAY = '#393939'; +const CUSTOM_LIGHT_GRAY = '#CACACA'; +const CUSTOM_LIGHTEST_GRAY = '#9E9E9E'; +const menuItemsBySection: MenuItemsBySection = { + Documentation: [ + { + title: '0x.js', + path: WebsitePaths.ZeroExJs, + }, + { + title: '0x Smart Contracts', + path: WebsitePaths.SmartContracts, + }, + { + title: 'Whitepaper', + path: WebsitePaths.Whitepaper, + isExternal: true, + }, + { + title: 'Wiki', + path: WebsitePaths.Wiki, + }, + { + title: 'FAQ', + path: WebsitePaths.FAQ, + }, + ], + Community: [ + { + title: 'Rocket.chat', + isExternal: true, + path: constants.ZEROEX_CHAT_URL, + fileName: 'rocketchat.png', + }, + { + title: 'Blog', + isExternal: true, + path: constants.BLOG_URL, + fileName: 'medium.png', + }, + { + title: 'Twitter', + isExternal: true, + path: constants.TWITTER_URL, + fileName: 'twitter.png', + }, + { + title: 'Reddit', + isExternal: true, + path: constants.REDDIT_URL, + fileName: 'reddit.png', + }, + ], + Organization: [ + { + title: 'About', + isExternal: false, + path: WebsitePaths.About, + }, + { + title: 'Careers', + isExternal: true, + path: constants.ANGELLIST_URL, + }, + { + title: 'Contact', + isExternal: true, + path: 'mailto:team@0xproject.com', + }, + ], +}; +const linkStyle = { + color: 'white', + cursor: 'pointer', +}; + +const titleToIcon: {[title: string]: string} = { + 'Rocket.chat': 'rocketchat.png', + 'Blog': 'medium.png', + 'Twitter': 'twitter.png', + 'Reddit': 'reddit.png', +}; + +export interface FooterProps { + location: Location; +} + +interface FooterState {} + +export class Footer extends React.Component<FooterProps, FooterState> { + public render() { + return ( + <div className="relative pb4 pt2" style={{backgroundColor: CUSTOM_DARK_GRAY}}> + <div className="mx-auto max-width-4 md-px2 lg-px0 py4 clearfix" style={{color: 'white'}}> + <div className="col lg-col-4 md-col-4 col-12 left"> + <div className="sm-mx-auto" style={{width: 148}}> + <div> + <img src="/images/protocol_logo_white.png" height="30" /> + </div> + <div style={{fontSize: 11, color: CUSTOM_LIGHTEST_GRAY, paddingLeft: 37, paddingTop: 2}}> + © ZeroEx, Intl. + </div> + </div> + </div> + <div className="col lg-col-8 md-col-8 col-12 lg-pl4 md-pl4"> + <div className="col lg-col-4 md-col-4 col-12"> + <div className="lg-right md-right sm-center"> + {this.renderHeader(Sections.Documentation)} + {_.map(menuItemsBySection[Sections.Documentation], this.renderMenuItem.bind(this))} + </div> + </div> + <div className="col lg-col-4 md-col-4 col-12 lg-pr2 md-pr2"> + <div className="lg-right md-right sm-center"> + {this.renderHeader(Sections.Community)} + {_.map(menuItemsBySection[Sections.Community], this.renderMenuItem.bind(this))} + </div> + </div> + <div className="col lg-col-4 md-col-4 col-12"> + <div className="lg-right md-right sm-center"> + {this.renderHeader(Sections.Organization)} + {_.map(menuItemsBySection[Sections.Organization], this.renderMenuItem.bind(this))} + </div> + </div> + </div> + </div> + </div> + ); + } + private renderIcon(fileName: string) { + return ( + <div style={{height: ICON_DIMENSION, width: ICON_DIMENSION}}> + <img src={`/images/social/${fileName}`} style={{width: ICON_DIMENSION}} /> + </div> + ); + } + private renderMenuItem(item: FooterMenuItem) { + const iconIfExists = titleToIcon[item.title]; + return ( + <div + key={item.title} + className="sm-center" + style={{fontSize: 13, paddingTop: 25}} + > + {item.isExternal ? + <a + className="text-decoration-none" + style={linkStyle} + target="_blank" + href={item.path} + > + {!_.isUndefined(iconIfExists) ? + <div className="sm-mx-auto" style={{width: 65}}> + <div className="flex"> + <div className="pr1"> + {this.renderIcon(iconIfExists)} + </div> + <div>{item.title}</div> + </div> + </div> : + item.title + } + </a> : + <Link + to={item.path} + style={linkStyle} + className="text-decoration-none" + > + <div> + {!_.isUndefined(iconIfExists) && + <div className="pr1"> + {this.renderIcon(iconIfExists)} + </div> + } + {item.title} + </div> + </Link> + } + </div> + ); + } + private renderHeader(title: string) { + const headerStyle = { + textTransform: 'uppercase', + color: CUSTOM_LIGHT_GRAY, + letterSpacing: 2, + fontFamily: 'Roboto Mono', + fontSize: 13, + }; + return ( + <div + className="lg-pb2 md-pb2 sm-pt4" + style={headerStyle} + > + {title} + </div> + ); + } + private renderHomepageLink(title: string) { + const hash = title.toLowerCase(); + if (this.props.location.pathname === WebsitePaths.Home) { + return ( + <ScrollLink + style={linkStyle} + to={hash} + smooth={true} + offset={0} + duration={constants.HOME_SCROLL_DURATION_MS} + containerId="home" + > + {title} + </ScrollLink> + ); + } else { + return ( + <HashLink + to={`/#${hash}`} + className="text-decoration-none" + style={linkStyle} + > + {title} + </HashLink> + ); + } + } +} |