mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-14 10:16:26 +00:00
add PersonalSettingModal
This commit is contained in:
@@ -3,5 +3,6 @@ var Reflux = require('reflux')
|
|||||||
module.exports = Reflux.createActions([
|
module.exports = Reflux.createActions([
|
||||||
'login',
|
'login',
|
||||||
'register',
|
'register',
|
||||||
'logout'
|
'logout',
|
||||||
|
'updateProfile'
|
||||||
])
|
])
|
||||||
|
|||||||
171
browser/main/Components/PersonalSettingModal.jsx
Normal file
171
browser/main/Components/PersonalSettingModal.jsx
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
/* global localStorage */
|
||||||
|
var React = require('react/addons')
|
||||||
|
var request = require('superagent')
|
||||||
|
|
||||||
|
var Catalyst = require('../Mixins/Catalyst')
|
||||||
|
|
||||||
|
var AuthActions = require('../Actions/AuthActions')
|
||||||
|
|
||||||
|
var apiUrl = 'http://localhost:8000/'
|
||||||
|
|
||||||
|
module.exports = React.createClass({
|
||||||
|
mixins: [Catalyst.LinkedStateMixin],
|
||||||
|
propTypes: {
|
||||||
|
close: React.PropTypes.func,
|
||||||
|
currentUser: React.PropTypes.object
|
||||||
|
},
|
||||||
|
getInitialState: function () {
|
||||||
|
return {
|
||||||
|
currentTab: 'profile',
|
||||||
|
userName: this.props.currentUser.name,
|
||||||
|
email: this.props.currentUser.email,
|
||||||
|
currentPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
confirmation: '',
|
||||||
|
contactTitle: '',
|
||||||
|
contactContent: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
activeProfile: function () {
|
||||||
|
this.setState({currentTab: 'profile'})
|
||||||
|
},
|
||||||
|
activeContact: function () {
|
||||||
|
this.setState({currentTab: 'contact'})
|
||||||
|
},
|
||||||
|
activeInfo: function () {
|
||||||
|
this.setState({currentTab: 'info'})
|
||||||
|
},
|
||||||
|
activeLogout: function () {
|
||||||
|
this.setState({currentTab: 'logout'})
|
||||||
|
},
|
||||||
|
saveProfile: function () {
|
||||||
|
AuthActions.updateProfile({
|
||||||
|
name: this.state.userName,
|
||||||
|
email: this.state.email
|
||||||
|
})
|
||||||
|
},
|
||||||
|
savePassword: function () {
|
||||||
|
if (this.state.newPassword === this.state.confirmation) {
|
||||||
|
request
|
||||||
|
.put(apiUrl + 'auth/password')
|
||||||
|
.set({
|
||||||
|
Authorization: 'Bearer ' + localStorage.getItem('token')
|
||||||
|
})
|
||||||
|
.send({
|
||||||
|
currentPassword: this.state.currentPassword,
|
||||||
|
newPassword: this.state.newPassword
|
||||||
|
})
|
||||||
|
.end(function (err, res) {
|
||||||
|
this.setState({
|
||||||
|
currentPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
confirmation: ''
|
||||||
|
})
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}.bind(this))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sendEmail: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
logOut: function () {
|
||||||
|
AuthActions.logout()
|
||||||
|
},
|
||||||
|
interceptClick: function (e) {
|
||||||
|
e.stopPropagation()
|
||||||
|
},
|
||||||
|
render: function () {
|
||||||
|
var content
|
||||||
|
if (this.state.currentTab === 'profile') {
|
||||||
|
content = (
|
||||||
|
<div className='profile'>
|
||||||
|
<div className='profileTop'>
|
||||||
|
<div className='profileFormRow'>
|
||||||
|
<label>Name</label>
|
||||||
|
<input valueLink={this.linkState('userName')} className='block-input' type='text' placeholder='Name'/>
|
||||||
|
</div>
|
||||||
|
<div className='profileFormRow'>
|
||||||
|
<label>E-mail</label>
|
||||||
|
<input valueLink={this.linkState('email')} className='block-input' type='text' placeholder='E-mail'/>
|
||||||
|
</div>
|
||||||
|
<div className='profileFormRow'>
|
||||||
|
<button onClick={this.saveProfile} className='saveButton btn-primary'>Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='profileBottom'>
|
||||||
|
<div className='profileFormRow'>
|
||||||
|
<label>Current password</label>
|
||||||
|
<input valueLink={this.linkState('currentPassword')} className='block-input' type='password' placeholder='Current password'/>
|
||||||
|
</div>
|
||||||
|
<div className='profileFormRow'>
|
||||||
|
<label>New password</label>
|
||||||
|
<input valueLink={this.linkState('newPassword')} className='block-input' type='password' placeholder='New password'/>
|
||||||
|
</div>
|
||||||
|
<div className='profileFormRow'>
|
||||||
|
<label>Confirmation</label>
|
||||||
|
<input valueLink={this.linkState('confirmation')} className='block-input' type='password' placeholder='Confirmation'/>
|
||||||
|
</div>
|
||||||
|
<div className='profileFormRow'>
|
||||||
|
<button onClick={this.savePassword} className='saveButton btn-primary'>Save</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else if (this.state.currentTab === 'contact') {
|
||||||
|
content = (
|
||||||
|
<div className='contact'>
|
||||||
|
<p>
|
||||||
|
Let us know your opinion about CodeXen.<br/>
|
||||||
|
Your feedback might be used to improvement of CodeXen.
|
||||||
|
</p>
|
||||||
|
<input valueLink={this.linkState('contactTitle')} className='block-input' type='text' placeholder='title'/>
|
||||||
|
<textarea valueLink={this.linkState('contactContent')} className='block-input' placeholder='message content'/>
|
||||||
|
<div className='contactFormRow'>
|
||||||
|
<button onClick={this.sendEmail} className='saveButton btn-primary'>Send</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else if (this.state.currentTab === 'info') {
|
||||||
|
content = (
|
||||||
|
<div className='info'>
|
||||||
|
<h2 className='infoLabel'>External links</h2>
|
||||||
|
<ul className='externalList'>
|
||||||
|
<li><a>CodeXen Homepage <i className='fa fa-external-link'/></a></li>
|
||||||
|
<li><a>Regulation <i className='fa fa-external-link'/></a></li>
|
||||||
|
<li><a>Private policy <i className='fa fa-external-link'/></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
content = (
|
||||||
|
<div className='logout'>
|
||||||
|
<p className='logoutLabel'>Are you sure to logout?</p>
|
||||||
|
<img className='userPhoto' width='150' height='150' src='../vendor/dummy.jpg'/><br/>
|
||||||
|
<button onClick={this.logOut} className='logoutButton btn-default'>Logout</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div onClick={this.interceptClick} className='PersonalSettingModal modal'>
|
||||||
|
<div className='settingNav'>
|
||||||
|
<h1>Personal setting</h1>
|
||||||
|
<nav>
|
||||||
|
<button className={this.state.currentTab === 'profile' ? 'active' : ''} onClick={this.activeProfile}><i className='fa fa-user fa-fw'/> Profile</button>
|
||||||
|
<button className={this.state.currentTab === 'contact' ? 'active' : ''} onClick={this.activeContact}><i className='fa fa-phone fa-fw'/> Contact</button>
|
||||||
|
<button className={this.state.currentTab === 'info' ? 'active' : ''} onClick={this.activeInfo}><i className='fa fa-info-circle fa-fw'/> Info</button>
|
||||||
|
<button className={this.state.currentTab === 'logout' ? 'active' : ''} onClick={this.activeLogout}><i className='fa fa-sign-out fa-fw'/> Logout</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div className='settingBody'>
|
||||||
|
{content}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -22,8 +22,8 @@ module.exports = React.createClass({
|
|||||||
this.setState({currentTab: 'planetProfile'})
|
this.setState({currentTab: 'planetProfile'})
|
||||||
|
|
||||||
},
|
},
|
||||||
activeManageMember: function () {
|
activeMembers: function () {
|
||||||
this.setState({currentTab: 'manageMember'})
|
this.setState({currentTab: 'members'})
|
||||||
},
|
},
|
||||||
saveProfile: function () {
|
saveProfile: function () {
|
||||||
var currentPlanet = this.props.currentPlanet
|
var currentPlanet = this.props.currentPlanet
|
||||||
@@ -79,7 +79,7 @@ module.exports = React.createClass({
|
|||||||
}.bind(this))
|
}.bind(this))
|
||||||
|
|
||||||
content = (
|
content = (
|
||||||
<div className='manageMember'>
|
<div className='members'>
|
||||||
<ul className='userList'>
|
<ul className='userList'>
|
||||||
{members}
|
{members}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -99,8 +99,8 @@ module.exports = React.createClass({
|
|||||||
<div className='settingNav'>
|
<div className='settingNav'>
|
||||||
<h1>Planet setting</h1>
|
<h1>Planet setting</h1>
|
||||||
<nav>
|
<nav>
|
||||||
<button className={this.state.currentTab === 'planetProfile' ? 'active' : ''} onClick={this.activePlanetProfile}><i className='fa fa-globe'/> Planet profile</button>
|
<button className={this.state.currentTab === 'planetProfile' ? 'active' : ''} onClick={this.activePlanetProfile}><i className='fa fa-globe fa-fw'/> Planet profile</button>
|
||||||
<button className={this.state.currentTab === 'manageMember' ? 'active' : ''} onClick={this.activeManageMember}><i className='fa fa-group'/> Manage member</button>
|
<button className={this.state.currentTab === 'members' ? 'active' : ''} onClick={this.activeMembers}><i className='fa fa-group fa-fw'/> Members</button>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ var ReactRouter = require('react-router')
|
|||||||
var Link = ReactRouter.Link
|
var Link = ReactRouter.Link
|
||||||
|
|
||||||
var ModalBase = require('./ModalBase')
|
var ModalBase = require('./ModalBase')
|
||||||
|
var PersonalSettingModal = require('./PersonalSettingModal')
|
||||||
var PlanetCreateModal = require('./PlanetCreateModal')
|
var PlanetCreateModal = require('./PlanetCreateModal')
|
||||||
|
|
||||||
var AuthStore = require('../Stores/AuthStore')
|
var AuthStore = require('../Stores/AuthStore')
|
||||||
@@ -27,6 +28,12 @@ module.exports = React.createClass({
|
|||||||
onLogout: function () {
|
onLogout: function () {
|
||||||
this.transitionTo('login')
|
this.transitionTo('login')
|
||||||
},
|
},
|
||||||
|
openPersonalSettingModal: function () {
|
||||||
|
this.setState({isPersonalSettingModalOpen: true})
|
||||||
|
},
|
||||||
|
closePersonalSettingModal: function () {
|
||||||
|
this.setState({isPersonalSettingModalOpen: false})
|
||||||
|
},
|
||||||
openPlanetCreateModal: function () {
|
openPlanetCreateModal: function () {
|
||||||
this.setState({isPlanetCreateModalOpen: true})
|
this.setState({isPlanetCreateModalOpen: true})
|
||||||
},
|
},
|
||||||
@@ -51,13 +58,18 @@ module.exports = React.createClass({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div tabIndex='2' className='UserNavigator'>
|
<div tabIndex='2' className='UserNavigator'>
|
||||||
<Link to='userHome' params={{userName: this.props.currentUser.name}} className='userConfig'>
|
<button onClick={this.openPersonalSettingModal} className='userButton'>
|
||||||
<img width='50' height='50' src='../vendor/dummy.jpg'/>
|
<img width='50' height='50' src='../vendor/dummy.jpg'/>
|
||||||
</Link>
|
</button>
|
||||||
<ul>
|
<ul className='planetList'>
|
||||||
{planets}
|
{planets}
|
||||||
</ul>
|
</ul>
|
||||||
<button onClick={this.openPlanetCreateModal} className='newPlanet'><i className='fa fa-plus'/></button>
|
<button onClick={this.openPlanetCreateModal} className='newPlanet'><i className='fa fa-plus'/></button>
|
||||||
|
|
||||||
|
<ModalBase isOpen={this.state.isPersonalSettingModalOpen} close={this.closePersonalSettingModal}>
|
||||||
|
<PersonalSettingModal currentUser={this.props.currentUser} close={this.closePersonalSettingModal}/>
|
||||||
|
</ModalBase>
|
||||||
|
|
||||||
<ModalBase isOpen={this.state.isPlanetCreateModalOpen} close={this.closePlanetCreateModal}>
|
<ModalBase isOpen={this.state.isPlanetCreateModalOpen} close={this.closePlanetCreateModal}>
|
||||||
<PlanetCreateModal close={this.closePlanetCreateModal}/>
|
<PlanetCreateModal close={this.closePlanetCreateModal}/>
|
||||||
</ModalBase>
|
</ModalBase>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ var React = require('react/addons')
|
|||||||
var ReactRouter = require('react-router')
|
var ReactRouter = require('react-router')
|
||||||
var Link = ReactRouter.Link
|
var Link = ReactRouter.Link
|
||||||
|
|
||||||
var AuthStore = require('../Stores/AuthStore')
|
|
||||||
var AuthActions = require('../Actions/AuthActions')
|
var AuthActions = require('../Actions/AuthActions')
|
||||||
|
|
||||||
var OnlyGuest = require('../Mixins/OnlyGuest')
|
var OnlyGuest = require('../Mixins/OnlyGuest')
|
||||||
@@ -15,12 +14,6 @@ module.exports = React.createClass({
|
|||||||
password: ''
|
password: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
|
||||||
this.unsubscribe = AuthStore.listen(this.onLogin)
|
|
||||||
},
|
|
||||||
componentWillUnmount: function () {
|
|
||||||
this.unsubscribe()
|
|
||||||
},
|
|
||||||
handleSubmit: function (e) {
|
handleSubmit: function (e) {
|
||||||
AuthActions.login({
|
AuthActions.login({
|
||||||
email: this.state.email,
|
email: this.state.email,
|
||||||
@@ -28,14 +21,6 @@ module.exports = React.createClass({
|
|||||||
})
|
})
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
},
|
},
|
||||||
onLogin: function (user) {
|
|
||||||
var planet = user.Planets.length > 0 ? user.Planets[0] : null
|
|
||||||
if (planet == null) {
|
|
||||||
this.transitionTo('user', {userName: user.name})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.transitionTo('planetHome', {userName: user.name, planetName: planet.name})
|
|
||||||
},
|
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
<div className='LoginContainer'>
|
<div className='LoginContainer'>
|
||||||
|
|||||||
@@ -2,8 +2,33 @@ var React = require('react/addons')
|
|||||||
var ReactRouter = require('react-router')
|
var ReactRouter = require('react-router')
|
||||||
var RouteHandler = ReactRouter.RouteHandler
|
var RouteHandler = ReactRouter.RouteHandler
|
||||||
|
|
||||||
|
var AuthStore = require('../Stores/AuthStore')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [ReactRouter.Navigation, ReactRouter.State],
|
mixins: [ReactRouter.Navigation, ReactRouter.State],
|
||||||
|
componentDidMount: function () {
|
||||||
|
this.unsubscribe = AuthStore.listen(this.onListen)
|
||||||
|
},
|
||||||
|
componentWillUnmount: function () {
|
||||||
|
this.unsubscribe()
|
||||||
|
},
|
||||||
|
onListen: function (res) {
|
||||||
|
if (res.status === 'loggedIn' || res.status === 'registered') {
|
||||||
|
var user = res.data
|
||||||
|
var planet = user.Planets.length > 0 ? user.Planets[0] : null
|
||||||
|
if (planet == null) {
|
||||||
|
this.transitionTo('user', {userName: user.name})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.transitionTo('planetHome', {userName: user.name, planetName: planet.name})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.status === 'loggedOut') {
|
||||||
|
this.transitionTo('login')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
// Redirect Login state
|
// Redirect Login state
|
||||||
if (this.getPath() === '/') {
|
if (this.getPath() === '/') {
|
||||||
|
|||||||
@@ -56,18 +56,21 @@ module.exports = React.createClass({
|
|||||||
},
|
},
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
return {
|
return {
|
||||||
|
currentUser: AuthStore.getUser(),
|
||||||
currentPlanet: null,
|
currentPlanet: null,
|
||||||
search: '',
|
search: '',
|
||||||
isFetched: false
|
isFetched: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
this.unsubscribe = PlanetStore.listen(this.onFetched)
|
this.unsubscribePlanet = PlanetStore.listen(this.onFetched)
|
||||||
|
this.unsubscribeAuth = AuthStore.listen(this.onListenAuth)
|
||||||
|
|
||||||
PlanetActions.fetchPlanet(this.props.params.userName, this.props.params.planetName)
|
PlanetActions.fetchPlanet(this.props.params.userName, this.props.params.planetName)
|
||||||
},
|
},
|
||||||
componentWillUnmount: function () {
|
componentWillUnmount: function () {
|
||||||
this.unsubscribe()
|
this.unsubscribePlanet()
|
||||||
|
this.unsubscribeAuth()
|
||||||
},
|
},
|
||||||
componentDidUpdate: function () {
|
componentDidUpdate: function () {
|
||||||
if (this.state.currentPlanet == null || this.state.currentPlanet.name !== this.props.params.planetName || this.state.currentPlanet.userName !== this.props.params.userName) {
|
if (this.state.currentPlanet == null || this.state.currentPlanet.name !== this.props.params.planetName || this.state.currentPlanet.userName !== this.props.params.userName) {
|
||||||
@@ -161,6 +164,19 @@ module.exports = React.createClass({
|
|||||||
React.findDOMNode(this).querySelector('.PlanetHeader .searchInput input').focus()
|
React.findDOMNode(this).querySelector('.PlanetHeader .searchInput input').focus()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onListenAuth: function (res) {
|
||||||
|
if (res.status === 'userProfileUpdated') {
|
||||||
|
if (this.state.currentPlanet != null) {
|
||||||
|
res.data.Planets.some(function (planet) {
|
||||||
|
if (planet.id === this.state.currentPlanet.id) {
|
||||||
|
this.transitionTo('planet', {userName: planet.userName, planetName: planet.name})
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}.bind(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
onFetched: function (res) {
|
onFetched: function (res) {
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
return
|
return
|
||||||
@@ -396,8 +412,7 @@ module.exports = React.createClass({
|
|||||||
|
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var user = AuthStore.getUser()
|
if (this.state.currentUser == null) return (<div/>)
|
||||||
if (user == null) return (<div/>)
|
|
||||||
if (this.state.currentPlanet == null) return (<div/>)
|
if (this.state.currentPlanet == null) return (<div/>)
|
||||||
|
|
||||||
var localId = parseInt(this.props.params.localId, 10)
|
var localId = parseInt(this.props.params.localId, 10)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ var React = require('react/addons')
|
|||||||
var ReactRouter = require('react-router')
|
var ReactRouter = require('react-router')
|
||||||
var Link = ReactRouter.Link
|
var Link = ReactRouter.Link
|
||||||
|
|
||||||
var AuthStore = require('../Stores/AuthStore')
|
|
||||||
var AuthActions = require('../Actions/AuthActions')
|
var AuthActions = require('../Actions/AuthActions')
|
||||||
|
|
||||||
var OnlyGuest = require('../Mixins/OnlyGuest')
|
var OnlyGuest = require('../Mixins/OnlyGuest')
|
||||||
@@ -17,12 +16,6 @@ module.exports = React.createClass({
|
|||||||
profileName: ''
|
profileName: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
|
||||||
this.unsubscribe = AuthStore.listen(this.onRegister)
|
|
||||||
},
|
|
||||||
componentWillUnmount: function () {
|
|
||||||
this.unsubscribe()
|
|
||||||
},
|
|
||||||
handleSubmit: function (e) {
|
handleSubmit: function (e) {
|
||||||
AuthActions.register({
|
AuthActions.register({
|
||||||
email: this.state.email,
|
email: this.state.email,
|
||||||
@@ -33,14 +26,6 @@ module.exports = React.createClass({
|
|||||||
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
},
|
},
|
||||||
onRegister: function (user) {
|
|
||||||
var planet = user.Planets.length > 0 ? user.Planets[0] : null
|
|
||||||
if (planet == null) {
|
|
||||||
this.transitionTo('user', {userName: user.name})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.transitionTo('planetHome', {userName: user.name, planetName: planet.name})
|
|
||||||
},
|
|
||||||
render: function () {
|
render: function () {
|
||||||
return (
|
return (
|
||||||
<div className='RegisterContainer'>
|
<div className='RegisterContainer'>
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
var React = require('react/addons')
|
var React = require('react/addons')
|
||||||
var ReactRouter = require('react-router')
|
var ReactRouter = require('react-router')
|
||||||
var RouteHandler = ReactRouter.RouteHandler
|
var RouteHandler = ReactRouter.RouteHandler
|
||||||
|
var Link = ReactRouter.Link
|
||||||
|
var request = require('superagent')
|
||||||
|
|
||||||
var UserNavigator = require('../Components/UserNavigator')
|
var UserNavigator = require('../Components/UserNavigator')
|
||||||
|
|
||||||
@@ -9,22 +11,49 @@ var AuthStore = require('../Stores/AuthStore')
|
|||||||
var PlanetStore = require('../Stores/PlanetStore')
|
var PlanetStore = require('../Stores/PlanetStore')
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
mixins: [React.addons.LinkedStateMixin, ReactRouter.Navigation],
|
mixins: [React.addons.LinkedStateMixin, ReactRouter.Navigation, ReactRouter.State],
|
||||||
propTypes: {
|
propTypes: {
|
||||||
params: React.PropTypes.shape({
|
params: React.PropTypes.shape({
|
||||||
|
userName: React.PropTypes.string,
|
||||||
planetName: React.PropTypes.string
|
planetName: React.PropTypes.string
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
return {
|
return {
|
||||||
currentUser: AuthStore.getUser()
|
currentUser: AuthStore.getUser(),
|
||||||
|
isUserFetched: false,
|
||||||
|
user: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
this.unsubscribe = PlanetStore.listen(this.onListen)
|
this.unsubscribePlanet = PlanetStore.listen(this.onListen)
|
||||||
|
this.unsubscribeAuth = AuthStore.listen(this.onListen)
|
||||||
|
|
||||||
|
if (this.isActive('userHome')) {
|
||||||
|
this.fetchUser(this.props.params.userName)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
componentWillUnmount: function () {
|
componentWillUnmount: function () {
|
||||||
this.unsubscribe()
|
this.unsubscribePlanet()
|
||||||
|
this.unsubscribeAuth()
|
||||||
|
},
|
||||||
|
componentDidUpdate: function () {
|
||||||
|
if (this.isActive('userHome') && (this.state.user == null || this.state.user.name !== this.props.params.userName)) {
|
||||||
|
this.fetchUser(this.props.params.userName)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fetchUser: function (userName) {
|
||||||
|
request
|
||||||
|
.get('http://localhost:8000/' + userName)
|
||||||
|
.send()
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({user: res.body, isUserFetched: true})
|
||||||
|
}.bind(this))
|
||||||
},
|
},
|
||||||
onListen: function (res) {
|
onListen: function (res) {
|
||||||
if (res.status == null) return
|
if (res.status == null) return
|
||||||
@@ -40,10 +69,15 @@ module.exports = React.createClass({
|
|||||||
if (res.status === 'nameChanged') {
|
if (res.status === 'nameChanged') {
|
||||||
this.setState({currentUser: AuthStore.getUser()})
|
this.setState({currentUser: AuthStore.getUser()})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res.status === 'userProfileUpdated') {
|
||||||
|
this.setState({currentUser: AuthStore.getUser()})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
render: function () {
|
render: function () {
|
||||||
var currentPlanetName = this.props.params.planetName
|
var currentPlanetName = this.props.params.planetName
|
||||||
var currentUser = this.state.currentUser
|
var currentUser = this.state.currentUser
|
||||||
|
var user = this.state.user
|
||||||
|
|
||||||
// user must be logged in
|
// user must be logged in
|
||||||
if (currentUser == null) return (<div></div>)
|
if (currentUser == null) return (<div></div>)
|
||||||
@@ -57,10 +91,49 @@ module.exports = React.createClass({
|
|||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var content
|
||||||
|
if (this.isActive('userHome')) {
|
||||||
|
if (this.state.isUserFetched === false) {
|
||||||
|
content = (
|
||||||
|
<div className='UserHome'>
|
||||||
|
User Loading...
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
var planets = user.Planets.map(function (planet) {
|
||||||
|
return (
|
||||||
|
<li key={'planet-' + planet.id}>
|
||||||
|
<Link to='planet' params={{userName: planet.userName, planetName: planet.name}}>{planet.userName}/{planet.name}</Link>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
content = (
|
||||||
|
<div className='UserHome'>
|
||||||
|
<h1>User Profile</h1>
|
||||||
|
<div className='userProfile'>
|
||||||
|
<img className='userPhoto' width='150' height='150' src='../vendor/dummy.jpg'/>
|
||||||
|
<div className='userIntro'>
|
||||||
|
<div className='userProfileName'>{user.profileName}</div>
|
||||||
|
<Link className='userName' to='user' params={{userName: user.name}}>{user.name}</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2>Planets</h2>
|
||||||
|
<ul className='userPlanetList'>
|
||||||
|
{planets}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content = (
|
||||||
|
<RouteHandler/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='UserContainer'>
|
<div className='UserContainer'>
|
||||||
<UserNavigator currentPlanet={currentPlanet} currentUser={currentUser}/>
|
<UserNavigator currentPlanet={currentPlanet} currentUser={currentUser}/>
|
||||||
<RouteHandler/>
|
{content}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,19 @@ var request = require('superagent')
|
|||||||
|
|
||||||
var AuthActions = require('../Actions/AuthActions')
|
var AuthActions = require('../Actions/AuthActions')
|
||||||
|
|
||||||
|
var apiUrl = 'http://localhost:8000/'
|
||||||
|
|
||||||
var AuthStore = Reflux.createStore({
|
var AuthStore = Reflux.createStore({
|
||||||
init: function () {
|
init: function () {
|
||||||
this.listenTo(AuthActions.login, this.login)
|
this.listenTo(AuthActions.login, this.login)
|
||||||
this.listenTo(AuthActions.register, this.register)
|
this.listenTo(AuthActions.register, this.register)
|
||||||
this.listenTo(AuthActions.logout, this.logout)
|
this.listenTo(AuthActions.logout, this.logout)
|
||||||
|
this.listenTo(AuthActions.updateProfile, this.updateProfile)
|
||||||
},
|
},
|
||||||
// Reflux Store
|
// Reflux Store
|
||||||
login: function (input) {
|
login: function (input) {
|
||||||
request
|
request
|
||||||
.post('http://localhost:8000/auth/login')
|
.post(apiUrl + 'auth/login')
|
||||||
.send(input)
|
.send(input)
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.end(function (err, res) {
|
.end(function (err, res) {
|
||||||
@@ -27,12 +30,15 @@ var AuthStore = Reflux.createStore({
|
|||||||
localStorage.setItem('token', res.body.token)
|
localStorage.setItem('token', res.body.token)
|
||||||
localStorage.setItem('user', JSON.stringify(res.body.user))
|
localStorage.setItem('user', JSON.stringify(res.body.user))
|
||||||
|
|
||||||
this.trigger(user)
|
this.trigger({
|
||||||
|
status: 'loggedIn',
|
||||||
|
data: user
|
||||||
|
})
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
},
|
},
|
||||||
register: function (input) {
|
register: function (input) {
|
||||||
request
|
request
|
||||||
.post('http://localhost:8000/auth/signup')
|
.post(apiUrl + 'auth/signup')
|
||||||
.send(input)
|
.send(input)
|
||||||
.set('Accept', 'application/json')
|
.set('Accept', 'application/json')
|
||||||
.end(function (err, res) {
|
.end(function (err, res) {
|
||||||
@@ -46,14 +52,42 @@ var AuthStore = Reflux.createStore({
|
|||||||
localStorage.setItem('token', res.body.token)
|
localStorage.setItem('token', res.body.token)
|
||||||
localStorage.setItem('user', JSON.stringify(res.body.user))
|
localStorage.setItem('user', JSON.stringify(res.body.user))
|
||||||
|
|
||||||
this.trigger(user)
|
this.trigger({
|
||||||
|
status: 'registered',
|
||||||
|
data: user
|
||||||
|
})
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
},
|
},
|
||||||
logout: function () {
|
logout: function () {
|
||||||
localStorage.removeItem('token')
|
localStorage.removeItem('token')
|
||||||
localStorage.removeItem('user')
|
localStorage.removeItem('user')
|
||||||
|
|
||||||
this.trigger()
|
this.trigger({
|
||||||
|
status: 'loggedOut'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
updateProfile: function (input) {
|
||||||
|
request
|
||||||
|
.put(apiUrl + 'auth/user')
|
||||||
|
.set({
|
||||||
|
Authorization: 'Bearer ' + localStorage.getItem('token')
|
||||||
|
})
|
||||||
|
.send(input)
|
||||||
|
.end(function (err, res) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
this.trigger(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = res.body
|
||||||
|
localStorage.setItem('user', JSON.stringify(user))
|
||||||
|
|
||||||
|
this.trigger({
|
||||||
|
status: 'userProfileUpdated',
|
||||||
|
data: user
|
||||||
|
})
|
||||||
|
}.bind(this))
|
||||||
},
|
},
|
||||||
// Methods
|
// Methods
|
||||||
check: function () {
|
check: function () {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ var LoginContainer = require('./Containers/LoginContainer.jsx')
|
|||||||
var RegisterContainer = require('./Containers/RegisterContainer.jsx')
|
var RegisterContainer = require('./Containers/RegisterContainer.jsx')
|
||||||
|
|
||||||
var UserContainer = require('./Containers/UserContainer.jsx')
|
var UserContainer = require('./Containers/UserContainer.jsx')
|
||||||
var UserSettingContainer = require('./Containers/UserSettingContainer.jsx')
|
|
||||||
var PlanetContainer = require('./Containers/PlanetContainer.jsx')
|
var PlanetContainer = require('./Containers/PlanetContainer.jsx')
|
||||||
|
|
||||||
var routes = (
|
var routes = (
|
||||||
@@ -22,7 +22,7 @@ var routes = (
|
|||||||
<Route name='register' path='register' handler={RegisterContainer}/>
|
<Route name='register' path='register' handler={RegisterContainer}/>
|
||||||
|
|
||||||
<Route name='user' path=':userName' handler={UserContainer}>
|
<Route name='user' path=':userName' handler={UserContainer}>
|
||||||
<DefaultRoute name='userHome' handler={UserSettingContainer}/>
|
<DefaultRoute name='userHome'/>
|
||||||
<Route name='planet' path=':planetName' handler={PlanetContainer}>
|
<Route name='planet' path=':planetName' handler={PlanetContainer}>
|
||||||
<DefaultRoute name='planetHome'/>
|
<DefaultRoute name='planetHome'/>
|
||||||
<Route name='snippets' path='snippets/:localId'/>
|
<Route name='snippets' path='snippets/:localId'/>
|
||||||
|
|||||||
@@ -5,19 +5,23 @@
|
|||||||
width 50px
|
width 50px
|
||||||
text-align center
|
text-align center
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
a.userConfig
|
.userButton
|
||||||
display block
|
display block
|
||||||
width 50px
|
width 50px
|
||||||
height 50px
|
height 50px
|
||||||
background-color black
|
background-color black
|
||||||
|
margin 0
|
||||||
|
padding 0
|
||||||
|
border none
|
||||||
|
cursor pointer
|
||||||
img
|
img
|
||||||
transition 0.1s
|
transition 0.1s
|
||||||
opacity 0.6
|
opacity 0.8
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
&.active, &:active, &.focus, &:focus, &.hover, &:hover
|
&.active, &:active, &.focus, &:focus, &.hover, &:hover
|
||||||
img
|
img
|
||||||
opacity 1
|
opacity 1
|
||||||
ul>li
|
ul.planetList>li
|
||||||
padding 10px 3px
|
padding 10px 3px
|
||||||
.shortCut
|
.shortCut
|
||||||
margin-top 5px
|
margin-top 5px
|
||||||
@@ -68,3 +72,29 @@
|
|||||||
border-color darken(brandBorderColor, 10%)
|
border-color darken(brandBorderColor, 10%)
|
||||||
background-color brandColor
|
background-color brandColor
|
||||||
color white
|
color white
|
||||||
|
.UserHome
|
||||||
|
absolute top bottom right
|
||||||
|
left 50px
|
||||||
|
box-sizing border-box
|
||||||
|
padding 15px
|
||||||
|
h1
|
||||||
|
margin 15px 0
|
||||||
|
.userProfile
|
||||||
|
clearfix()
|
||||||
|
.userPhoto
|
||||||
|
circle()
|
||||||
|
float left
|
||||||
|
margin 25px
|
||||||
|
.userIntro
|
||||||
|
float left
|
||||||
|
margin-top 25px
|
||||||
|
.userProfileName
|
||||||
|
font-size 2em
|
||||||
|
margin-bottom 15px
|
||||||
|
.userName
|
||||||
|
font-size 1.5em
|
||||||
|
.userPlanetList
|
||||||
|
padding-left 20px
|
||||||
|
li
|
||||||
|
font-size 1.3em
|
||||||
|
margin 10px
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
btnDefault()
|
btnDefault()
|
||||||
border-style solid
|
border-style solid
|
||||||
border-width 1px
|
border-width 1px
|
||||||
border-color brandBorderColor
|
border-color lightButtonColor
|
||||||
background-color transparent
|
background-color transparent
|
||||||
color brandColor
|
color lightButtonColor
|
||||||
|
|
||||||
&:hover, &.hover, &:focus, &.focus
|
&:hover, &.hover, &:focus, &.focus
|
||||||
border-color darken(brandBorderColor, 30%)
|
border-color darken(lightButtonColor, 50%)
|
||||||
color darken(brandColor, 30%)
|
color darken(lightButtonColor, 50%)
|
||||||
&:active, &.active
|
&:active, &.active
|
||||||
|
border-color darken(brandBorderColor, 10%)
|
||||||
background-color brandColor
|
background-color brandColor
|
||||||
color white
|
color white
|
||||||
|
|
||||||
|
|
||||||
btnPrimary()
|
btnPrimary()
|
||||||
border-style solid
|
border-style solid
|
||||||
border-width 1px
|
border-width 1px
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
height 55px
|
height 55px
|
||||||
circle()
|
circle()
|
||||||
btnPrimary()
|
btnPrimary()
|
||||||
.PlanetSettingModal.modal
|
.PlanetSettingModal.modal, .PersonalSettingModal.modal
|
||||||
width 720px
|
width 720px
|
||||||
height 500px
|
height 500px
|
||||||
.settingNav
|
.settingNav
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
padding 10px
|
padding 10px
|
||||||
border-right solid 1px borderColor
|
border-right solid 1px borderColor
|
||||||
h1
|
h1
|
||||||
margin 40px 15px
|
margin 40px auto
|
||||||
font-size 1.5em
|
font-size 1.5em
|
||||||
color brandColor
|
color brandColor
|
||||||
nav
|
nav
|
||||||
@@ -139,11 +139,70 @@
|
|||||||
background-color hoverBackgroundColor
|
background-color hoverBackgroundColor
|
||||||
&:active, &.active
|
&:active, &.active
|
||||||
color brandColor
|
color brandColor
|
||||||
|
|
||||||
.settingBody
|
.settingBody
|
||||||
absolute top bottom right
|
absolute top bottom right
|
||||||
left 200px
|
left 200px
|
||||||
padding 15px
|
padding 15px
|
||||||
|
.PersonalSettingModal.modal
|
||||||
|
.settingBody
|
||||||
|
.profile
|
||||||
|
height 500px
|
||||||
|
padding-top 50px
|
||||||
|
.profileTop
|
||||||
|
box-sizing border-box
|
||||||
|
height 200px
|
||||||
|
border-bottom solid 1px borderColor
|
||||||
|
.profileBottom
|
||||||
|
margin-top 25px
|
||||||
|
height 200px
|
||||||
|
.profileFormRow
|
||||||
|
clearfix()
|
||||||
|
margin-bottom 15px
|
||||||
|
label
|
||||||
|
display block
|
||||||
|
float left
|
||||||
|
width 150px
|
||||||
|
line-height 33px
|
||||||
|
text-align left
|
||||||
|
input
|
||||||
|
float left
|
||||||
|
width 250px
|
||||||
|
.saveButton
|
||||||
|
float right
|
||||||
|
.contact
|
||||||
|
height 500px
|
||||||
|
padding-top 50px
|
||||||
|
p
|
||||||
|
text-align left
|
||||||
|
margin-bottom 15px
|
||||||
|
line-height 140%
|
||||||
|
input
|
||||||
|
margin-bottom 15px
|
||||||
|
textarea
|
||||||
|
margin-bottom 15px
|
||||||
|
max-height 250px
|
||||||
|
.contactFormRow
|
||||||
|
clearfix()
|
||||||
|
.saveButton
|
||||||
|
float right
|
||||||
|
.info
|
||||||
|
text-align left
|
||||||
|
.infoLabel
|
||||||
|
margin 75px 0 25px
|
||||||
|
.externalList
|
||||||
|
padding-left 10px
|
||||||
|
li
|
||||||
|
margin 15px
|
||||||
|
.logout
|
||||||
|
.logoutLabel
|
||||||
|
margin 100px 0 25px
|
||||||
|
font-size 1.4em
|
||||||
|
.userPhoto
|
||||||
|
margin-bottom 25px
|
||||||
|
circle()
|
||||||
|
|
||||||
|
.PlanetSettingModal.modal
|
||||||
|
.settingBody
|
||||||
.planetProfile
|
.planetProfile
|
||||||
height 500px
|
height 500px
|
||||||
padding-top 50px
|
padding-top 50px
|
||||||
@@ -174,7 +233,7 @@
|
|||||||
margin-right 0
|
margin-right 0
|
||||||
.deleteButton
|
.deleteButton
|
||||||
float left
|
float left
|
||||||
.manageMember
|
.members
|
||||||
height 500px
|
height 500px
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
padding-top 50px
|
padding-top 50px
|
||||||
|
|||||||
Reference in New Issue
Block a user