1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-17 11:41:44 +00:00

add Logout modal & update PlanetHeader

This commit is contained in:
Rokt33r
2015-07-20 01:12:45 +09:00
parent 0f8eaaf750
commit 6140e93cc8
4 changed files with 150 additions and 109 deletions

View File

@@ -8,24 +8,12 @@ var PlanetHeader = React.createClass({
}, },
getInitialState: function () { getInitialState: function () {
return { return {
isMenuDropDownOpen: false,
search: '' search: ''
} }
}, },
componentDidMount: function () { componentDidMount: function () {
React.findDOMNode(this.refs.search).focus() React.findDOMNode(this.refs.search).focus()
}, },
toggleMenuDropDown: function () {
this.setState({isMenuDropDownOpen: !this.state.isMenuDropDownOpen}, function () {
if (this.state.isMenuDropDownOpen) {
document.body.onclick = function () {
this.setState({isMenuDropDownOpen: false}, function () {
document.body.onclick = null
})
}.bind(this)
}
})
},
interceptClick: function (e) { interceptClick: function (e) {
e.stopPropagation() e.stopPropagation()
}, },
@@ -40,23 +28,25 @@ var PlanetHeader = React.createClass({
}, },
render: function () { render: function () {
var currentPlanetName = this.props.currentPlanet.name var currentPlanetName = this.props.currentPlanet.name
var currentUserName = this.props.currentUser.name
return ( return (
<div onClick={this.interceptClick} className='PlanetHeader'> <div onClick={this.interceptClick} className='PlanetHeader'>
<span className='planetName'>{currentPlanetName}</span> <div className='headerLabel'>
<button onClick={this.toggleMenuDropDown} className={this.state.isMenuDropDownOpen ? 'menuBtn active' : 'menuBtn'}> <span className='userName'>{currentUserName}</span><br/>
<i className='fa fa-chevron-down'></i> <span className='divider'>/</span>
</button> <span className='planetName'>{currentPlanetName}</span>
<div className={this.state.isMenuDropDownOpen ? 'dropDown' : 'dropDown hide'} ref='menuDropDown'> <button className={'menuBtn'}>
<a href='#'><i className='fa fa-wrench fa-fw'/> Planet Setting</a> <i className='fa fa-gears'></i>
<a href='#'><i className='fa fa-group fa-fw'/> Manage member</a> </button>
<a href='#'><i className='fa fa-trash fa-fw'/> Delete Planet</a> </div>
<div className='headerControl'>
<span className='searchInput'>
<i className='fa fa-search'/>
<input onKeyDown={this.handleKeyDown} onChange={this.handleChange} value={this.state.search} ref='search' tabIndex='1' type='text' className='inline-input circleInput' placeholder='Search...'/>
</span>
<a className='downloadButtton btn-primary'>Download Mac app</a>
</div> </div>
<span className='searchInput'>
<i className='fa fa-search'/>
<input onKeyDown={this.handleKeyDown} onChange={this.handleChange} value={this.state.search} ref='search' tabIndex='1' type='text' className='inline-input circleInput' placeholder='Search...'/>
</span>
<a className='downloadButtton btn-primary'>Download Mac app</a>
</div> </div>
) )
} }

View File

