1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 01:36:22 +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 () {
return {
isMenuDropDownOpen: false,
search: ''
}
},
componentDidMount: function () {
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) {
e.stopPropagation()
},
@@ -40,23 +28,25 @@ var PlanetHeader = React.createClass({
},
render: function () {
var currentPlanetName = this.props.currentPlanet.name
var currentUserName = this.props.currentUser.name
return (
<div onClick={this.interceptClick} className='PlanetHeader'>
<span className='planetName'>{currentPlanetName}</span>
<button onClick={this.toggleMenuDropDown} className={this.state.isMenuDropDownOpen ? 'menuBtn active' : 'menuBtn'}>
<i className='fa fa-chevron-down'></i>
</button>
<div className={this.state.isMenuDropDownOpen ? 'dropDown' : 'dropDown hide'} ref='menuDropDown'>
<a href='#'><i className='fa fa-wrench fa-fw'/> Planet Setting</a>
<a href='#'><i className='fa fa-group fa-fw'/> Manage member</a>
<a href='#'><i className='fa fa-trash fa-fw'/> Delete Planet</a>
<div className='headerLabel'>
<span className='userName'>{currentUserName}</span><br/>
<span className='divider'>/</span>
<span className='planetName'>{currentPlanetName}</span>
<button className={'menuBtn'}>
<i className='fa fa-gears'></i>
</button>
</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>
<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>
)
}

View File

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

View File

@@ -1,13 +1,51 @@
var React = require('react/addons')
var ReactRouter = require('react-router')
var ModalBase = require('../Components/ModalBase')
var AuthActions = require('../Actions/AuthActions')
var currentUser = {
name: 'testcat',
email: 'testcat@example.com',
profileName: 'Test Cat'
}
var AuthStore = require('../Stores/AuthStore')
var LogOutModal = React.createClass({
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({
propTypes: {
@@ -17,13 +55,21 @@ var UserSettingNavigation = React.createClass({
current: React.PropTypes.string,
changeCurrent: React.PropTypes.func
},
getInitialState: function () {
return {
isLogOutModalOpen: false
}
},
changeFactory: function (current) {
return function () {
this.props.changeCurrent(current)
}.bind(this)
},
logOut: function () {
AuthActions.logout()
openLogOutModal: function () {
this.setState({isLogOutModalOpen: true})
},
closeLogOutModal: function () {
this.setState({isLogOutModalOpen: false})
},
render: function () {
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 === '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 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>
<ModalBase close={this.closeLogOutModal} isOpen={this.state.isLogOutModalOpen}>
<LogOutModal close={this.closeLogOutModal}/>
</ModalBase>
</div>
)
}
@@ -112,6 +161,8 @@ module.exports = React.createClass({
})
},
render: function () {
var currentUser = AuthStore.getUser()
return (
<div className='UserSettingContainer'>
<UserSettingNavigation currentUser={currentUser} current={this.state.current} changeCurrent={this.changeCurrent}/>

View File

@@ -20,86 +20,81 @@
box-sizing border-box
padding 5px 15px
clearfix()
.planetName
line-height 30px
font-size 2em
color brandColor
line-height 55px
padding 0 20px
.menuBtn
.headerLabel
absolute top left bottom
overflow hidden
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
border solid 1px borderColor
box-sizing border-box
margin-top -5px
margin-left 125px
box-shadow popupShadow
&.hide
visibility hidden
a
color textColor
display block
width 100%
padding 15px
.userName
position absolute
left 15px
top 5px
font-size 1.2em
color brandColor
.divider
position absolute
top 25px
left 15px
font-size 2em
.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
border-bottom solid 1px borderColor
text-decoration none
&:hover, &.hover
background-color hoverBackgroundColor
circle()
background-image none
background-color transparent
width 44px
height 44px
text-align center
cursor pointer
transition 0.1s
transform scale(0.8)
&:focus, &.focus
color black
outline none
&:hover, &.hover, &:focus, &.focus
border-color darken(lightButtonColor, 50%)
color darken(lightButtonColor, 50%)
&:active, &.active
color brandColor
&:last-child
border-bottom none
border-color darken(brandBorderColor, 10%)
background-color brandColor
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
absolute bottom left