Skip to content

Commit 484dfe6

Browse files
committed
on Refactor... BoostIO#3
1 parent d8cb93f commit 484dfe6

13 files changed

Lines changed: 366 additions & 519 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
var remote = require('remote')
2+
var version = remote.getGlobal('version')
3+
4+
var React = require('react/addons')
5+
6+
var ExternalLink = require('../Mixins/ExternalLink')
7+
8+
module.exports = React.createClass({
9+
mixins: [ExternalLink],
10+
propTypes: {
11+
close: React.PropTypes.func
12+
},
13+
render: function () {
14+
return (
15+
<div className='AboutModal modal'>
16+
<div className='about1'>
17+
<img className='logo' src='resources/favicon-230x230.png'/>
18+
<div className='appInfo'>Boost {version == null ? 'DEV version' : 'v' + version}</div>
19+
</div>
20+
21+
<div className='about2'>
22+
<div className='externalLabel'>External links</div>
23+
<ul className='externalList'>
24+
<li><a onClick={this.openExternal} href='http://b00st.io'>Boost Homepage <i className='fa fa-external-link'/></a></li>
25+
<li><a>Regulation <i className='fa fa-external-link'/></a></li>
26+
<li><a>Private policy <i className='fa fa-external-link'/></a></li>
27+
</ul>
28+
</div>
29+
</div>
30+
)
31+
}
32+
})

