1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-25 15:41:42 +00:00

on Refactor... #3

This commit is contained in:
Rokt33r
2015-08-19 00:54:38 +09:00
parent d8cb93fb10
commit 484dfe6726
13 changed files with 369 additions and 522 deletions

View 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>
)
}
})

View File

@@ -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'>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>
)
}
})

View File

@@ -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>
)
}
})