mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
on Refactor... #3
This commit is contained in:
32
browser/main/Components/AboutModal.jsx
Normal file
32
browser/main/Components/AboutModal.jsx
Normal file
@@ -0,0 +1,32 @@
|
||||
var remote = require('remote')
|
||||
var version = remote.getGlobal('version')
|
||||
|
||||
var React = require('react/addons')
|
||||
|
||||
var ExternalLink = require('../Mixins/ExternalLink')
|
||||
|
||||
module.exports = React.createClass({
|
||||
mixins: [ExternalLink],
|
||||
propTypes: {
|
||||
close: React.PropTypes.func
|
||||
},
|
||||
render: function () {
|
||||
return (
|
||||
<div className='AboutModal modal'>
|
||||
<div className='about1'>
|
||||
<img className='logo' src='resources/favicon-230x230.png'/>
|
||||
<div className='appInfo'>Boost {version == null ? 'DEV version' : 'v' + version}</div>
|
||||
</div>
|
||||
|
||||
<div className='about2'>
|
||||
<div className='externalLabel'>External links</div>
|
||||
<ul className='externalList'>
|
||||
<li><a onClick={this.openExternal} href='http://b00st.io'>Boost 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>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
@@ -95,7 +95,7 @@ module.exports = React.createClass({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='EditProfileModal modal'>
|
||||
<div className='EditProfileModal modal tabModal'>
|
||||
<div className='leftPane'>
|
||||
<div className='tabLabel'>Edit profile</div>
|
||||
<div className='tabList'>
|
||||
|
||||
@@ -11,7 +11,7 @@ var Modal = require('../Mixins/Modal')
|
||||
|
||||
var UserStore = require('../Stores/UserStore')
|
||||
|
||||
var PreferencesModal = require('./PreferencesModal')
|
||||
var AboutModal = require('./AboutModal')
|
||||
var PlanetCreateModal = require('./PlanetCreateModal')
|
||||
var TeamCreateModal = require('./TeamCreateModal')
|
||||
var ProfileImage = require('./ProfileImage')
|
||||
@@ -36,8 +36,8 @@ module.exports = React.createClass({
|
||||
openTeamCreateModal: function () {
|
||||
this.openModal(TeamCreateModal, {user: this.state.currentUser, transitionTo: this.transitionTo})
|
||||
},
|
||||
openPreferencesModal: function () {
|
||||
this.openModal(PreferencesModal, {currentUser: this.state.currentUser})
|
||||
openAboutModal: function () {
|
||||
this.openModal(AboutModal)
|
||||
},
|
||||
openPlanetCreateModal: function () {
|
||||
this.openModal(PlanetCreateModal, {transitionTo: this.transitionTo})
|
||||
@@ -80,7 +80,7 @@ module.exports = React.createClass({
|
||||
}
|
||||
|
||||
var planets = (this.state.currentUser.Planets.concat(this.state.currentUser.Teams.reduce(function (planets, team) {
|
||||
return planets.concat(team.Planets)
|
||||
return team.Planets == null ? planets : planets.concat(team.Planets)
|
||||
}, []))).map(function (planet, index) {
|
||||
return (
|
||||
<li key={planet.id} className={params.userName === planet.userName && params.planetName === planet.name ? 'active' : ''}>
|
||||
@@ -146,7 +146,7 @@ module.exports = React.createClass({
|
||||
|
||||
<ul className='controlGroup'>
|
||||
<li>
|
||||
<button onClick={this.openPreferencesModal}><i className='fa fa-gear fa-fw'/> Preferences</button>
|
||||
<button onClick={this.openAboutModal}><i className='fa fa-info-circle fa-fw'/> About this app</button>
|
||||
</li>
|
||||
<li>
|
||||
<button onClick={this.handleLogoutClick}><i className='fa fa-sign-out fa-fw'/> Logout</button>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
var shell = require('shell')
|
||||
|
||||
var React = require('react/addons')
|
||||
var ReactRouter = require('react-router')
|
||||
|
||||
var Modal = require('../Mixins/Modal')
|
||||
var ExternalLink = require('../Mixins/ExternalLink')
|
||||
|
||||
var PlanetSettingModal = require('./PlanetSettingModal')
|
||||
|
||||
module.exports = React.createClass({
|
||||
mixins: [ReactRouter.State],
|
||||
mixins: [ReactRouter.State, Modal, ExternalLink],
|
||||
propTypes: {
|
||||
search: React.PropTypes.string,
|
||||
fetchPlanet: React.PropTypes.func,
|
||||
@@ -19,9 +22,8 @@ module.exports = React.createClass({
|
||||
componentDidMount: function () {
|
||||
React.findDOMNode(this.refs.search).focus()
|
||||
},
|
||||
handleLogoClick: function (e) {
|
||||
shell.openExternal('http://b00st.io')
|
||||
e.preventDefault()
|
||||
openPlanetSettingModal: function () {
|
||||
this.openModal(PlanetSettingModal, {planet: this.props.currentPlanet})
|
||||
},
|
||||
refresh: function () {
|
||||
this.props.fetchPlanet()
|
||||
@@ -35,7 +37,7 @@ module.exports = React.createClass({
|
||||
<div className='headerLabel'>
|
||||
<span className='userName'>{currentUserName}</span><br/>
|
||||
<span className='planetName'>{currentPlanetName}</span>
|
||||
<button className='menuBtn'>
|
||||
<button onClick={this.openPlanetSettingModal} className='menuBtn'>
|
||||
<i className='fa fa-chevron-down'></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -45,7 +47,7 @@ module.exports = React.createClass({
|
||||
<input onChange={this.props.onSearchChange} value={this.props.search} ref='search' type='text' className='inline-input circleInput' placeholder='Search...'/>
|
||||
</div>
|
||||
<button onClick={this.refresh} className='refreshButton'><i className='fa fa-refresh'/></button>
|
||||
<a onClick={this.handleLogoClick} href='http://b00st.io' className='logo'>
|
||||
<a onClick={this.openExternal} href='http://b00st.io' className='logo'>
|
||||
<img width='44' height='44' src='resources/favicon-230x230.png'/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1,83 +1,154 @@
|
||||
var React = require('react/addons')
|
||||
|
||||
var Catalyst = require('../Mixins/Catalyst')
|
||||
var Hq = require('../Services/Hq')
|
||||
|
||||
var ProfileImage = require('./ProfileImage')
|
||||
var LinkedState = require('../Mixins/LinkedState')
|
||||
|
||||
var PlanetStore = require('../Stores/PlanetStore')
|
||||
|
||||
module.exports = React.createClass({
|
||||
mixins: [Catalyst.LinkedStateMixin],
|
||||
mixins: [LinkedState],
|
||||
propTypes: {
|
||||
close: React.PropTypes.func,
|
||||
currentPlanet: React.PropTypes.object
|
||||
planet: React.PropTypes.shape({
|
||||
name: React.PropTypes.string,
|
||||
public: React.PropTypes.bool,
|
||||
userName: React.PropTypes.string
|
||||
})
|
||||
},
|
||||
getInitialState: function () {
|
||||
var deleteTextCandidates = [
|
||||
'Confirm',
|
||||
'Exterminatus',
|
||||
'Avada Kedavra'
|
||||
]
|
||||
var random = Math.round(Math.random() * 10) % 10
|
||||
var randomDeleteText = random > 1 ? deleteTextCandidates[0] : random === 1 ? deleteTextCandidates[1] : deleteTextCandidates[2]
|
||||
|
||||
return {
|
||||
currentTab: 'planetProfile',
|
||||
planetName: this.props.currentPlanet.name,
|
||||
isDeletePlanetChecked: false,
|
||||
userName: ''
|
||||
currentTab: 'profile',
|
||||
planet: {
|
||||
name: this.props.planet.name,
|
||||
public: this.props.planet.public
|
||||
},
|
||||
randomDeleteText: randomDeleteText,
|
||||
deleteConfirmation: ''
|
||||
}
|
||||
},
|
||||
activePlanetProfile: function () {
|
||||
this.setState({currentTab: 'planetProfile'})
|
||||
this.setState({currentTab: 'profile'})
|
||||
},
|
||||
saveProfile: function () {
|
||||
var currentPlanet = this.props.currentPlanet
|
||||
PlanetActions.changeName(currentPlanet.userName, currentPlanet.name, this.state.planetName)
|
||||
activePlanetDelete: function () {
|
||||
this.setState({currentTab: 'delete'})
|
||||
},
|
||||
handleChange: function (value) {
|
||||
this.setState({userName: value})
|
||||
handlePublicChange: function (value) {
|
||||
return function () {
|
||||
this.state.planet.public = value
|
||||
this.setState({planet: this.state.planet})
|
||||
}.bind(this)
|
||||
},
|
||||
doubleCheckDeletePlanet: function () {
|
||||
if (this.state.isDeletePlanetChecked) {
|
||||
PlanetActions.deletePlanet(this.props.currentPlanet.userName, this.props.currentPlanet.name)
|
||||
return
|
||||
}
|
||||
this.setState({isDeletePlanetChecked: true})
|
||||
React.findDOMNode(this.refs.deleteCancelButton).focus()
|
||||
handleSavePlanetProfile: function (e) {
|
||||
var planet = this.props.planet
|
||||
|
||||
this.setState({profileSubmitStatus: 'sending'}, function () {
|
||||
Hq.updatePlanet(planet.userName, planet.name, this.state.planet)
|
||||
.then(function (res) {
|
||||
var planet = res.body
|
||||
|
||||
this.setState({profileSubmitStatus: 'done'})
|
||||
|
||||
PlanetStore.Actions.update(planet)
|
||||
}.bind(this))
|
||||
.catch(function (err) {
|
||||
this.setState({profileSubmitStatus: 'error'})
|
||||
console.error(err)
|
||||
}.bind(this))
|
||||
})
|
||||
},
|
||||
cancelDeletePlanet: function () {
|
||||
this.setState({isDeletePlanetChecked: false})
|
||||
},
|
||||
interceptClick: function (e) {
|
||||
e.stopPropagation()
|
||||
handleDeletePlanetClick: function () {
|
||||
var planet = this.props.planet
|
||||
|
||||
this.setState({deleteSubmitStatus: 'sending'}, function () {
|
||||
Hq.destroyPlanet(planet.userName, planet.name)
|
||||
.then(function (res) {
|
||||
var planet = res.body
|
||||
|
||||
PlanetStore.Actions.destroy(planet)
|
||||
this.setState({deleteSubmitStatus: 'done'}, function () {
|
||||
this.props.close()
|
||||
})
|
||||
}.bind(this))
|
||||
.catch(function (err) {
|
||||
this.setState({deleteSubmitStatus: 'error'})
|
||||
console.error(err)
|
||||
}.bind(this))
|
||||
})
|
||||
|
||||
},
|
||||
render: function () {
|
||||
var content
|
||||
|
||||
content = (
|
||||
<div className='planetProfile'>
|
||||
<div className='planetProfileForm'>
|
||||
<label>Planet name </label>
|
||||
<input valueLink={this.linkState('planetName')} className='inline-input'/>
|
||||
<button onClick={this.saveProfile} className='saveButton btn-primary'>Save</button>
|
||||
</div>
|
||||
|
||||
<div className='planetDeleteForm'>
|
||||
<div className='planetDeleteControl'>
|
||||
<div className={'toggle' + (this.state.isDeletePlanetChecked ? '' : ' hide')}>
|
||||
<div className='planetDeleteLabel'>Are you sure to delete this planet?</div>
|
||||
<button ref='deleteCancelButton' onClick={this.cancelDeletePlanet} className='cancelButton btn-default'>Cancel</button>
|
||||
</div>
|
||||
<button onClick={this.doubleCheckDeletePlanet} className='deleteButton btn-primary'>{!this.state.isDeletePlanetChecked ? 'Delete Planet' : 'Confirm'}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
content = this.state.currentTab === 'profile' ? this.renderPlanetProfileTab() : this.renderPlanetDeleteTab()
|
||||
|
||||
return (
|
||||
<div onClick={this.interceptClick} className='PlanetSettingModal modal'>
|
||||
<div className='settingNav'>
|
||||
<h1>Planet setting</h1>
|
||||
<nav>
|
||||
<button className={this.state.currentTab === 'planetProfile' ? 'active' : ''} onClick={this.activePlanetProfile}><i className='fa fa-globe fa-fw'/> Planet profile</button>
|
||||
<div className='PlanetSettingModal modal tabModal'>
|
||||
<div className='leftPane'>
|
||||
<h1 className='tabLabel'>Planet setting</h1>
|
||||
<nav className='tabList'>
|
||||
<button onClick={this.activePlanetProfile} className={this.state.currentTab === 'profile' ? 'active' : ''}><i className='fa fa-globe fa-fw'/> Planet profile</button>
|
||||
<button onClick={this.activePlanetDelete} className={this.state.currentTab === 'delete' ? 'active' : ''}><i className='fa fa-trash fa-fw'/> Delete Planet</button>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div className='settingBody'>
|
||||
<div className='rightPane'>
|
||||
{content}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
renderPlanetProfileTab: function () {
|
||||
return (
|
||||
<div className='planetProfileTab'>
|
||||
<div className='formField'>
|
||||
<label>Planet name </label>
|
||||
<input valueLink={this.linkState('planet.name')}/>
|
||||
</div>
|
||||
|
||||
<div className='formRadioField'>
|
||||
<input id='publicOption' checked={this.state.planet.public} onChange={this.handlePublicChange(true)} name='public' type='radio'/> <label htmlFor='publicOption'>Public</label>
|
||||
|
||||
<input id='privateOption' checked={!this.state.planet.public} onChange={this.handlePublicChange(false)} name='public' type='radio'/> <label htmlFor='privateOption'>Private</label>
|
||||
</div>
|
||||
<div className='formConfirm'>
|
||||
<button onClick={this.handleSavePlanetProfile} className='saveButton btn-primary'>Save</button>
|
||||
|
||||
<div className={'alertInfo' + (this.state.profileSubmitStatus === 'sending' ? '' : ' hide')}>on Sending...</div>
|
||||
|
||||
<div className={'alertError' + (this.state.profileSubmitStatus === 'error' ? '' : ' hide')}>Connection failed.. Try again.</div>
|
||||
|
||||
<div className={'alertSuccess' + (this.state.profileSubmitStatus === 'done' ? '' : ' hide')}>Successfully done!!</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
renderPlanetDeleteTab: function () {
|
||||
var disabled = !this.state.deleteConfirmation.match(new RegExp('^' + this.props.planet.userName + '/' + this.props.planet.name + '$'))
|
||||
|
||||
return (
|
||||
<div className='planetDeleteTab'>
|
||||
<p>Are you sure to destroy <strong>'{this.props.planet.userName + '/' + this.props.planet.name}'</strong>?</p>
|
||||
<p>If you are sure, write <strong>'{this.props.planet.userName + '/' + this.props.planet.name}'</strong> to input below and click <strong>'{this.state.randomDeleteText}'</strong> button.</p>
|
||||
<input valueLink={this.linkState('deleteConfirmation')} placeholder='userName/planetName'/>
|
||||
<div className='formConfirm'>
|
||||
<button disabled={disabled} onClick={this.handleDeletePlanetClick}>{this.state.randomDeleteText}</button>
|
||||
|
||||
<div className={'alertInfo' + (this.state.deleteSubmitStatus === 'sending' ? '' : ' hide')}>on Sending...</div>
|
||||
|
||||
<div className={'alertError' + (this.state.deleteSubmitStatus === 'error' ? '' : ' hide')}>Connection failed.. Try again.</div>
|
||||
|
||||
<div className={'alertSuccess' + (this.state.deleteSubmitStatus === 'done' ? '' : ' hide')}>Successfully done!!</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
/* global localStorage */
|
||||
var React = require('react/addons')
|
||||
var ReactRouter = require('react-router')
|
||||
var Navigation = ReactRouter.Navigation
|
||||
var request = require('superagent')
|
||||
|
||||
var LinkedState = require('../Mixins/LinkedState')
|
||||
|
||||
var ProfileImage = require('./ProfileImage')
|
||||
|
||||
var apiUrl = require('../../../config').apiUrl
|
||||
|
||||
module.exports = React.createClass({
|
||||
mixins: [LinkedState, Navigation],
|
||||
propTypes: {
|
||||
close: React.PropTypes.func,
|
||||
currentUser: React.PropTypes.object
|
||||
},
|
||||
getInitialState: function () {
|
||||
return {
|
||||
currentTab: 'profile',
|
||||
profileName: this.props.currentUser.profileName,
|
||||
userName: this.props.currentUser.name,
|
||||
email: this.props.currentUser.email,
|
||||
currentPassword: '',
|
||||
newPassword: '',
|
||||
confirmation: '',
|
||||
contactTitle: '',
|
||||
contactContent: ''
|
||||
}
|
||||
},
|
||||
componentDidMount: function () {
|
||||
},
|
||||
componentWillUnmount: function () {
|
||||
},
|
||||
onListen: function (res) {
|
||||
},
|
||||
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 () {
|
||||
},
|
||||
savePassword: function () {
|
||||
this.setState({
|
||||
isChangingPassword: true,
|
||||
isChangingPasswordDone: false,
|
||||
isChangingPasswordFailed: false
|
||||
})
|
||||
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) {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
this.setState({
|
||||
currentPassword: '',
|
||||
newPassword: '',
|
||||
confirmation: '',
|
||||
isChangingPassword: false,
|
||||
isChangingPasswordDone: false,
|
||||
isChangingPasswordFailed: true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
this.setState({
|
||||
currentPassword: '',
|
||||
newPassword: '',
|
||||
confirmation: '',
|
||||
isChangingPassword: false,
|
||||
isChangingPasswordDone: true,
|
||||
isChangingPasswordFailed: false
|
||||
})
|
||||
|
||||
}.bind(this))
|
||||
}
|
||||
},
|
||||
sendEmail: function () {
|
||||
this.setState({
|
||||
isSending: true,
|
||||
isSendingDone: false,
|
||||
isSendingFailed: false
|
||||
}, function () {
|
||||
request
|
||||
.post(apiUrl + 'mail')
|
||||
.set({
|
||||
Authorization: 'Bearer ' + localStorage.getItem('token')
|
||||
})
|
||||
.send({
|
||||
title: this.state.contactTitle,
|
||||
content: this.state.contactContent
|
||||
})
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
this.setState({
|
||||
isSending: false,
|
||||
isSendingDone: false,
|
||||
isSendingFailed: true
|
||||
})
|
||||
return
|
||||
}
|
||||
this.setState({
|
||||
isSending: false,
|
||||
isSendingDone: true,
|
||||
isSendingFailed: false,
|
||||
contactTitle: '',
|
||||
contactContent: ''
|
||||
})
|
||||
}.bind(this))
|
||||
})
|
||||
},
|
||||
logOut: function () {
|
||||
localStorage.removeItem('currentUser')
|
||||
localStorage.removeItem('token')
|
||||
},
|
||||
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>Profile Name</label>
|
||||
<input valueLink={this.linkState('profileName')} className='block-input' type='text' placeholder='Name'/>
|
||||
</div>
|
||||
<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>
|
||||
<p className={'alertInfo' + (this.state.isUpdatingProfile ? '' : ' hide')}>Updating profile...</p>
|
||||
<p className={'alertSuccess' + (this.state.isUpdatingProfileDone ? '' : ' hide')}>Successfully updated</p>
|
||||
<p className={'alertError' + (this.state.isUpdatingProfileFailed ? '' : ' hide')}>An Error occurred</p>
|
||||
</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>
|
||||
<p className={'alertInfo' + (this.state.isChangingPassword ? '' : ' hide')}>Changing password...</p>
|
||||
<p className={'alertSuccess' + (this.state.isChangingPasswordDone ? '' : ' hide')}>Successfully changed</p>
|
||||
<p className={'alertError' + (this.state.isChangingPasswordFailed ? '' : ' hide')}>An Error occurred</p>
|
||||
</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 disabled={this.state.isSending} onClick={this.sendEmail} className='saveButton btn-primary'>Send</button>
|
||||
<p className={'alertInfo' + (this.state.isSending ? '' : ' hide')}>Sending...</p>
|
||||
<p className={'alertSuccess' + (this.state.isSendingDone ? '' : ' hide')}>Successfully sent</p>
|
||||
<p className={'alertError' + (this.state.isSendingFailed ? '' : ' hide')}>An Error occurred</p>
|
||||
</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>
|
||||
|
||||
<ProfileImage className='userPhoto' size='150' email={this.props.currentUser.email}/><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>
|
||||
)
|
||||
}
|
||||
})
|
||||
@@ -89,10 +89,25 @@ module.exports = React.createClass({
|
||||
},
|
||||
onPlanetChange: function (res) {
|
||||
if (this.state.planet == null) return
|
||||
console.log(res.data)
|
||||
|
||||
var code, note, articleIndex, articlesCount
|
||||
var planet, code, note, articleIndex, articlesCount
|
||||
switch (res.status) {
|
||||
case 'updated':
|
||||
planet = res.data
|
||||
if (this.state.planet.id === planet.id) {
|
||||
if (this.state.planet.name === planet.name) {
|
||||
this.setState({planet: planet})
|
||||
} else {
|
||||
this.transitionTo('planetHome', {userName: planet.userName, planetName: planet.name})
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'destroyed':
|
||||
planet = res.data
|
||||
if (this.state.planet.id === planet.id) {
|
||||
this.transitionTo('userHome', {userName: this.state.planet.userName})
|
||||
}
|
||||
break
|
||||
case 'codeUpdated':
|
||||
code = res.data
|
||||
if (code.PlanetId === this.state.planet.id) {
|
||||
|
||||
@@ -30,14 +30,15 @@ module.exports = React.createClass({
|
||||
}, function () {
|
||||
Hq.signup(this.state.user)
|
||||
.then(function (res) {
|
||||
console.log(res.body)
|
||||
localStorage.setItem('token', res.body.token)
|
||||
localStorage.setItem('currentUser', JSON.stringify(res.body.user))
|
||||
|
||||
this.transitionTo('userHome', {userName: res.body.user.name})
|
||||
}.bind(this))
|
||||
.catch(function (err) {
|
||||
console.error(err)
|
||||
var res = err.response
|
||||
console.error(res.body)
|
||||
if (err.status === 409) {
|
||||
// Confliction
|
||||
var emailConflicted = res.body.errors[0].path === 'email'
|
||||
@@ -90,12 +91,6 @@ module.exports = React.createClass({
|
||||
|
||||
<nav className='authNavigator text-center'><Link to='login'>Log In</Link> / <Link to='signup'>Sign Up</Link></nav>
|
||||
|
||||
<div className='socialControl'>
|
||||
<p>Connect with</p>
|
||||
<button className='facebookBtn'><i className='fa fa-facebook fa-fw'/></button>
|
||||
<button className='githubBtn'><i className='fa fa-github fa-fw'/></button>
|
||||
</div>
|
||||
|
||||
<div className='divider'>
|
||||
<hr/>
|
||||
<div className='dividerLabel'>or</div>
|
||||
|
||||
8
browser/main/Mixins/ExternalLink.js
Normal file
8
browser/main/Mixins/ExternalLink.js
Normal file
@@ -0,0 +1,8 @@
|
||||
var shell = require('shell')
|
||||
|
||||
module.exports = {
|
||||
openExternal: function (e) {
|
||||
shell.openExternal(e.currentTarget.href)
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,21 @@ module.exports = {
|
||||
return request
|
||||
.get(apiUrl + 'resources/' + userName + '/planets/' + planetName)
|
||||
},
|
||||
updatePlanet: function (userName, planetName, input) {
|
||||
return request
|
||||
.put(apiUrl + 'resources/' + userName + '/planets/' + planetName)
|
||||
.set({
|
||||
Authorization: 'Bearer ' + localStorage.getItem('token')
|
||||
})
|
||||
.send(input)
|
||||
},
|
||||
destroyPlanet: function (userName, planetName) {
|
||||
return request
|
||||
.del(apiUrl + 'resources/' + userName + '/planets/' + planetName)
|
||||
.set({
|
||||
Authorization: 'Bearer ' + localStorage.getItem('token')
|
||||
})
|
||||
},
|
||||
createCode: function (userName, planetName, input) {
|
||||
return request
|
||||
.post(apiUrl + 'resources/' + userName + '/planets/' + planetName + '/codes')
|
||||
|
||||
@@ -84,6 +84,43 @@ module.exports = Reflux.createStore({
|
||||
data: planet
|
||||
})
|
||||
},
|
||||
onDestroy: function (planet) {
|
||||
// Check if the planet should be updated to currentUser
|
||||
var currentUser = JSON.parse(localStorage.getItem('currentUser'))
|
||||
|
||||
var ownedByCurrentUser = currentUser.id === planet.OwnerId
|
||||
|
||||
if (ownedByCurrentUser) {
|
||||
currentUser.Planets = deleteItemFromTargetArray(planet, currentUser.Planets)
|
||||
}
|
||||
|
||||
if (!ownedByCurrentUser) {
|
||||
var team = null
|
||||
currentUser.Teams.some(function (_team) {
|
||||
if (_team.id === planet.OwnerId) {
|
||||
team = _team
|
||||
return true
|
||||
}
|
||||
return
|
||||
})
|
||||
|
||||
if (team) {
|
||||
team.Planets = deleteItemFromTargetArray(planet, team.Planets)
|
||||
}
|
||||
}
|
||||
|
||||
// Update currentUser
|
||||
localStorage.setItem('currentUser', JSON.stringify(currentUser))
|
||||
UserStore.Actions.update(currentUser)
|
||||
|
||||
// Update the planet
|
||||
localStorage.setItem('planet-' + planet.id, JSON.stringify(planet))
|
||||
|
||||
this.trigger({
|
||||
status: 'destroyed',
|
||||
data: planet
|
||||
})
|
||||
},
|
||||
onUpdateCode: function (code) {
|
||||
code.type = 'code'
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
.modal-control
|
||||
float right
|
||||
|
||||
.EditProfileModal
|
||||
.tabModal
|
||||
height 500px
|
||||
.leftPane
|
||||
absolute top bottom left
|
||||
@@ -56,54 +56,103 @@
|
||||
absolute top bottom right
|
||||
left 175px
|
||||
padding 15px
|
||||
.userInfoTab, .paswordTab
|
||||
padding-top 45px
|
||||
.formField
|
||||
position relative
|
||||
clearfix()
|
||||
margin-bottom 15px
|
||||
label
|
||||
width 30%
|
||||
display block
|
||||
line-height 33px
|
||||
float left
|
||||
input
|
||||
width 70%
|
||||
display block
|
||||
borderInput()
|
||||
height 33px
|
||||
font-size 1em
|
||||
border-radius 10px
|
||||
float left
|
||||
.formConfirm
|
||||
position relative
|
||||
clearfix()
|
||||
margin-bottom 15px
|
||||
button
|
||||
float right
|
||||
btnDefault()
|
||||
padding 10px 15px
|
||||
border-radius 5px
|
||||
font-size 1em
|
||||
margin-left 5px
|
||||
.alertInfo, .alertSuccess, .alertError
|
||||
float right
|
||||
padding 12px 10px
|
||||
border-radius 5px
|
||||
width 200px
|
||||
font-size 1em
|
||||
overflow-x hidden
|
||||
white-space nowrap
|
||||
transition 0.1s
|
||||
&.hide
|
||||
width 0
|
||||
padding 12px 0
|
||||
.alertInfo
|
||||
alertInfo()
|
||||
.alertSuccess
|
||||
alertSuccess()
|
||||
.alertError
|
||||
alertError()
|
||||
|
||||
.EditProfileModal, .PlanetSettingModal
|
||||
.userInfoTab, .paswordTab, .planetProfileTab
|
||||
padding-top 45px
|
||||
.formField
|
||||
position relative
|
||||
clearfix()
|
||||
margin-bottom 15px
|
||||
label
|
||||
width 30%
|
||||
display block
|
||||
line-height 33px
|
||||
float left
|
||||
input
|
||||
width 70%
|
||||
display block
|
||||
borderInput()
|
||||
height 33px
|
||||
font-size 1em
|
||||
border-radius 10px
|
||||
float left
|
||||
.formRadioField
|
||||
margin-bottom 15px
|
||||
input
|
||||
margin-left 25px
|
||||
.formConfirm
|
||||
position relative
|
||||
clearfix()
|
||||
margin-bottom 15px
|
||||
button
|
||||
float right
|
||||
btnDefault()
|
||||
padding 10px 15px
|
||||
border-radius 5px
|
||||
font-size 1em
|
||||
margin-left 5px
|
||||
.alertInfo, .alertSuccess, .alertError
|
||||
float right
|
||||
padding 12px 10px
|
||||
border-radius 5px
|
||||
width 200px
|
||||
font-size 1em
|
||||
overflow-x hidden
|
||||
white-space nowrap
|
||||
transition 0.1s
|
||||
&.hide
|
||||
width 0
|
||||
padding 12px 0
|
||||
.alertInfo
|
||||
alertInfo()
|
||||
.alertSuccess
|
||||
alertSuccess()
|
||||
.alertError
|
||||
alertError()
|
||||
.planetDeleteTab
|
||||
padding-top 65px
|
||||
p
|
||||
margin-bottom 25px
|
||||
strong
|
||||
color brandColor
|
||||
font-size 1.1em
|
||||
input
|
||||
borderInput()
|
||||
margin-right 5px
|
||||
height 33px
|
||||
font-size 1em
|
||||
border-radius 10px
|
||||
.formConfirm
|
||||
position relative
|
||||
clearfix()
|
||||
margin-bottom 15px
|
||||
button
|
||||
float right
|
||||
btnDefault()
|
||||
padding 10px 15px
|
||||
border-radius 5px
|
||||
font-size 1em
|
||||
margin-left 5px
|
||||
.alertInfo, .alertSuccess, .alertError
|
||||
float right
|
||||
padding 12px 10px
|
||||
border-radius 5px
|
||||
width 200px
|
||||
font-size 1em
|
||||
overflow-x hidden
|
||||
white-space nowrap
|
||||
transition 0.1s
|
||||
&.hide
|
||||
width 0
|
||||
padding 12px 0
|
||||
.alertInfo
|
||||
alertInfo()
|
||||
.alertSuccess
|
||||
alertSuccess()
|
||||
.alertError
|
||||
alertError()
|
||||
|
||||
|
||||
.LaunchModal
|
||||
.modal-tab
|
||||
@@ -171,6 +220,27 @@
|
||||
border-radius 5px
|
||||
marked()
|
||||
|
||||
.AboutModal
|
||||
width 320px
|
||||
.about1
|
||||
margin-bottom 25px
|
||||
.logo
|
||||
display block
|
||||
margin 0 auto
|
||||
.appInfo
|
||||
font-size 1.5em
|
||||
text-align center
|
||||
.about2
|
||||
width 200px
|
||||
margin 0 auto
|
||||
.externalLabel
|
||||
font-size 1.2em
|
||||
margin-bottom 15px
|
||||
.externalList
|
||||
li
|
||||
margin-bottom 15px
|
||||
|
||||
|
||||
.PlanetCreateModal.modal, .TeamCreateModal.modal
|
||||
padding 60px 0
|
||||
.nameInput
|
||||
@@ -203,162 +273,3 @@
|
||||
height 55px
|
||||
circle()
|
||||
btnPrimary()
|
||||
.PlanetSettingModal.modal, .PersonalSettingModal.modal
|
||||
width 720px
|
||||
height 500px
|
||||
.settingNav
|
||||
absolute top bottom left
|
||||
width 200px
|
||||
box-sizing border-box
|
||||
padding 10px
|
||||
border-right solid 1px borderColor
|
||||
h1
|
||||
margin 40px auto
|
||||
font-size 1.5em
|
||||
color brandColor
|
||||
text-align center
|
||||
nav
|
||||
button
|
||||
font-size 1em
|
||||
display block
|
||||
box-sizing border-box
|
||||
padding 15px 15px
|
||||
margin 10px 0
|
||||
border none
|
||||
border-radius 10px
|
||||
width 100%
|
||||
text-align left
|
||||
background-color transparent
|
||||
color textColor
|
||||
cursor pointer
|
||||
transition 0.1s
|
||||
&:hover, &.hover
|
||||
background-color hoverBackgroundColor
|
||||
&:active, &.active
|
||||
color brandColor
|
||||
.settingBody
|
||||
absolute top bottom right
|
||||
left 200px
|
||||
padding 15px
|
||||
.PreferencesModal.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
|
||||
.alertSuccess, .alertError, .alertInfo
|
||||
float right
|
||||
transition 0.1s
|
||||
overflow hidden
|
||||
white-space nowrap
|
||||
width 200px
|
||||
text-align center
|
||||
&.hide
|
||||
width 0
|
||||
.alertSuccess
|
||||
alertSuccess()
|
||||
.alertError
|
||||
alertError()
|
||||
.alertInfo
|
||||
alertInfo()
|
||||
.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
|
||||
.alertSuccess, .alertError, .alertInfo
|
||||
float right
|
||||
transition 0.1s
|
||||
overflow hidden
|
||||
white-space nowrap
|
||||
width 200px
|
||||
text-align center
|
||||
&.hide
|
||||
width 0
|
||||
.alertSuccess
|
||||
alertSuccess()
|
||||
.alertError
|
||||
alertError()
|
||||
.alertInfo
|
||||
alertInfo()
|
||||
.info
|
||||
text-align left
|
||||
.infoLabel
|
||||
margin 75px 0 25px
|
||||
.externalList
|
||||
padding-left 10px
|
||||
li
|
||||
margin 15px
|
||||
.logout
|
||||
text-align center
|
||||
.logoutLabel
|
||||
margin 100px 0 25px
|
||||
font-size 1.4em
|
||||
.userPhoto
|
||||
margin-bottom 25px
|
||||
circle()
|
||||
box-shadow 1px 1px 4px 0px #C5C5C5
|
||||
|
||||
.PlanetSettingModal.modal
|
||||
.settingBody
|
||||
.planetProfile
|
||||
height 500px
|
||||
padding-top 50px
|
||||
.planetProfileForm
|
||||
height 275px
|
||||
box-sizing border-box
|
||||
border-bottom solid 1px borderColor
|
||||
.planetDeleteForm
|
||||
height 225px
|
||||
.planetDeleteControl
|
||||
margin-top 15px
|
||||
clearfix()
|
||||
.toggle
|
||||
float left
|
||||
transition width 0.3s, color 0.1s, border-color 0.1s
|
||||
overflow hidden
|
||||
white-space nowrap
|
||||
width 345px
|
||||
height 44px
|
||||
&.hide
|
||||
width 0
|
||||
.planetDeleteLabel
|
||||
display inline-block
|
||||
line-height 44px
|
||||
.cancelButton
|
||||
display inline-block
|
||||
margin-left 15px
|
||||
margin-right 0
|
||||
.deleteButton
|
||||
float left
|
||||
|
||||
Reference in New Issue
Block a user