@@ -250,7 +250,7 @@ module.exports = React.createClass({
this.setState({isDeleteModalOpen: false}) this.setState({isDeleteModalOpen: false})
}, },
handleKeyDown: function (e) { handleKeyDown: function (e) {
console.log(e.keyCode) // Bypath for modal open state
if (this.state.isLaunchModalOpen) { if (this.state.isLaunchModalOpen) {
if (e.keyCode === 27) this.closeLaunchModal() if (e.keyCode === 27) this.closeLaunchModal()
return return
@@ -264,10 +264,13 @@ module.exports = React.createClass({
return return
} }
// LaunchModal
if ((e.keyCode === 13 && e.metaKey)) { if ((e.keyCode === 13 && e.metaKey)) {
e.preventDefault() e.preventDefault()
this.openLaunchModal() this.openLaunchModal()
} }
// Focus(blur) search input
var searchInput = React.findDOMNode(this).querySelector('.PlanetHeader .searchInput input') var searchInput = React.findDOMNode(this).querySelector('.PlanetHeader .searchInput input')
if (document.activeElement === searchInput) { if (document.activeElement === searchInput) {
@@ -287,6 +290,7 @@ module.exports = React.createClass({
return return
} }
// Article indexing
if (document.activeElement !== searchInput) { if (document.activeElement !== searchInput) {
switch (e.keyCode) { switch (e.keyCode) {
case 38: case 38:
@@ -302,6 +306,7 @@ module.exports = React.createClass({
break break
} }
// Other hotkeys
switch (e.keyCode) { switch (e.keyCode) {
case 65: case 65:
e.preventDefault() e.preventDefault()

View File

@@ -1,13 +1,51 @@
var React = require('react/addons') var React = require('react/addons')
var ReactRouter = require('react-router') var ReactRouter = require('react-router')
var ModalBase = require('../Components/ModalBase')
var AuthActions = require('../Actions/AuthActions') var AuthActions = require('../Actions/AuthActions')
var currentUser = { var AuthStore = require('../Stores/AuthStore')
name: 'testcat',
email: 'testcat@example.com', var LogOutModal = React.createClass({
profileName: 'Test Cat' propTypes: {
} close: React.PropTypes.func
},
componentDidMount: function () {
React.findDOMNode(this.refs.cancel).focus()
},
submit: function () {
AuthActions.logout()
},
handleKeyDown: function (e) {
if (e.keyCode === 13 && e.metaKey) {
this.submit()
return
}
if (e.keyCode === 27) {
this.props.close()
return
}
},
render: function () {
return (
<div onKeyDown={this.handleKeyDown} className='logOutModal modal'>
<div className='modal-header'>
<h1>Logout</h1>
</div>
<div className='modal-body'>
<p>Are you sure to log out?</p>
</div>
<div className='modal-footer'>
<div className='modal-control'>
<button ref='cancel' onClick={this.props.close} className='btn-default'>Cancel</button>
<button onClick={this.submit} className='btn-primary'>Logout</button>
</div>
</div>
</div>
)
}
})
var UserSettingNavigation = React.createClass({ var UserSettingNavigation = React.createClass({
propTypes: { propTypes: {
@@ -17,13 +55,21 @@ var UserSettingNavigation = React.createClass({
current: React.PropTypes.string, current: React.PropTypes.string,
changeCurrent: React.PropTypes.func changeCurrent: React.PropTypes.func
}, },
getInitialState: function () {
return {
isLogOutModalOpen: false
}
},
changeFactory: function (current) { changeFactory: function (current) {
return function () { return function () {
this.props.changeCurrent(current) this.props.changeCurrent(current)
}.bind(this) }.bind(this)
}, },
logOut: function () { openLogOutModal: function () {
AuthActions.logout() this.setState({isLogOutModalOpen: true})
},
closeLogOutModal: function () {
this.setState({isLogOutModalOpen: false})
}, },
render: function () { render: function () {
return ( return (
@@ -34,8 +80,11 @@ var UserSettingNavigation = React.createClass({
<a className={this.props.current === 'setting' ? 'active' : ''} onClick={this.changeFactory('setting')}><i className='fa fa-gears fa-fw'/> Setting</a> <a className={this.props.current === 'setting' ? 'active' : ''} onClick={this.changeFactory('setting')}><i className='fa fa-gears fa-fw'/> Setting</a>
<a className={this.props.current === 'integration' ? 'active' : ''} onClick={this.changeFactory('integration')}><i className='fa fa-share-alt fa-fw'/> Integration</a> <a className={this.props.current === 'integration' ? 'active' : ''} onClick={this.changeFactory('integration')}><i className='fa fa-share-alt fa-fw'/> Integration</a>
<a className={this.props.current === 'help' ? 'active' : ''} onClick={this.changeFactory('help')}><i className='fa fa-info-circle fa-fw'/> Help</a> <a className={this.props.current === 'help' ? 'active' : ''} onClick={this.changeFactory('help')}><i className='fa fa-info-circle fa-fw'/> Help</a>
<a onClick={this.logOut}><i className='fa fa-sign-out fa-fw'/> Logout</a> <a onClick={this.openLogOutModal}><i className='fa fa-sign-out fa-fw'/> Logout</a>
</nav> </nav>
<ModalBase close={this.closeLogOutModal} isOpen={this.state.isLogOutModalOpen}>
<LogOutModal close={this.closeLogOutModal}/>
</ModalBase>
</div> </div>
) )
} }
@@ -112,6 +161,8 @@ module.exports = React.createClass({
}) })
}, },
render: function () { render: function () {
var currentUser = AuthStore.getUser()
return ( return (
<div className='UserSettingContainer'> <div className='UserSettingContainer'>
<UserSettingNavigation currentUser={currentUser} current={this.state.current} changeCurrent={this.changeCurrent}/> <UserSettingNavigation currentUser={currentUser} current={this.state.current} changeCurrent={this.changeCurrent}/>

View File

@@ -20,86 +20,81 @@
box-sizing border-box box-sizing border-box
padding 5px 15px padding 5px 15px
clearfix() clearfix()
.planetName .headerLabel
line-height 30px absolute top left bottom
font-size 2em overflow hidden
color brandColor
line-height 55px
padding 0 20px
.menuBtn
display inline-block display inline-block
position relative
top -5px
font-size 0.8em
color lightButtonColor
border solid 1px lightButtonColor
box-sizing border-box
circle()
background-image none
background-color transparent
width 30px
height 30px
text-align center
cursor pointer
transition 0.1s
transform scale(0.8)
&:focus, &.focus
outline none
&:hover, &.hover, &:focus, &.focus
border-color darken(lightButtonColor, 50%)
color darken(lightButtonColor, 50%)
&:active, &.active
border-color darken(brandBorderColor, 10%)
background-color brandColor
color white
.searchInput
display inline-block
position relative
top -3px
margin-left 15px
input
padding-left 32px
.fa
position absolute
top 7px
left 10px
.downloadButtton
position relative
float right
top 5px
padding 7px 25px
box-sizing border-box
line-height 30px
font-size 1em
border-radius 22px
.dropDown
z-index 500
position fixed
background white
width 200px width 200px
border solid 1px borderColor .userName
box-sizing border-box position absolute
margin-top -5px left 15px
margin-left 125px top 5px
box-shadow popupShadow font-size 1.2em
&.hide color brandColor
visibility hidden .divider
a position absolute
color textColor top 25px
display block left 15px
width 100% font-size 2em
padding 15px .planetName
position absolute
top 28px
left 30px
width 130px
font-size 1.5em
color brandColor
overflow-x hidden
text-overflow ellipsis
white-space nowrap
.menuBtn
position absolute
top 10px
right 0
font-size 1em
color lightButtonColor
border none
box-sizing border-box box-sizing border-box
border-bottom solid 1px borderColor circle()
text-decoration none background-image none
&:hover, &.hover background-color transparent
background-color hoverBackgroundColor width 44px
height 44px
text-align center
cursor pointer
transition 0.1s
transform scale(0.8)
&:focus, &.focus &:focus, &.focus
color black outline none
&:hover, &.hover, &:focus, &.focus
border-color darken(lightButtonColor, 50%)
color darken(lightButtonColor, 50%)
&:active, &.active &:active, &.active
color brandColor border-color darken(brandBorderColor, 10%)
&:last-child background-color brandColor
border-bottom none color white
.headerControl
absolute top bottom right
left 200px
.searchInput
display block
position absolute
top 14px
left 0
input
padding-left 32px
.fa
position absolute
top 8px
left 12px
.downloadButtton
position absolute
right 5px
top 10px
padding 7px 25px
box-sizing border-box
line-height 25px
font-size 1em
border-radius 22px
.PlanetNavigator .PlanetNavigator
absolute bottom left absolute bottom left