browser/main/Components/EditProfileModal.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ module.exports = React.createClass({
9595
}
9696

9797
return (
98-
<div className='EditProfileModal modal'>
98+
<div className='EditProfileModal modal tabModal'>
9999
<div className='leftPane'>
100100
<div className='tabLabel'>Edit profile</div>
101101
<div className='tabList'>

browser/main/Components/HomeNavigator.jsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var Modal = require('../Mixins/Modal')
1111

1212
var UserStore = require('../Stores/UserStore')
1313

14-
var PreferencesModal = require('./PreferencesModal')
14+
var AboutModal = require('./AboutModal')
1515
var PlanetCreateModal = require('./PlanetCreateModal')
1616
var TeamCreateModal = require('./TeamCreateModal')
1717
var ProfileImage = require('./ProfileImage')
@@ -36,8 +36,8 @@ module.exports = React.createClass({
3636
openTeamCreateModal: function () {
3737
this.openModal(TeamCreateModal, {user: this.state.currentUser, transitionTo: this.transitionTo})
3838
},
39-
openPreferencesModal: function () {
40-
this.openModal(PreferencesModal, {currentUser: this.state.currentUser})
39+
openAboutModal: function () {
40+
this.openModal(AboutModal)
4141
},
4242
openPlanetCreateModal: function () {
4343
this.openModal(PlanetCreateModal, {transitionTo: this.transitionTo})
@@ -80,7 +80,7 @@ module.exports = React.createClass({
8080
}
8181

8282
var planets = (this.state.currentUser.Planets.concat(this.state.currentUser.Teams.reduce(function (planets, team) {
83-
return planets.concat(team.Planets)
83+
return team.Planets == null ? planets : planets.concat(team.Planets)
8484
}, []))).map(function (planet, index) {
8585
return (
8686
<li key={planet.id} className={params.userName === planet.userName && params.planetName === planet.name ? 'active' : ''}>
@@ -146,7 +146,7 @@ module.exports = React.createClass({
146146

147147
<ul className='controlGroup'>
148148
<li>
149-
<button onClick={this.openPreferencesModal}><i className='fa fa-gear fa-fw'/> Preferences</button>
149+
<button onClick={this.openAboutModal}><i className='fa fa-info-circle fa-fw'/> About this app</button>
150150
</li>
151151
<li>
152152
<button onClick={this.handleLogoutClick}><i className='fa fa-sign-out fa-fw'/> Logout</button>

browser/main/Components/PlanetHeader.jsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
var shell = require('shell')
2-
31
var React = require('react/addons')
42
var ReactRouter = require('react-router')
53

4+
var Modal = require('../Mixins/Modal')
5+
var ExternalLink = require('../Mixins/ExternalLink')
6+
7+
var PlanetSettingModal = require('./PlanetSettingModal')
8+
69
module.exports = React.createClass({
7-
mixins: [ReactRouter.State],
10+
mixins: [ReactRouter.State, Modal, ExternalLink],
811
propTypes: {
912
search: React.PropTypes.string,
1013
fetchPlanet: React.PropTypes.func,
@@ -19,9 +22,8 @@ module.exports = React.createClass({
1922
componentDidMount: function () {
2023
React.findDOMNode(this.refs.search).focus()
2124
},
22-
handleLogoClick: function (e) {
23-
shell.openExternal('http://b00st.io')
24-
e.preventDefault()
25+
openPlanetSettingModal: function () {
26+
this.openModal(PlanetSettingModal, {planet: this.props.currentPlanet})
2527
},
2628
refresh: function () {
2729
this.props.fetchPlanet()
@@ -35,7 +37,7 @@ module.exports = React.createClass({
3537
<div className='headerLabel'>
3638
<span className='userName'>{currentUserName}</span><br/>
3739
<span className='planetName'>{currentPlanetName}</span>
38-
<button className='menuBtn'>
40+
<button onClick={this.openPlanetSettingModal} className='menuBtn'>
3941
<i className='fa fa-chevron-down'></i>
4042
</button>
4143
</div>
@@ -45,7 +47,7 @@ module.exports = React.createClass({
4547
<input onChange={this.props.onSearchChange} value={this.props.search} ref='search' type='text' className='inline-input circleInput' placeholder='Search...'/>
4648
</div>
4749
<button onClick={this.refresh} className='refreshButton'><i className='fa fa-refresh'/></button>
48-
<a onClick={this.handleLogoClick} href='http://b00st.io' className='logo'>
50+
<a onClick={this.openExternal} href='http://b00st.io' className='logo'>
4951
<img width='44' height='44' src='resources/favicon-230x230.png'/>
5052
</a>
5153
</div>

browser/main/Components/PlanetSettingModal.jsx

Lines changed: 119 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,152 @@
11
var React = require('react/addons')
22

3-
var Catalyst = require('../Mixins/Catalyst')
3+
var Hq = require('../Services/Hq')
44

5-
var ProfileImage = require('./ProfileImage')
5+
var LinkedState = require('../Mixins/LinkedState')
6+
7+
var PlanetStore = require('../Stores/PlanetStore')
68

79
module.exports = React.createClass({
8-
mixins: [Catalyst.LinkedStateMixin],
10+
mixins: [LinkedState],
911
propTypes: {
1012
close: React.PropTypes.func,
11-
currentPlanet: React.PropTypes.object
13+
planet: React.PropTypes.shape({
14+
name: React.PropTypes.string,
15+
public: React.PropTypes.bool,
16+
userName: React.PropTypes.string
17+
})
1218
},
1319
getInitialState: function () {
20+
var deleteTextCandidates = [
21+
'Confirm',
22+
'Exterminatus',
23+
'Avada Kedavra'
24+
]
25+
var random = Math.round(Math.random() * 10) % 10
26+
var randomDeleteText = random > 1 ? deleteTextCandidates[0] : random === 1 ? deleteTextCandidates[1] : deleteTextCandidates[2]
27+
1428
return {
15-
currentTab: 'planetProfile',
16-
planetName: this.props.currentPlanet.name,
17-
isDeletePlanetChecked: false,
18-
userName: ''
29+
currentTab: 'profile',
30+
planet: {
31+
name: this.props.planet.name,
32+
public: this.props.planet.public
33+
},
34+
randomDeleteText: randomDeleteText,
35+
deleteConfirmation: ''
1936
}
2037
},
2138
activePlanetProfile: function () {
22-
this.setState({currentTab: 'planetProfile'})
39+
this.setState({currentTab: 'profile'})
2340
},
24-
saveProfile: function () {
25-
var currentPlanet = this.props.currentPlanet
26-
PlanetActions.changeName(currentPlanet.userName, currentPlanet.name, this.state.planetName)
41+
activePlanetDelete: function () {
42+
this.setState({currentTab: 'delete'})
2743
},
28-
handleChange: function (value) {
29-
this.setState({userName: value})
30-
},
31-
doubleCheckDeletePlanet: function () {
32-
if (this.state.isDeletePlanetChecked) {
33-
PlanetActions.deletePlanet(this.props.currentPlanet.userName, this.props.currentPlanet.name)
34-
return
35-
}
36-
this.setState({isDeletePlanetChecked: true})
37-
React.findDOMNode(this.refs.deleteCancelButton).focus()
44+
handlePublicChange: function (value) {
45+
return function () {
46+
this.state.planet.public = value
47+
this.setState({planet: this.state.planet})
48+
}.bind(this)
3849
},
39-
cancelDeletePlanet: function () {
40-
this.setState({isDeletePlanetChecked: false})
50+
handleSavePlanetProfile: function (e) {
51+
var planet = this.props.planet
52+
53+
this.setState({profileSubmitStatus: 'sending'}, function () {
54+
Hq.updatePlanet(planet.userName, planet.name, this.state.planet)
55+
.then(function (res) {
56+
var planet = res.body
57+
58+
this.setState({profileSubmitStatus: 'done'})
59+
60+
PlanetStore.Actions.update(planet)
61+
}.bind(this))
62+
.catch(function (err) {
63+
this.setState({profileSubmitStatus: 'error'})
64+
console.error(err)
65+
}.bind(this))
66+
})
4167
},
42-
interceptClick: function (e) {
43-
e.stopPropagation()
68+
handleDeletePlanetClick: function () {
69+
var planet = this.props.planet
70+
71+
this.setState({deleteSubmitStatus: 'sending'}, function () {
72+
Hq.destroyPlanet(planet.userName, planet.name)
73+
.then(function (res) {
74+
var planet = res.body
75+
76+
PlanetStore.Actions.destroy(planet)
77+
this.setState({deleteSubmitStatus: 'done'}, function () {
78+
this.props.close()
79+
})
80+
}.bind(this))
81+
.catch(function (err) {
82+
this.setState({deleteSubmitStatus: 'error'})
83+
console.error(err)
84+
}.bind(this))
85+
})
86+
4487
},
4588
render: function () {
4689
var content
4790

48-
content = (
49-
<div className='planetProfile'>
50-
<div className='planetProfileForm'>
91+
content = this.state.currentTab === 'profile' ? this.renderPlanetProfileTab() : this.renderPlanetDeleteTab()
92+
93+
return (
94+
<div className='PlanetSettingModal modal tabModal'>
95+
<div className='leftPane'>
96+
<h1 className='tabLabel'>Planet setting</h1>
97+
<nav className='tabList'>
98+
<button onClick={this.activePlanetProfile} className={this.state.currentTab === 'profile' ? 'active' : ''}><i className='fa fa-globe fa-fw'/> Planet profile</button>
99+
<button onClick={this.activePlanetDelete} className={this.state.currentTab === 'delete' ? 'active' : ''}><i className='fa fa-trash fa-fw'/> Delete Planet</button>
100+
</nav>
101+
</div>
102+
103+
<div className='rightPane'>
104+
{content}
105+
</div>
106+
</div>
107+
)
108+
},
109+
renderPlanetProfileTab: function () {
110+
return (
111+
<div className='planetProfileTab'>
112+
<div className='formField'>
51113
<label>Planet name </label>
52-
<input valueLink={this.linkState('planetName')} className='inline-input'/>
53-
<button onClick={this.saveProfile} className='saveButton btn-primary'>Save</button>
114+
<input valueLink={this.linkState('planet.name')}/>
115+
</div>
116+
117+
<div className='formRadioField'>
118+
<input id='publicOption' checked={this.state.planet.public} onChange={this.handlePublicChange(true)} name='public' type='radio'/> <label htmlFor='publicOption'>Public</label>
119+
120+
<input id='privateOption' checked={!this.state.planet.public} onChange={this.handlePublicChange(false)} name='public' type='radio'/> <label htmlFor='privateOption'>Private</label>
54121
</div>
122+
<div className='formConfirm'>
123+
<button onClick={this.handleSavePlanetProfile} className='saveButton btn-primary'>Save</button>
55124

56-
<div className='planetDeleteForm'>
57-
<div className='planetDeleteControl'>
58-
<div className={'toggle' + (this.state.isDeletePlanetChecked ? '' : ' hide')}>
59-
<div className='planetDeleteLabel'>Are you sure to delete this planet?</div>
60-
<button ref='deleteCancelButton' onClick={this.cancelDeletePlanet} className='cancelButton btn-default'>Cancel</button>
61-
</div>
62-
<button onClick={this.doubleCheckDeletePlanet} className='deleteButton btn-primary'>{!this.state.isDeletePlanetChecked ? 'Delete Planet' : 'Confirm'}</button>
63-
</div>
125+
<div className={'alertInfo' + (this.state.profileSubmitStatus === 'sending' ? '' : ' hide')}>on Sending...</div>
126+
127+
<div className={'alertError' + (this.state.profileSubmitStatus === 'error' ? '' : ' hide')}>Connection failed.. Try again.</div>
128+
129+
<div className={'alertSuccess' + (this.state.profileSubmitStatus === 'done' ? '' : ' hide')}>Successfully done!!</div>
64130
</div>
65131
</div>
66132
)
133+
},
134+
renderPlanetDeleteTab: function () {
135+
var disabled = !this.state.deleteConfirmation.match(new RegExp('^' + this.props.planet.userName + '/' + this.props.planet.name + '$'))
67136

68137
return (
69-
<div onClick={this.interceptClick} className='PlanetSettingModal modal'>
70-
<div className='settingNav'>
71-
<h1>Planet setting</h1>
72-
<nav>
73-
<button className={this.state.currentTab === 'planetProfile' ? 'active' : ''} onClick={this.activePlanetProfile}><i className='fa fa-globe fa-fw'/> Planet profile</button>
74-
</nav>
75-
</div>
138+
<div className='planetDeleteTab'>
139+
<p>Are you sure to destroy <strong>'{this.props.planet.userName + '/' + this.props.planet.name}'</strong>?</p>
140+
<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>
141+
<input valueLink={this.linkState('deleteConfirmation')} placeholder='userName/planetName'/>
142+
<div className='formConfirm'>
143+
<button disabled={disabled} onClick={this.handleDeletePlanetClick}>{this.state.randomDeleteText}</button>
76144

77-
<div className='settingBody'>
78-
{content}
145+
<div className={'alertInfo' + (this.state.deleteSubmitStatus === 'sending' ? '' : ' hide')}>on Sending...</div>
146+
147+
<div className={'alertError' + (this.state.deleteSubmitStatus === 'error' ? '' : ' hide')}>Connection failed.. Try again.</div>
148+
149+
<div className={'alertSuccess' + (this.state.deleteSubmitStatus === 'done' ? '' : ' hide')}>Successfully done!!</div>
79150
</div>
80151
</div>
81152
)

0 commit comments

Comments
 (0)