1
0
mirror of https://github.com/ascribe/onion.git synced 2024-11-15 01:25:17 +01:00

WIP prize settings for admin

This commit is contained in:
diminator 2015-08-05 14:40:26 +02:00
parent 5ce549e533
commit 6ab5bec8d3
11 changed files with 401 additions and 4 deletions

View File

@ -15,6 +15,9 @@ import { mergeOptionsWithDuplicates } from '../../utils/general_utils';
let Form = React.createClass({
propTypes: {
url: React.PropTypes.string,
buttons: React.PropTypes.object,
buttonSubmitText: React.PropTypes.string,
spinner: React.PropTypes.object,
handleSuccess: React.PropTypes.func,
getFormData: React.PropTypes.func,
children: React.PropTypes.oneOfType([
@ -24,6 +27,12 @@ let Form = React.createClass({
className: React.PropTypes.string
},
getDefaultProps() {
return {
buttonSubmitText: 'SAVE'
};
},
getInitialState() {
return {
edited: false,
@ -125,7 +134,7 @@ let Form = React.createClass({
buttons = (
<div className="row" style={{margin: 0}}>
<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>
</p>
</div>

View File

@ -29,12 +29,19 @@ import { getLangText } from '../utils/lang_utils';
import { getCookie } from '../utils/fetch_api_utils';
let SettingsContainer = React.createClass({
propTypes: {
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element])
},
mixins: [Router.Navigation],
render() {
return (
<div className="settings-container">
<AccountSettings />
{this.props.children}
<APISettings />
<BitcoinWalletSettings />
<LoanContractSettings />
@ -121,6 +128,7 @@ let AccountSettings = React.createClass({
</span>
</InputCheckbox>
</Property>
<hr />
{/*<Property
name='language'
label={getLangText('Choose your Language')}
@ -135,7 +143,6 @@ let AccountSettings = React.createClass({
</option>
</select>
</Property>*/}
<hr />
</Form>
);
}

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

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

View 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;

View File

@ -9,7 +9,9 @@ function getApiUrls(subdomain) {
'users_signup': AppConstants.apiEndpoint + 'prize/' + subdomain + '/users/',
'user': AppConstants.apiEndpoint + 'prize/' + subdomain + '/users/',
'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/'
};
}

View File

@ -0,0 +1,12 @@
'use strict';
import requests from '../../../../utils/requests';
let PrizeFetcher = {
fetch() {
return requests.get('prize');
}
};
export default PrizeFetcher;

View File

@ -0,0 +1,12 @@
'use strict';
import requests from '../../../../utils/requests';
let PrizeJuryFetcher = {
fetch() {
return requests.get('jury');
}
};
export default PrizeJuryFetcher;

View File

@ -12,7 +12,7 @@ import PrizeRegisterPiece from './components/register_piece';
import PrizePieceList from './components/piece_list';
import PrizePieceContainer from './components/ascribe_detail/piece_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 AppConstants from '../../../constants/application_constants';

View 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');

View 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');