UNPKG

instantjob-recruiter-client

Version:

a set of tools for creating an instantjob recruiter react client

252 lines (232 loc) 8.28 kB
import React, {Component} from 'react' import styled from 'styled-components' import {connect} from 'react-redux' import {browserHistory} from 'react-router' import { MdFlag, MdGroup, MdComment, MdArrowDropDown, MdMenu, MdTrendingUp, MdSettings, MdPowerSettingsNew, } from 'react-icons/lib/md' import ProfileImage from 'components/profile_image' import InstantJob from 'components/instant_job' import Hover from 'components/utils/hover' import ViewportListener from 'components/viewport_listener' import Chat from 'scenes/chat' import store from 'common/store' import auto_bind from 'common/auto_bind' import {color, link} from 'common/styles' import {action_logout} from 'common/authentication' import {array_from_hash, array_contains} from 'common/utilities' import {store_viewport} from 'actions/display' const font_title = 20 const font_text = 12 class NavbarStatic extends Component { constructor(props) { super(props) this.state = { previously_extended: false, } auto_bind(this) } render() { return ( <div style={{display: 'flex', flexDirection: 'column'}}> <ViewportListener on_change={(viewport, scrollbar_size) => store.dispatch(store_viewport(viewport, scrollbar_size))}/> <div style={styles.nav_bar}> <div style={{display: 'flex', alignItems: 'center', height: 50}}> <div style={styles.brand(true)}> <InstantJob /> </div> </div> <CollapsibleLinks {...this.props} /> </div> <div style={{display: 'flex', flexDirection: 'row', alignItems: 'stretch', position: 'absolute', top: 50, right: 0, left: 0, bottom: 0}}> <div style={{zIndex: 0, overflow: 'auto', backgroundColor: 'white', flexGrow: 10000000, flexShrink: 1, display: 'flex', flexDirection: 'column', alignItems: 'stretch', justifyContent: 'flex-start'}}> {this.props.children} </div> {array_contains(['xs', 'sm'], this.props.viewport) ? null : ( <Chat side_module /> )} </div> </div> ) } } class CollapsibleLinks extends Component { render() { let tabs switch (this.props.viewport) { case 'xs': case 'sm': tabs = [ {path: "/", icon: MdTrendingUp, label: "Activité", is_active: (path) => (path.match(/^\/statistics\/?/) || path == '/')}, {path: "/deals", icon: MdFlag, label: "Missions", is_active: (path) => path.match(/^\/deals\/?/)}, {path: "/users", icon: MdGroup, label: "Répertoire", is_active: (path) => path.match(/^\/users\/?/)}, {path: "/messages", icon: MdComment, label: "Messagerie", is_active: (path) => path.match(/^\/messages\/?/)}, {path: "/settings", icon: MdSettings, label: "Paramètres", is_active: (path) => path.match(/^\/settings\/?/)}, ] return ( <Hover> {(hover) => ( <div style={{display: 'flex', alignItems: 'center'}}> <div style={{right: 0, marginLeft: 'auto', paddingRight: 15, color: color('white'), fontSize: 30}}> <MdMenu/> </div> {hover ? ( <div style={styles.extended_menu}> <div style={{display: 'flex', flexDirection: 'column'}}> {tabs.map((tab) => <Tab key={tab.label} path={tab.path} icon={tab.icon} label={tab.label} active={tab.is_active(this.props.location.pathname)} extended/>)} <div className="link" style={{...styles.profile, paddingTop: 8}} onClick={() => browserHistory.push('/settings')}> <ProfileImage {...this.props.profile} hide_status /> <div style={{...styles.profile_infos, marginLeft: 8}}> <div>{this.props.profile.first_name}</div> <div style={{display: 'flex', fontSize: font_text}}>{this.props.profile.agency.name}</div> </div> <MdArrowDropDown style={{...styles.icons, fontSize: 22, marginLeft: 10}}/> </div> </div> <div style={{fontSize: 20, color: 'white', right: 20, bottom: 15, position: 'absolute'}} dangerouslySetInnerHTML={{__html: this.props.logout_link}}></div> </div> ) : null} </div> )} </Hover> ) case 'md': case 'lg': case 'xl': tabs = [ {path: "/", icon: MdTrendingUp, label: "Activité", is_active: (path) => (path.match(/^\/statistics\/?/) || path == '/')}, {path: "/deals", icon: MdFlag, label: "Missions", is_active: (path) => path.match(/^\/deals\/?/)}, {path: "/users", icon: MdGroup, label: "Répertoire", is_active: (path) => path.match(/^\/users\/?/)}, {path: "/settings", icon: MdSettings, label: "Paramètres", is_active: (path) => path.match(/^\/settings\/?/)}, ] return ( <div style={{flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'space-between'}}> <div style={styles.tab_list}> {tabs.map(({is_active, ...tab}, index) => <Tab {...tab} key={tab.label} index={index} active={is_active(this.props.location.pathname)}/>)} </div> <div style={styles.profile_container}> <div style={styles.profile}> <ProfileImage {...this.props.profile} large hide_status /> <div style={styles.profile_infos}> <div>{this.props.profile.first_name}</div> <div style={{display: 'flex', fontSize: font_text}}>{this.props.profile.agency.name}</div> </div> </div> <Logout onClick={action_logout}> <MdPowerSettingsNew /> </Logout> </div> </div> ) default: return <div></div> } } } const Tab = ({icon: Icon, extended, active, index, path, label}) => { const tab_style = extended ? styles.extended_tab(active, index) : styles.tab(active, index) return ( <TabContainer style={tab_style} onClick={() => browserHistory.push(path)}> <Icon/> <div style={{paddingLeft:10}}> {label} </div> </TabContainer> ) } const TabContainer = styled.div` ${link} ` const Navbar = connect( (state) => { return { profile: state.profile, viewport: state.display.viewport, } } )(NavbarStatic) const styles = { nav_bar: { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'stretch', paddingLeft: 8, backgroundColor: color('primary'), height: 50, zIndex: 2, position: 'relative', }, tab_list: { display: 'flex', flexDirection: 'row', alignItems: 'flex-start', }, tab(activated, index) { return { display: 'flex', flexDirection: 'row', marginLeft: index ? 40 : 20, fontSize: font_title, color: activated ? color('white') : color('black', 'normal', 0.5), alignItems: 'center', } }, extended_tab(activated, index) { return { ...this.tab(activated, index), marginLeft: 8, paddingTop: 8, } }, extended_menu: { display: 'flex', flexDirection:'row', alignItems: 'flex-end', paddingBottom: 15, position: 'absolute', left: 0, top: 50, right: 0, flex: 1, backgroundColor: color('primary'), }, brand(activated) { return { display: 'flex', color: activated ? color('white') : color('black', 'normal', 0.5), marginRight: 8, fontSize: 24, } }, profile_container: { display: 'flex', flexDirection: 'row', alignItems: 'center', color: color('white'), marginRight: 15, }, profile: { display: 'flex', flexDirection: 'row', alignItems: 'center', color: color('white'), }, profile_infos: { display: 'flex', flexDirection: 'column', fontSize: font_title, marginLeft: 20, }, icons: { fontSize: 30, marginLeft: 20, }, } const Logout = styled.div` ${link} font-size: 25px; color: white; margin-left: 20px; ` export default Navbar