diff --git a/browser/main/Containers/LoginContainer.jsx b/browser/main/Containers/LoginContainer.jsx
index 9b169650..6eac413b 100644
--- a/browser/main/Containers/LoginContainer.jsx
+++ b/browser/main/Containers/LoginContainer.jsx
@@ -2,7 +2,6 @@ var React = require('react/addons')
var ReactRouter = require('react-router')
var Link = ReactRouter.Link
-var AuthStore = require('../Stores/AuthStore')
var AuthActions = require('../Actions/AuthActions')
var OnlyGuest = require('../Mixins/OnlyGuest')
@@ -15,12 +14,6 @@ module.exports = React.createClass({
password: ''
}
},
- componentDidMount: function () {
- this.unsubscribe = AuthStore.listen(this.onLogin)
- },
- componentWillUnmount: function () {
- this.unsubscribe()
- },
handleSubmit: function (e) {
AuthActions.login({
email: this.state.email,
@@ -28,14 +21,6 @@ module.exports = React.createClass({
})
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 () {
return (
diff --git a/browser/main/Containers/MainContainer.jsx b/browser/main/Containers/MainContainer.jsx
index 3bdf2202..95fd0bea 100644
--- a/browser/main/Containers/MainContainer.jsx
+++ b/browser/main/Containers/MainContainer.jsx
@@ -2,8 +2,33 @@ var React = require('react/addons')
var ReactRouter = require('react-router')
var RouteHandler = ReactRouter.RouteHandler
+var AuthStore = require('../Stores/AuthStore')
+
module.exports = React.createClass({
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 () {
// Redirect Login state
if (this.getPath() === '/') {
diff --git a/browser/main/Containers/PlanetContainer.jsx b/browser/main/Containers/PlanetContainer.jsx
index 5b1f647a..fb957122 100644
--- a/browser/main/Containers/PlanetContainer.jsx
+++ b/browser/main/Containers/PlanetContainer.jsx
@@ -56,18 +56,21 @@ module.exports = React.createClass({
},
getInitialState: function () {
return {
+ currentUser: AuthStore.getUser(),
currentPlanet: null,
search: '',
isFetched: false
}
},
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)
},
componentWillUnmount: function () {
- this.unsubscribe()
+ this.unsubscribePlanet()
+ this.unsubscribeAuth()
},
componentDidUpdate: function () {
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()
}
},
+ 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) {
if (res == null) {
return
@@ -396,8 +412,7 @@ module.exports = React.createClass({
},
render: function () {
- var user = AuthStore.getUser()
- if (user == null) return (
)
+ if (this.state.currentUser == null) return (
)
if (this.state.currentPlanet == null) return (
)
var localId = parseInt(this.props.params.localId, 10)
diff --git a/browser/main/Containers/RegisterContainer.jsx b/browser/main/Containers/RegisterContainer.jsx
index 298d4caf..cae170b7 100644
--- a/browser/main/Containers/RegisterContainer.jsx
+++ b/browser/main/Containers/RegisterContainer.jsx
@@ -2,7 +2,6 @@ var React = require('react/addons')
var ReactRouter = require('react-router')
var Link = ReactRouter.Link
-var AuthStore = require('../Stores/AuthStore')
var AuthActions = require('../Actions/AuthActions')
var OnlyGuest = require('../Mixins/OnlyGuest')
@@ -17,12 +16,6 @@ module.exports = React.createClass({
profileName: ''
}
},
- componentDidMount: function () {
- this.unsubscribe = AuthStore.listen(this.onRegister)
- },
- componentWillUnmount: function () {
- this.unsubscribe()
- },
handleSubmit: function (e) {
AuthActions.register({
email: this.state.email,
@@ -33,14 +26,6 @@ module.exports = React.createClass({
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 () {
return (
diff --git a/browser/main/Containers/UserContainer.jsx b/browser/main/Containers/UserContainer.jsx
index aac9a1c3..31cf167f 100644
--- a/browser/main/Containers/UserContainer.jsx
+++ b/browser/main/Containers/UserContainer.jsx
@@ -2,6 +2,8 @@
var React = require('react/addons')
var ReactRouter = require('react-router')
var RouteHandler = ReactRouter.RouteHandler
+var Link = ReactRouter.Link
+var request = require('superagent')
var UserNavigator = require('../Components/UserNavigator')
@@ -9,22 +11,49 @@ var AuthStore = require('../Stores/AuthStore')
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
- mixins: [React.addons.LinkedStateMixin, ReactRouter.Navigation],
+ mixins: [React.addons.LinkedStateMixin, ReactRouter.Navigation, ReactRouter.State],
propTypes: {
params: React.PropTypes.shape({
+ userName: React.PropTypes.string,
planetName: React.PropTypes.string
})
},
getInitialState: function () {
return {
- currentUser: AuthStore.getUser()
+ currentUser: AuthStore.getUser(),
+ isUserFetched: false,
+ user: null
}
},
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 () {
- 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) {
if (res.status == null) return
@@ -40,10 +69,15 @@ module.exports = React.createClass({
if (res.status === 'nameChanged') {
this.setState({currentUser: AuthStore.getUser()})
}
+
+ if (res.status === 'userProfileUpdated') {
+ this.setState({currentUser: AuthStore.getUser()})
+ }
},
render: function () {
var currentPlanetName = this.props.params.planetName
var currentUser = this.state.currentUser
+ var user = this.state.user
// user must be logged in
if (currentUser == null) return (
)
@@ -57,10 +91,49 @@ module.exports = React.createClass({
return false
})
+ var content
+ if (this.isActive('userHome')) {
+ if (this.state.isUserFetched === false) {
+ content = (
+
+ User Loading...
+
+ )
+ } else {
+ var planets = user.Planets.map(function (planet) {
+ return (
+
+ {planet.userName}/{planet.name}
+
+ )
+ })
+ content = (
+
+
User Profile
+
+

+
+
{user.profileName}
+
{user.name}
+
+
+
Planets
+
+
+ )
+ }
+ } else {
+ content = (
+
+ )
+ }
+
return (
-
+ {content}
)
}
diff --git a/browser/main/Stores/AuthStore.js b/browser/main/Stores/AuthStore.js
index 3c240ad8..b14d856d 100644
--- a/browser/main/Stores/AuthStore.js
+++ b/browser/main/Stores/AuthStore.js
@@ -4,16 +4,19 @@ var request = require('superagent')
var AuthActions = require('../Actions/AuthActions')
+var apiUrl = 'http://localhost:8000/'
+
var AuthStore = Reflux.createStore({
init: function () {
this.listenTo(AuthActions.login, this.login)
this.listenTo(AuthActions.register, this.register)
this.listenTo(AuthActions.logout, this.logout)
+ this.listenTo(AuthActions.updateProfile, this.updateProfile)
},
// Reflux Store
login: function (input) {
request
- .post('http://localhost:8000/auth/login')
+ .post(apiUrl + 'auth/login')
.send(input)
.set('Accept', 'application/json')
.end(function (err, res) {
@@ -27,12 +30,15 @@ var AuthStore = Reflux.createStore({
localStorage.setItem('token', res.body.token)
localStorage.setItem('user', JSON.stringify(res.body.user))
- this.trigger(user)
+ this.trigger({
+ status: 'loggedIn',
+ data: user
+ })
}.bind(this))
},
register: function (input) {
request
- .post('http://localhost:8000/auth/signup')
+ .post(apiUrl + 'auth/signup')
.send(input)
.set('Accept', 'application/json')
.end(function (err, res) {
@@ -46,14 +52,42 @@ var AuthStore = Reflux.createStore({
localStorage.setItem('token', res.body.token)
localStorage.setItem('user', JSON.stringify(res.body.user))
- this.trigger(user)
+ this.trigger({
+ status: 'registered',
+ data: user
+ })
}.bind(this))
},
logout: function () {
localStorage.removeItem('token')
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
check: function () {
diff --git a/browser/main/index.jsx b/browser/main/index.jsx
index dca93960..328ed49a 100644
--- a/browser/main/index.jsx
+++ b/browser/main/index.jsx
@@ -13,7 +13,7 @@ var LoginContainer = require('./Containers/LoginContainer.jsx')
var RegisterContainer = require('./Containers/RegisterContainer.jsx')
var UserContainer = require('./Containers/UserContainer.jsx')
-var UserSettingContainer = require('./Containers/UserSettingContainer.jsx')
+
var PlanetContainer = require('./Containers/PlanetContainer.jsx')
var routes = (
@@ -22,7 +22,7 @@ var routes = (
-
+
diff --git a/browser/styles/main/containers/UserContainer.styl b/browser/styles/main/containers/UserContainer.styl
index d011eb42..d234a331 100644
--- a/browser/styles/main/containers/UserContainer.styl
+++ b/browser/styles/main/containers/UserContainer.styl
@@ -5,19 +5,23 @@
width 50px
text-align center
box-sizing border-box
- a.userConfig
+ .userButton
display block
width 50px
height 50px
background-color black
+ margin 0
+ padding 0
+ border none
+ cursor pointer
img
transition 0.1s
- opacity 0.6
+ opacity 0.8
box-sizing border-box
&.active, &:active, &.focus, &:focus, &.hover, &:hover
img
opacity 1
- ul>li
+ ul.planetList>li
padding 10px 3px
.shortCut
margin-top 5px
@@ -68,3 +72,29 @@
border-color darken(brandBorderColor, 10%)
background-color brandColor
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
diff --git a/browser/styles/mixins/btnStyle.styl b/browser/styles/mixins/btnStyle.styl
index 8c594e37..22dc57b4 100644
--- a/browser/styles/mixins/btnStyle.styl
+++ b/browser/styles/mixins/btnStyle.styl
@@ -1,16 +1,19 @@
btnDefault()
border-style solid
border-width 1px
- border-color brandBorderColor
+ border-color lightButtonColor
background-color transparent
- color brandColor
+ color lightButtonColor
+
&:hover, &.hover, &:focus, &.focus
- border-color darken(brandBorderColor, 30%)
- color darken(brandColor, 30%)
+ border-color darken(lightButtonColor, 50%)
+ color darken(lightButtonColor, 50%)
&:active, &.active
+ border-color darken(brandBorderColor, 10%)
background-color brandColor
color white
-
+
+
btnPrimary()
border-style solid
border-width 1px
diff --git a/browser/styles/shared/modal.styl b/browser/styles/shared/modal.styl
index ac71c8a6..947ac119 100644
--- a/browser/styles/shared/modal.styl
+++ b/browser/styles/shared/modal.styl
@@ -107,7 +107,7 @@
height 55px
circle()
btnPrimary()
- .PlanetSettingModal.modal
+ .PlanetSettingModal.modal, .PersonalSettingModal.modal
width 720px
height 500px
.settingNav
@@ -117,7 +117,7 @@
padding 10px
border-right solid 1px borderColor
h1
- margin 40px 15px
+ margin 40px auto
font-size 1.5em
color brandColor
nav
@@ -139,11 +139,70 @@
background-color hoverBackgroundColor
&:active, &.active
color brandColor
-
.settingBody
absolute top bottom right
left 200px
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
height 500px
padding-top 50px
@@ -174,7 +233,7 @@
margin-right 0
.deleteButton
float left
- .manageMember
+ .members
height 500px
box-sizing border-box
padding-top 50px