UNPKG

thinkful-ui

Version:

Shared navigation and UI resources for Thinkful.

229 lines (207 loc) 10 kB
const cx = require('classnames'); const React = require('react'); const _ = require('lodash'); const moment = require('moment-timezone'); const uniqueId = require('lodash/utility/uniqueId'); // TUI Components const {Icon} = require('../Icon'); const {Gravatar} = require('../Gravatar'); const {NavLink} = require('./NavLink'); const {Notifications} = require('./notifications/Notifications'); const {CourseLink} = require('./CourseLink'); const linkSet = require('./linkSet'); /** * AppNav * @property {} description */ class AppNav extends React.Component { static propTypes = { user: React.PropTypes.object, config: React.PropTypes.object.isRequired } static childContextTypes = { user: React.PropTypes.object.isRequired, }; getChildContext() { return { user: this.props.user, } } constructor(props) { super(props); this.state = { isMenuVisible: false, isCourseDropdownVisible: false }; this._toggleMenu = this._toggleMenu.bind(this); this._toggleCourseDropdown = this._toggleCourseDropdown.bind(this); this._handleMouseEnter = this._handleMouseEnter.bind(this); this._handleMouseLeave = this._handleMouseLeave.bind(this); } _toggleMenu() { this.setState({ isMenuVisible: ! this.state.isMenuVisible }); } _toggleCourseDropdown() { this.setState({ isCourseDropdownVisible: ! this.state.isCourseDropdownVisible }); } _handleMouseEnter(event) { if (this.mouseTimeout) { clearTimeout(this.mouseTimeout); } } _handleMouseLeave(event) { clearTimeout(this.mouseTimeout); this.mouseTimeout = setTimeout(() => { this.setState({ isMenuVisible: false, isCourseDropdownVisible: false }) }, 400); } renderAuthed(user, config) { const navClassName = cx( 'app-nav', {'app-nav__visible': this.state.isMenuVisible}); const navLinks = linkSet.main.filter(link => !link.search); return ( <div className='app-nav-container'> <nav onMouseLeave={this._handleMouseLeave} className={navClassName} key="main-navigation" rel="main-navigation"> <a href={linkSet.home.url}><div dangerouslySetInnerHTML={{__html: require('./images/white_t_logo.svg')}}> </div></a> <ul className="app-nav-main"> {navLinks.map( (link) => <li key={uniqueId('link_')}> <NavLink {...link} /></li>)} </ul> <ul onMouseEnter={this._handleMouseEnter} className="app-nav-list"> {navLinks.map( (link) => <li key={uniqueId('link_')}> <NavLink className="app-nav-link__mobile-only" {...link} /></li>)} {linkSet.menu.map( (link) => <li key={uniqueId('link_')}> <NavLink className="app-nav-link__in-menu" {...link}/></li>)} </ul> <Notifications /> <a className="app-nav-link app-nav-link__toggle" onClick={this._toggleMenu}> <span alt="Menu" className="app-nav-burger"></span> <Gravatar className="app-nav-gravatar" email="" src={`${config.api.url}/api/hupers/me/avatar`} size={120}/> </a> </nav> </div> ) } renderCourseDropdown() { const {config} = this.props; const dropdownContentClasses = cx("app-nav-course-dropdown-content", {"app-nav-course-dropdown-content__visible" : this.state.isCourseDropdownVisible}); return ( <div className="app-nav-course-dropdown"> <span className='app-nav-link' onClick={this._toggleCourseDropdown}>Courses <Icon className='app-nav-link-down-arrow' name='navigatedown' /> </span> <div onMouseEnter={this._handleMouseEnter} className={dropdownContentClasses}> <div className="app-nav-section-header">Become a developer</div> <div className="app-nav-courses"> <CourseLink href={`${config.www.url}/bootcamp/web-development/flexible/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/career.gz.svg" name="Flexible Bootcamp" /> <CourseLink href={`${config.www.url}/bootcamp/web-development/full-time/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/career.gz.svg" name="Full Time Bootcamp" /> </div> <div className="app-nav-section-header">Master a new skill</div> <div className="app-nav-courses"> <CourseLink href={`${config.www.url}/courses/learn-web-development-online/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/frontend.gz.svg" name="Frontend Development" /> <CourseLink href={`${config.www.url}/courses/learn-ux-online/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/uxd.gz.svg" name="User Experience Design" /> <CourseLink href={`${config.www.url}/courses/learn-angularjs-online/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/angular.gz.svg" name="Frontend in AngularJS" /> <CourseLink href={`${config.www.url}/courses/learn-web-design-online/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/design.gz.svg" name="Modern Web Design" /> <CourseLink href={`${config.www.url}/courses/learn-python-online/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/python.gz.svg" name="Programming in Python" /> <CourseLink href={`${config.www.url}/courses/learn-swift-programming-online/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/swift.gz.svg" name="iOS Programming in Swift" /> <CourseLink href={`${config.www.url}/courses/learn-ruby-on-rails-online/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/ruby.gz.svg" name="Web Development in Rails" /> <CourseLink href={`${config.www.url}/courses/learn-android-programming-online/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/android.gz.svg" name="Android Mobile Development" /> <CourseLink href={`${config.www.url}/courses/learn-nodejs-online/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/node.gz.svg" name="Backend in Node.js" /> <CourseLink href={`${config.www.url}/courses/learn-data-science-online/`} icon="//tf-assets-prod.s3.amazonaws.com/wow-next/course-icons/data.gz.svg" name="Data Science in Python" /> </div> <div className="app-nav-courses app-nav-courses__center"> <CourseLink href={`${config.www.url}/courses/`} name="Explore all courses" arrow={true} /> </div> </div> </div>); } renderUnauthed(config) { const navClassName = cx( 'app-nav', {'app-nav__visible': this.state.isMenuVisible}); return ( <div className='app-nav-container app-nav-container__unauthed'> <nav onMouseLeave={this._handleMouseLeave} className={navClassName} rel="main-navigation"> <a href={`${linkSet.home.url}/?rel=nav`}> <div dangerouslySetInnerHTML={{__html: require('./images/blue_full_logo.svg')}}/> </a> <ul onMouseEnter={this._handleMouseEnter} className='app-nav-list'> {linkSet.insertCourseDropdown && this.renderCourseDropdown()} {linkSet.insertCourseDropdown && <li key="courseDropdown"> <NavLink className='app-nav-link__mobile-only' displayName='Courses' url={`${config.www.url}/courses/`} /> </li>} {linkSet.menu.map( (link) => <li key={uniqueId('link_')}> <NavLink className='app-nav-link__in-menu' {...link}/></li>)} </ul> <a className='app-nav-link app-nav-link__toggle' onClick={this._toggleMenu}> <span alt='Menu' className='app-nav-burger'></span> </a> </nav> </div> ) } render() { const {user, config} = this.props; return user && user.tf_login && user.role !== 'guest' ? this.renderAuthed(user, config) : this.renderUnauthed(config); } } module.exports = AppNav;