Created
June 8, 2018 20:39
-
-
Save marvinkome/d10fb429027214aa0989bf48fd8de628 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * ./src/components/post/view/topbar | |
| */ | |
| import React, { Component } from 'react'; | |
| import PropTypes from 'prop-types'; | |
| import { Link } from 'react-router-dom'; | |
| import { connect } from 'react-redux'; | |
| import { logoutUser } from '../../js/redux/actions'; | |
| import img from '../../img/default-pic.png'; | |
| import { MdMenu, MdNotificationsNone } from 'react-icons/lib/md'; | |
| import { format_date } from '../../js/helpers'; | |
| import './topbar.less'; | |
| export const Dropdown = ({ handleLogout }) => ( | |
| <div className="dropdown-container user-profile"> | |
| <ul className="dropdown-content" id="dropdown-menu"> | |
| <li> | |
| <Link to="/admin/new-post">New Post</Link> | |
| </li> | |
| <li> | |
| <Link to="/admin/posts">All Posts</Link> | |
| </li> | |
| <li> | |
| <div className="divider" /> | |
| </li> | |
| <li> | |
| <Link to="/admin/dashboard">Dashboard</Link> | |
| </li> | |
| <li> | |
| <a className="logout" onClick={handleLogout}> | |
| Logout | |
| </a> | |
| </li> | |
| </ul> | |
| </div> | |
| ); | |
| export const NavMenu = () => ( | |
| <div> | |
| <span> | |
| <a>home</a> | |
| </span> | |
| <span> | |
| <a>trust</a> | |
| </span> | |
| <span> | |
| <a>culture</a> | |
| </span> | |
| <span> | |
| <a>tech</a> | |
| </span> | |
| <span> | |
| <a>entreprenuership</a> | |
| </span> | |
| <span> | |
| <a>self</a> | |
| </span> | |
| <span> | |
| <a>politics</a> | |
| </span> | |
| <span> | |
| <a>media</a> | |
| </span> | |
| <span> | |
| <a>design</a> | |
| </span> | |
| <span> | |
| <a>programming</a> | |
| </span> | |
| <span> | |
| <a>art</a> | |
| </span> | |
| <span> | |
| <a>popular</a> | |
| </span> | |
| <span> | |
| <a>science</a> | |
| </span> | |
| </div> | |
| ); | |
| export const MobileSideNav = ({ data, logout }) => ( | |
| <div> | |
| <li> | |
| <div className="user-view"> | |
| <a> | |
| <img className={'circle' + data.imageClass} src={data.image} /> | |
| </a> | |
| <span className="email">Hello, {data.isLoggedIn ? data.username : 'Guest'}</span> | |
| </div> | |
| </li> | |
| {data.isLoggedIn ? ( | |
| <div> | |
| <li> | |
| <Link to="/admin/new-post"> | |
| <span>New Post</span> | |
| </Link> | |
| </li> | |
| <li> | |
| <Link to="/admin/posts"> | |
| <span>All Posts</span> | |
| </Link> | |
| </li> | |
| <div className="divider" /> | |
| <li> | |
| <Link to="/admin/posts"> | |
| <span>Dashboard</span> | |
| </Link> | |
| </li> | |
| <li> | |
| <a title="Logout" onClick={logout}> | |
| <span>Logout</span> | |
| </a> | |
| </li> | |
| </div> | |
| ) : ( | |
| <div> | |
| <li> | |
| <Link className="hide-on-med-and-up" to="/auth/login"> | |
| Sign In | |
| </Link> | |
| </li> | |
| <div className="divider" /> | |
| <li> | |
| <Link className="hide-on-med-and-up" to="/auth/signup"> | |
| Get Started | |
| </Link> | |
| </li> | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| export const Notifications = ({notifications}) => ( | |
| notifications.map((notification) => ( | |
| <li className="notification" key={notification.id}> | |
| <div className="row"> | |
| <div className="col s3"> | |
| <div className="author-image"> | |
| <img src={img} className="responsive-img circle" /> | |
| </div> | |
| </div> | |
| <div className="notification-info col s9"> | |
| <p className="user-action"> | |
| {notification.from.name} <span> | |
| commented on | |
| </span> | |
| </p> | |
| <p className="post-title"> | |
| {notification.post.title} | |
| </p> | |
| <p className="meta"> | |
| {format_date(notification.timestamp)} | |
| </p> | |
| </div> | |
| </div> | |
| </li> | |
| )) | |
| ); | |
| export class TopBar extends Component { | |
| constructor(props) { | |
| super(props); | |
| this.state = { | |
| sticky: false | |
| }; | |
| this.sidenav = React.createRef(); | |
| this.dropdown = React.createRef(); | |
| this.notificationDropdown = React.createRef(); | |
| this.sidenavIns; | |
| this.dropdownIns; | |
| this.notificationDropdownIns; | |
| } | |
| componentDidMount() { | |
| window.addEventListener('scroll', this.onScroll, false); | |
| const sidenav = this.sidenav.current; | |
| if (window.M) { | |
| this.sidenavIns = window.M.Sidenav.init(sidenav); | |
| } | |
| } | |
| componentDidUpdate() { | |
| this.register_dropdown(this.dropdown.current, 'DIV.user-profile', 'dropdownIns'); | |
| this.register_dropdown( | |
| this.notificationDropdown.current, | |
| 'DIV.notifications', | |
| 'notificationDropdownIns' | |
| ); | |
| } | |
| componentWillUnmount() { | |
| window.removeEventListener('scroll', this.onScroll, false); | |
| if (this.sidenavIns !== undefined && this.sidenavIns !== null) { | |
| this.sidenavIns.close(); | |
| this.sidenavIns.destroy(); | |
| } | |
| this.deactivate_dropdown('notificationDropdownIns'); | |
| this.deactivate_dropdown('dropdownIns'); | |
| } | |
| deactivate_dropdown = (ins) => { | |
| if (this[ins] !== undefined && this[ins] !== null) { | |
| this[ins].close(); | |
| this[ins].destroy(); | |
| } | |
| }; | |
| register_dropdown = (elem, container, ins) => { | |
| if (elem != null) { | |
| this[ins] = window.M.Dropdown.init(elem, { | |
| constrainWidth: false, | |
| coverTrigger: false, | |
| container | |
| }); | |
| } | |
| }; | |
| onScroll = () => { | |
| if (this.props.isPostPage === undefined || this.props.isPostPage === false) { | |
| if (window.pageYOffset >= 72) { | |
| this.setState({ | |
| sticky: true | |
| }); | |
| } else { | |
| this.setState({ | |
| sticky: false | |
| }); | |
| } | |
| } | |
| }; | |
| handleLogout = () => { | |
| this.props.logout(); | |
| }; | |
| render_navbar = (data) => ( | |
| <ul className="right hide-on-small-only"> | |
| {data.isLoggedIn ? ( | |
| <div> | |
| <li> | |
| <a | |
| className="notification-icon" | |
| ref={this.notificationDropdown} | |
| data-target="notifications-menu" | |
| > | |
| <MdNotificationsNone /> | |
| </a> | |
| </li> | |
| <li> | |
| <a | |
| ref={this.dropdown} | |
| className="dropdown-trigger user-profile" | |
| data-target="dropdown-menu" | |
| > | |
| <img | |
| className={'user-image responsive-img circle' + data.imageClass} | |
| src={data.image} | |
| /> | |
| </a> | |
| <Dropdown handleLogout={this.handleLogout} /> | |
| {this.render_notification_dropdown()} | |
| </li> | |
| </div> | |
| ) : ( | |
| <div> | |
| <li> | |
| <Link to="/auth/login" className="sign-in"> | |
| Sign in | |
| </Link> | |
| </li> | |
| <li> | |
| <Link to="/auth/signup" className="sign-up btn"> | |
| Get started | |
| </Link> | |
| </li> | |
| </div> | |
| )} | |
| </ul> | |
| ); | |
| render_notification_dropdown = () => ( | |
| <div className="notifications dropdown-container"> | |
| <ul className="dropdown-content" id="notifications-menu"> | |
| <Notifications notifications={this.props.notifications}/> | |
| </ul> | |
| </div> | |
| ); | |
| render() { | |
| let defaultImageClass = ' defImg'; | |
| let userImg = img; | |
| if (this.props.user_data !== undefined && this.props.user_data !== null) { | |
| if (this.props.user_data.user.gravatarUrl !== null) { | |
| userImg = this.props.user_data.user.gravatarUrl; | |
| defaultImageClass = ''; | |
| } | |
| } | |
| const menu_class = this.state.sticky ? ' sticky' : ''; | |
| const isLoggedIn = this.props.user_data != undefined && this.props.user_data !== null; | |
| const nav_data = { | |
| isLoggedIn, | |
| imageClass: defaultImageClass, | |
| image: userImg, | |
| username: this.props.user_data ? this.props.user_data.user.fullName : null | |
| }; | |
| return ( | |
| <div className="navbar-wrapper"> | |
| <div className=""> | |
| <nav className="topbar nav-extended"> | |
| <div className="nav-wrapper"> | |
| <a | |
| href="#" | |
| data-target="mobile-topbar" | |
| className="sidenav-trigger hide-on-med-and-up" | |
| > | |
| <MdMenu /> | |
| </a> | |
| <Link to="/" className="brand-logo center"> | |
| <span className="blog-title">ReactPress</span> | |
| </Link> | |
| {isLoggedIn && ( | |
| <a | |
| className="notification-icon-on-small right hide-on-med-and-up" | |
| ref={this.notificationDropdown} | |
| > | |
| <MdNotificationsNone /> | |
| </a> | |
| )} | |
| {this.render_navbar(nav_data)} | |
| </div> | |
| {(this.props.isPostPage === undefined || | |
| this.props.isPostPage === false) && ( | |
| <div className={'nav-content' + menu_class}> | |
| <NavMenu /> | |
| </div> | |
| )} | |
| </nav> | |
| </div> | |
| <ul ref={this.sidenav} className="sidenav hide-on-med-and-up" id="mobile-topbar"> | |
| <MobileSideNav data={nav_data} logout={this.handleLogout} /> | |
| </ul> | |
| </div> | |
| ); | |
| } | |
| } | |
| Dropdown.propTypes = { | |
| handleLogout: PropTypes.func.isRequired | |
| }; | |
| MobileSideNav.propTypes = { | |
| data: PropTypes.object.isRequired, | |
| logout: PropTypes.func.isRequired | |
| }; | |
| TopBar.propTypes = { | |
| isPostPage: PropTypes.bool, | |
| user_data: PropTypes.object, | |
| notifications: PropTypes.array, | |
| logout: PropTypes.func.isRequired | |
| }; | |
| const mapDispatchToProp = (dispatch) => ({ | |
| logout: () => dispatch(logoutUser()) | |
| }); | |
| export default connect(null, mapDispatchToProp)(TopBar); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment