mirror of
https://github.com/ascribe/onion.git
synced 2025-02-14 21:10:27 +01:00
WIP prize settings for admin
This commit is contained in:
parent
5ce549e533
commit
6ab5bec8d3
@ -15,6 +15,9 @@ import { mergeOptionsWithDuplicates } from '../../utils/general_utils';
|
|||||||
let Form = React.createClass({
|
let Form = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
url: React.PropTypes.string,
|
url: React.PropTypes.string,
|
||||||
|
buttons: React.PropTypes.object,
|
||||||
|
buttonSubmitText: React.PropTypes.string,
|
||||||
|
spinner: React.PropTypes.object,
|
||||||
handleSuccess: React.PropTypes.func,
|
handleSuccess: React.PropTypes.func,
|
||||||
getFormData: React.PropTypes.func,
|
getFormData: React.PropTypes.func,
|
||||||
children: React.PropTypes.oneOfType([
|
children: React.PropTypes.oneOfType([
|
||||||
@ -24,6 +27,12 @@ let Form = React.createClass({
|
|||||||
className: React.PropTypes.string
|
className: React.PropTypes.string
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getDefaultProps() {
|
||||||
|
return {
|
||||||
|
buttonSubmitText: 'SAVE'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {
|
return {
|
||||||
edited: false,
|
edited: false,
|
||||||
@ -125,7 +134,7 @@ let Form = React.createClass({
|
|||||||
buttons = (
|
buttons = (
|
||||||
<div className="row" style={{margin: 0}}>
|
<div className="row" style={{margin: 0}}>
|
||||||
<p className="pull-right">
|
<p className="pull-right">
|
||||||
<Button className="btn btn-default btn-sm ascribe-margin-1px" type="submit">SAVE</Button>
|
<Button className="btn btn-default btn-sm ascribe-margin-1px" type="submit">{this.props.buttonSubmitText}</Button>
|
||||||
<Button className="btn btn-danger btn-delete btn-sm ascribe-margin-1px" onClick={this.reset}>CANCEL</Button>
|
<Button className="btn btn-danger btn-delete btn-sm ascribe-margin-1px" onClick={this.reset}>CANCEL</Button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,12 +29,19 @@ import { getLangText } from '../utils/lang_utils';
|
|||||||
import { getCookie } from '../utils/fetch_api_utils';
|
import { getCookie } from '../utils/fetch_api_utils';
|
||||||
|
|
||||||
let SettingsContainer = React.createClass({
|
let SettingsContainer = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
children: React.PropTypes.oneOfType([
|
||||||
|
React.PropTypes.arrayOf(React.PropTypes.element),
|
||||||
|
React.PropTypes.element])
|
||||||
|
},
|
||||||
|
|
||||||
mixins: [Router.Navigation],
|
mixins: [Router.Navigation],
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="settings-container">
|
<div className="settings-container">
|
||||||
<AccountSettings />
|
<AccountSettings />
|
||||||
|
{this.props.children}
|
||||||
<APISettings />
|
<APISettings />
|
||||||
<BitcoinWalletSettings />
|
<BitcoinWalletSettings />
|
||||||
<LoanContractSettings />
|
<LoanContractSettings />
|
||||||
@ -121,6 +128,7 @@ let AccountSettings = React.createClass({
|
|||||||
</span>
|
</span>
|
||||||
</InputCheckbox>
|
</InputCheckbox>
|
||||||
</Property>
|
</Property>
|
||||||
|
<hr />
|
||||||
{/*<Property
|
{/*<Property
|
||||||
name='language'
|
name='language'
|
||||||
label={getLangText('Choose your Language')}
|
label={getLangText('Choose your Language')}
|
||||||
@ -135,7 +143,6 @@ let AccountSettings = React.createClass({
|
|||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</Property>*/}
|
</Property>*/}
|
||||||
<hr />
|
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
33
js/components/whitelabel/prize/actions/prize_actions.js
Normal file
33
js/components/whitelabel/prize/actions/prize_actions.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import alt from '../../../../alt';
|
||||||
|
import Q from 'q';
|
||||||
|
|
||||||
|
import PrizeFetcher from '../fetchers/prize_fetcher';
|
||||||
|
|
||||||
|
class PrizeActions {
|
||||||
|
constructor() {
|
||||||
|
this.generateActions(
|
||||||
|
'updatePrize'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchPrize() {
|
||||||
|
return Q.Promise((resolve, reject) => {
|
||||||
|
PrizeFetcher
|
||||||
|
.fetch()
|
||||||
|
.then((res) => {
|
||||||
|
this.actions.updatePrize({
|
||||||
|
prize: res.prize
|
||||||
|
});
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.logGlobal(err);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default alt.createActions(PrizeActions);
|
31
js/components/whitelabel/prize/actions/prize_jury_actions.js
Normal file
31
js/components/whitelabel/prize/actions/prize_jury_actions.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import alt from '../../../../alt';
|
||||||
|
import Q from 'q';
|
||||||
|
|
||||||
|
import PrizeJuryFetcher from '../fetchers/prize_jury_fetcher';
|
||||||
|
|
||||||
|
class PrizeJuryActions {
|
||||||
|
constructor() {
|
||||||
|
this.generateActions(
|
||||||
|
'updatePrizeJury'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchJury() {
|
||||||
|
return Q.Promise((resolve, reject) => {
|
||||||
|
PrizeJuryFetcher
|
||||||
|
.fetch()
|
||||||
|
.then((res) => {
|
||||||
|
this.actions.updatePrizeJury(res.members);
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.logGlobal(err);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default alt.createActions(PrizeJuryActions);
|
255
js/components/whitelabel/prize/components/settings_container.js
Normal file
255
js/components/whitelabel/prize/components/settings_container.js
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import UserStore from '../../../../stores/user_store';
|
||||||
|
import UserActions from '../../../../actions/user_actions';
|
||||||
|
import PrizeActions from '../actions/prize_actions';
|
||||||
|
import PrizeStore from '../stores/prize_store';
|
||||||
|
import PrizeJuryActions from '../actions/prize_jury_actions';
|
||||||
|
import PrizeJuryStore from '../stores/prize_jury_store';
|
||||||
|
|
||||||
|
import SettingsContainer from '../../../settings_container';
|
||||||
|
import CollapsibleParagraph from '../../../ascribe_collapsible/collapsible_paragraph';
|
||||||
|
|
||||||
|
import Form from '../../../ascribe_forms/form';
|
||||||
|
import Property from '../../../ascribe_forms/property';
|
||||||
|
import FormPropertyHeader from '../../../ascribe_forms/form_property_header';
|
||||||
|
|
||||||
|
import Table from '../../../ascribe_table/table';
|
||||||
|
import TableItem from '../../../ascribe_table/table_item';
|
||||||
|
import TableItemText from '../../../ascribe_table/table_item_text';
|
||||||
|
|
||||||
|
import GlobalNotificationModel from '../../../../models/global_notification_model';
|
||||||
|
import GlobalNotificationActions from '../../../../actions/global_notification_actions';
|
||||||
|
|
||||||
|
import AppConstants from '../../../../constants/application_constants';
|
||||||
|
import apiUrls from '../../../../constants/api_urls';
|
||||||
|
|
||||||
|
import { ColumnModel} from '../../../ascribe_table/models/table_models';
|
||||||
|
import { getLangText } from '../../../../utils/lang_utils';
|
||||||
|
|
||||||
|
|
||||||
|
let Settings = React.createClass({
|
||||||
|
getInitialState() {
|
||||||
|
return UserStore.getState();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
UserStore.listen(this.onChange);
|
||||||
|
UserActions.fetchCurrentUser();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
UserStore.unlisten(this.onChange);
|
||||||
|
},
|
||||||
|
|
||||||
|
onChange(state) {
|
||||||
|
this.setState(state);
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let prize_settings = null;
|
||||||
|
if (this.state.currentUser.is_admin){
|
||||||
|
prize_settings = <PrizeSettings />;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<SettingsContainer>
|
||||||
|
{prize_settings}
|
||||||
|
</SettingsContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let PrizeSettings = React.createClass({
|
||||||
|
|
||||||
|
getInitialState() {
|
||||||
|
return PrizeStore.getState();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
PrizeStore.listen(this.onChange);
|
||||||
|
PrizeActions.fetchPrize();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
PrizeStore.unlisten(this.onChange);
|
||||||
|
},
|
||||||
|
|
||||||
|
onChange(state) {
|
||||||
|
this.setState(state);
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<CollapsibleParagraph
|
||||||
|
title={'Prize Settings for ' + this.state.prize.name}
|
||||||
|
show={true}
|
||||||
|
defaultExpanded={true}>
|
||||||
|
<Form >
|
||||||
|
<Property
|
||||||
|
name='prize_name'
|
||||||
|
label={getLangText('Prize name')}
|
||||||
|
editable={false}>
|
||||||
|
<pre className="ascribe-pre">{this.state.prize.name}</pre>
|
||||||
|
</Property>
|
||||||
|
<Property
|
||||||
|
name='prize_rounds'
|
||||||
|
label={getLangText('Active round/Number of rounds')}
|
||||||
|
editable={false}>
|
||||||
|
<pre className="ascribe-pre">{this.state.prize.active_round}/{this.state.prize.rounds}</pre>
|
||||||
|
</Property>
|
||||||
|
<Property
|
||||||
|
name='num_submissions'
|
||||||
|
label={getLangText('Allowed number of submissions per user')}
|
||||||
|
editable={false}>
|
||||||
|
<pre className="ascribe-pre">{this.state.prize.num_submissions}</pre>
|
||||||
|
</Property>
|
||||||
|
<hr />
|
||||||
|
</Form>
|
||||||
|
<PrizeJurySettings
|
||||||
|
prize={this.state.prize}/>
|
||||||
|
</CollapsibleParagraph>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let PrizeJurySettings = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
prize: React.PropTypes.object
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState() {
|
||||||
|
return PrizeJuryStore.getState();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
PrizeJuryStore.listen(this.onChange);
|
||||||
|
PrizeJuryActions.fetchJury();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
PrizeJuryStore.unlisten(this.onChange);
|
||||||
|
},
|
||||||
|
|
||||||
|
onChange(state) {
|
||||||
|
this.setState(state);
|
||||||
|
},
|
||||||
|
|
||||||
|
handleCreateSuccess(response) {
|
||||||
|
PrizeJuryActions.fetchJury();
|
||||||
|
let notification = new GlobalNotificationModel(response.notification, 'success', 5000);
|
||||||
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let content = (
|
||||||
|
<div style={{textAlign: 'center'}}>
|
||||||
|
<img src={AppConstants.baseUrl + 'static/img/ascribe_animated_medium.gif'} />
|
||||||
|
</div>);
|
||||||
|
|
||||||
|
if (this.state.members.length > -1) {
|
||||||
|
content = this.state.members.map(function(member, i) {
|
||||||
|
return (
|
||||||
|
<Property
|
||||||
|
name={member.email}
|
||||||
|
label={member.email}
|
||||||
|
key={i}>
|
||||||
|
<div className="row-same-height">
|
||||||
|
<div className="no-padding col-xs-6 col-sm-10 col-xs-height col-middle">
|
||||||
|
{member.status}
|
||||||
|
</div>
|
||||||
|
<div className="col-xs-6 col-sm-2 col-xs-height">
|
||||||
|
<button
|
||||||
|
className="pull-right btn btn-default btn-sm"
|
||||||
|
data-id={member.name}>
|
||||||
|
{getLangText('RESEND INVITATION')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Property>);
|
||||||
|
}, this);
|
||||||
|
content = (
|
||||||
|
<div>
|
||||||
|
<Form>
|
||||||
|
{content}
|
||||||
|
<hr />
|
||||||
|
</Form>
|
||||||
|
</div>);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form
|
||||||
|
url={apiUrls.jury}
|
||||||
|
handleSuccess={this.handleCreateSuccess}
|
||||||
|
buttonSubmitText='INVITE'>
|
||||||
|
<FormPropertyHeader>
|
||||||
|
<h4 style={{margin: '30px 0px 10px 10px'}}>Jury Members</h4>
|
||||||
|
</FormPropertyHeader>
|
||||||
|
<Property
|
||||||
|
name='email'
|
||||||
|
label={getLangText('New jury member')}>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
placeholder={getLangText('Enter an email to invite a jury member')}
|
||||||
|
required/>
|
||||||
|
</Property>
|
||||||
|
<hr />
|
||||||
|
</Form>
|
||||||
|
{content}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let PrizesDashboard = React.createClass({
|
||||||
|
|
||||||
|
getColumnList() {
|
||||||
|
return [
|
||||||
|
new ColumnModel(
|
||||||
|
(item) => {
|
||||||
|
return {
|
||||||
|
'content': item.name
|
||||||
|
}; },
|
||||||
|
'name',
|
||||||
|
getLangText('Name'),
|
||||||
|
TableItemText,
|
||||||
|
6,
|
||||||
|
false,
|
||||||
|
null
|
||||||
|
),
|
||||||
|
new ColumnModel(
|
||||||
|
(item) => {
|
||||||
|
return {
|
||||||
|
'content': item.domain
|
||||||
|
}; },
|
||||||
|
'domain',
|
||||||
|
getLangText('Domain'),
|
||||||
|
TableItemText,
|
||||||
|
1,
|
||||||
|
false,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Table
|
||||||
|
responsive
|
||||||
|
className="ascribe-table"
|
||||||
|
columnList={this.getColumnList()}
|
||||||
|
itemList={this.state.prizeList}>
|
||||||
|
{this.state.prizeList.map((item, i) => {
|
||||||
|
return (
|
||||||
|
<TableItem
|
||||||
|
className="ascribe-table-item-selectable"
|
||||||
|
key={i}/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Table>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Settings;
|
@ -9,7 +9,9 @@ function getApiUrls(subdomain) {
|
|||||||
'users_signup': AppConstants.apiEndpoint + 'prize/' + subdomain + '/users/',
|
'users_signup': AppConstants.apiEndpoint + 'prize/' + subdomain + '/users/',
|
||||||
'user': AppConstants.apiEndpoint + 'prize/' + subdomain + '/users/',
|
'user': AppConstants.apiEndpoint + 'prize/' + subdomain + '/users/',
|
||||||
'piece_submit_to_prize': AppConstants.apiEndpoint + 'prize/' + subdomain + '/pieces/${piece_id}/submit/',
|
'piece_submit_to_prize': AppConstants.apiEndpoint + 'prize/' + subdomain + '/pieces/${piece_id}/submit/',
|
||||||
'piece': AppConstants.apiEndpoint + 'prize/' + subdomain + '/pieces/${piece_id}/'
|
'piece': AppConstants.apiEndpoint + 'prize/' + subdomain + '/pieces/${piece_id}/',
|
||||||
|
'prize': AppConstants.apiEndpoint + 'prize/' + subdomain + '/',
|
||||||
|
'jury': AppConstants.apiEndpoint + 'prize/' + subdomain + '/jury/'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
js/components/whitelabel/prize/fetchers/prize_fetcher.js
Normal file
12
js/components/whitelabel/prize/fetchers/prize_fetcher.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import requests from '../../../../utils/requests';
|
||||||
|
|
||||||
|
|
||||||
|
let PrizeFetcher = {
|
||||||
|
fetch() {
|
||||||
|
return requests.get('prize');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PrizeFetcher;
|
@ -0,0 +1,12 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import requests from '../../../../utils/requests';
|
||||||
|
|
||||||
|
|
||||||
|
let PrizeJuryFetcher = {
|
||||||
|
fetch() {
|
||||||
|
return requests.get('jury');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PrizeJuryFetcher;
|
@ -12,7 +12,7 @@ import PrizeRegisterPiece from './components/register_piece';
|
|||||||
import PrizePieceList from './components/piece_list';
|
import PrizePieceList from './components/piece_list';
|
||||||
import PrizePieceContainer from './components/ascribe_detail/piece_container';
|
import PrizePieceContainer from './components/ascribe_detail/piece_container';
|
||||||
import EditionContainer from '../../ascribe_detail/edition_container';
|
import EditionContainer from '../../ascribe_detail/edition_container';
|
||||||
import SettingsContainer from '../../../components/settings_container';
|
import SettingsContainer from './components/settings_container';
|
||||||
|
|
||||||
import App from './app';
|
import App from './app';
|
||||||
import AppConstants from '../../../constants/application_constants';
|
import AppConstants from '../../../constants/application_constants';
|
||||||
|
18
js/components/whitelabel/prize/stores/prize_jury_store.js
Normal file
18
js/components/whitelabel/prize/stores/prize_jury_store.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import alt from '../../../../alt';
|
||||||
|
|
||||||
|
import PrizeJuryActions from '../actions/prize_jury_actions';
|
||||||
|
|
||||||
|
class PrizeJuryStore {
|
||||||
|
constructor() {
|
||||||
|
this.members = [];
|
||||||
|
this.bindActions(PrizeJuryActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdatePrizeJury( members ) {
|
||||||
|
this.members = members;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default alt.createStore(PrizeJuryStore, 'PrizeJuryStore');
|
18
js/components/whitelabel/prize/stores/prize_store.js
Normal file
18
js/components/whitelabel/prize/stores/prize_store.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import alt from '../../../../alt';
|
||||||
|
|
||||||
|
import PrizeActions from '../actions/prize_actions';
|
||||||
|
|
||||||
|
class PrizeStore {
|
||||||
|
constructor() {
|
||||||
|
this.prize = [];
|
||||||
|
this.bindActions(PrizeActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdatePrize({ prize }) {
|
||||||
|
this.prize = prize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default alt.createStore(PrizeStore, 'PrizeStore');
|
Loading…
x
Reference in New Issue
Block a user