diff --git a/js/components/ascribe_forms/form.js b/js/components/ascribe_forms/form.js index 0f022a0d..89e51da2 100644 --- a/js/components/ascribe_forms/form.js +++ b/js/components/ascribe_forms/form.js @@ -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 = (

- +

diff --git a/js/components/settings_container.js b/js/components/settings_container.js index 381cd1c4..c35fba1e 100644 --- a/js/components/settings_container.js +++ b/js/components/settings_container.js @@ -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 (
+ {this.props.children} @@ -121,6 +128,7 @@ let AccountSettings = React.createClass({ +
{/* */} -
); } diff --git a/js/components/whitelabel/prize/actions/prize_actions.js b/js/components/whitelabel/prize/actions/prize_actions.js new file mode 100644 index 00000000..5646e2d6 --- /dev/null +++ b/js/components/whitelabel/prize/actions/prize_actions.js @@ -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); \ No newline at end of file diff --git a/js/components/whitelabel/prize/actions/prize_jury_actions.js b/js/components/whitelabel/prize/actions/prize_jury_actions.js new file mode 100644 index 00000000..e2fe1a96 --- /dev/null +++ b/js/components/whitelabel/prize/actions/prize_jury_actions.js @@ -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); \ No newline at end of file diff --git a/js/components/whitelabel/prize/components/settings_container.js b/js/components/whitelabel/prize/components/settings_container.js new file mode 100644 index 00000000..af72ac18 --- /dev/null +++ b/js/components/whitelabel/prize/components/settings_container.js @@ -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 = ; + } + return ( + + {prize_settings} + + ); + } +}); + +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 ( + +
+ +
{this.state.prize.name}
+
+ +
{this.state.prize.active_round}/{this.state.prize.rounds}
+
+ +
{this.state.prize.num_submissions}
+
+
+
+ +
+ ); + } +}); + +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 = ( +
+ +
); + + if (this.state.members.length > -1) { + content = this.state.members.map(function(member, i) { + return ( + +
+
+ {member.status} +
+
+ +
+
+
); + }, this); + content = ( +
+
+ {content} +
+
+
); + } + return ( +
+
+ +

Jury Members

+
+ + + +
+
+ {content} +
+ ); + } +}); + + +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 ( + + {this.state.prizeList.map((item, i) => { + return ( + + ); + })} +
+ ); + } +}); + +export default Settings; \ No newline at end of file diff --git a/js/components/whitelabel/prize/constants/api_urls.js b/js/components/whitelabel/prize/constants/api_urls.js index e868d403..49441341 100644 --- a/js/components/whitelabel/prize/constants/api_urls.js +++ b/js/components/whitelabel/prize/constants/api_urls.js @@ -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/' }; } diff --git a/js/components/whitelabel/prize/fetchers/prize_fetcher.js b/js/components/whitelabel/prize/fetchers/prize_fetcher.js new file mode 100644 index 00000000..0bf9fc55 --- /dev/null +++ b/js/components/whitelabel/prize/fetchers/prize_fetcher.js @@ -0,0 +1,12 @@ +'use strict'; + +import requests from '../../../../utils/requests'; + + +let PrizeFetcher = { + fetch() { + return requests.get('prize'); + } +}; + +export default PrizeFetcher; diff --git a/js/components/whitelabel/prize/fetchers/prize_jury_fetcher.js b/js/components/whitelabel/prize/fetchers/prize_jury_fetcher.js new file mode 100644 index 00000000..be00e930 --- /dev/null +++ b/js/components/whitelabel/prize/fetchers/prize_jury_fetcher.js @@ -0,0 +1,12 @@ +'use strict'; + +import requests from '../../../../utils/requests'; + + +let PrizeJuryFetcher = { + fetch() { + return requests.get('jury'); + } +}; + +export default PrizeJuryFetcher; diff --git a/js/components/whitelabel/prize/routes.js b/js/components/whitelabel/prize/routes.js index ac490c4e..62b190d4 100644 --- a/js/components/whitelabel/prize/routes.js +++ b/js/components/whitelabel/prize/routes.js @@ -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'; diff --git a/js/components/whitelabel/prize/stores/prize_jury_store.js b/js/components/whitelabel/prize/stores/prize_jury_store.js new file mode 100644 index 00000000..59a54329 --- /dev/null +++ b/js/components/whitelabel/prize/stores/prize_jury_store.js @@ -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'); \ No newline at end of file diff --git a/js/components/whitelabel/prize/stores/prize_store.js b/js/components/whitelabel/prize/stores/prize_store.js new file mode 100644 index 00000000..f311e1fe --- /dev/null +++ b/js/components/whitelabel/prize/stores/prize_store.js @@ -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'); \ No newline at end of file