1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-22 17:33:14 +01:00

Add UI button to allow admins to advance rounds

This commit is contained in:
Brett Sun 2015-12-22 10:05:03 +01:00
parent 70bf11dd6c
commit e9c52765a8
5 changed files with 159 additions and 46 deletions

View File

@ -0,0 +1,53 @@
'use strict'
import React from 'react';
import { getLangText } from '../../../../../../utils/lang_utils';
const PrizeAdvanceRoundModal = React.createClass({
propTypes: {
handleSuccess: React.PropTypes.func,
handleCancel: React.PropTypes.func
},
render() {
const { handleCancel, handleSuccess } = this.props;
return (
<div className="clearfix">
<div className="ascribe-modal-content">
<p>
{getLangText('Are you sure you want to advance to the next round of judging?')}
</p>
<p>
{getLangText('Advancing will keep only the currently selected pieces for review in the next round. ' +
'Ratings associated with each piece will be reset and all currently active jury members will be deactivated as well.')}
</p>
{/* Remove once api is up */}
<p>
<strong>{getLangText('Note: Advancing to the next round will only be available after submissions end on Dec. 27th.')}</strong>
</p>
</div>
<div
className="col-xs-6 ascribe-btn-container-left">
{/* Remove disabled from here too */}
<button
disabled
onClick={handleSuccess}
className="btn btn-default btn-wide">
{getLangText('Advance')}
</button>
</div>
<div className="col-xs-6 ascribe-btn-container-right">
<button
onClick={handleCancel}
className="btn btn-secondary btn-wide">
{getLangText('Cancel')}
</button>
</div>
</div>
);
}
});
export default PrizeAdvanceRoundModal;

View File

@ -2,6 +2,8 @@
import React from 'react'; import React from 'react';
import PrizeAdvanceRoundModal from './ascribe_modal/prize_advance_round_modal';
import UserStore from '../../../../../stores/user_store'; import UserStore from '../../../../../stores/user_store';
import UserActions from '../../../../../actions/user_actions'; import UserActions from '../../../../../actions/user_actions';
import PrizeActions from '../actions/prize_actions'; import PrizeActions from '../actions/prize_actions';
@ -15,6 +17,8 @@ import CollapsibleParagraph from '../../../../ascribe_collapsible/collapsible_pa
import Form from '../../../../ascribe_forms/form'; import Form from '../../../../ascribe_forms/form';
import Property from '../../../../ascribe_forms/property'; import Property from '../../../../ascribe_forms/property';
import ModalWrapper from '../../../../ascribe_modal/modal_wrapper';
import ActionPanel from '../../../../ascribe_panel/action_panel'; import ActionPanel from '../../../../ascribe_panel/action_panel';
import GlobalNotificationModel from '../../../../../models/global_notification_model'; import GlobalNotificationModel from '../../../../../models/global_notification_model';
@ -27,7 +31,7 @@ import { getLangText } from '../../../../../utils/lang_utils';
import { setDocumentTitle } from '../../../../../utils/dom_utils'; import { setDocumentTitle } from '../../../../../utils/dom_utils';
let Settings = React.createClass({ const Settings = React.createClass({
getInitialState() { getInitialState() {
return UserStore.getState(); return UserStore.getState();
}, },
@ -48,20 +52,15 @@ let Settings = React.createClass({
render() { render() {
setDocumentTitle(getLangText('Account settings')); setDocumentTitle(getLangText('Account settings'));
let prizeSettings = null;
if (this.state.currentUser.is_admin){
prizeSettings = <PrizeSettings />;
}
return ( return (
<SettingsContainer> <SettingsContainer>
{prizeSettings} {this.state.currentUser.is_admin ? <PrizeSettings /> : null}
</SettingsContainer> </SettingsContainer>
); );
} }
}); });
let PrizeSettings = React.createClass({ const PrizeSettings = React.createClass({
getInitialState() { getInitialState() {
return PrizeStore.getState(); return PrizeStore.getState();
}, },
@ -78,40 +77,74 @@ let PrizeSettings = React.createClass({
onChange(state) { onChange(state) {
this.setState(state); this.setState(state);
}, },
advanceRound() {
// TODO: add action to prizes to advance round once api is available
},
render() { render() {
return ( return (
<CollapsibleParagraph <div>
title={'Prize Settings for ' + this.state.prize.name} <CollapsibleParagraph
defaultExpanded={true}> title={'Prize Settings for ' + this.state.prize.name}
<Form > defaultExpanded={true}>
<Property <Form>
name='prize_name' <Property
label={getLangText('Prize name')} name='prize_name'
editable={false}> label={getLangText('Prize name')}
<pre className="ascribe-pre">{this.state.prize.name}</pre> editable={false}>
</Property> <pre className="ascribe-pre">{this.state.prize.name}</pre>
<Property </Property>
name='prize_rounds' <Property
label={getLangText('Active round/Number of rounds')} name='num_submissions'
editable={false}> label={getLangText('Allowed number of submissions per user')}
<pre className="ascribe-pre">{this.state.prize.active_round}/{this.state.prize.rounds}</pre> editable={false}>
</Property> <pre className="ascribe-pre">{this.state.prize.num_submissions}</pre>
<Property </Property>
name='num_submissions' </Form>
label={getLangText('Allowed number of submissions per user')}
editable={false}>
<pre className="ascribe-pre">{this.state.prize.num_submissions}</pre>
</Property>
<hr /> <hr />
</Form> <Form
<PrizeJurySettings buttons={(
prize={this.state.prize}/> <div className="row" style={{margin: 0}}>
</CollapsibleParagraph> <ModalWrapper
title={getLangText('Advance to next round')}
handleSuccess={this.advanceRound}
trigger={(
<button
type="button"
onClick={this.onAdvanceRound}
className="btn btn-default btn-sm pull-right">
{getLangText('ADVANCE ROUND')}
</button>
)}>
<PrizeAdvanceRoundModal />
</ModalWrapper>
</div>
)}>
<h4>{getLangText('Judging Rounds')}</h4>
<Property
name='prize_rounds'
label={getLangText('Number of rounds')}
editable={false}>
<pre className="ascribe-pre">{this.state.prize.rounds}</pre>
</Property>
<Property
name='prize_active_round'
label={getLangText('Active round')}
editable={false}>
<pre className="ascribe-pre">{this.state.prize.active_round}</pre>
</Property>
</Form>
<hr />
<PrizeJurySettings
prize={this.state.prize}/>
</CollapsibleParagraph>
</div>
); );
} }
}); });
let PrizeJurySettings = React.createClass({ const PrizeJurySettings = React.createClass({
propTypes: { propTypes: {
prize: React.PropTypes.object prize: React.PropTypes.object
}, },
@ -141,29 +174,31 @@ let PrizeJurySettings = React.createClass({
}, },
handleActivate(event) { handleActivate(event) {
let email = event.target.getAttribute('data-id'); const email = event.target.getAttribute('data-id');
PrizeJuryActions.activateJury(email).then((response) => { PrizeJuryActions
.activateJury(email)
.then((response) => {
PrizeJuryActions.fetchJury(); PrizeJuryActions.fetchJury();
this.displayNotification(response); this.displayNotification(response);
}); });
}, },
handleRevoke(event) { handleRevoke(event) {
let email = event.target.getAttribute('data-id'); const email = event.target.getAttribute('data-id');
PrizeJuryActions PrizeJuryActions
.revokeJury(email) .revokeJury(email)
.then(this.displayNotification); .then(this.displayNotification);
}, },
handleResend(event) { handleResend(event) {
let email = event.target.getAttribute('data-id'); const email = event.target.getAttribute('data-id');
PrizeJuryActions PrizeJuryActions
.resendJuryInvitation(email) .resendJuryInvitation(email)
.then(this.displayNotification); .then(this.displayNotification);
}, },
displayNotification(response) { displayNotification(response) {
let notification = new GlobalNotificationModel(response.notification, 'success', 5000); const notification = new GlobalNotificationModel(response.notification, 'success', 5000);
GlobalNotificationActions.appendGlobalNotification(notification); GlobalNotificationActions.appendGlobalNotification(notification);
}, },
@ -172,7 +207,7 @@ let PrizeJurySettings = React.createClass({
return ( return (
<ActionPanel <ActionPanel
name={member.email} name={member.email}
key={i} key={member.email}
content={ content={
<div> <div>
<div className='ascribe-panel-title'> <div className='ascribe-panel-title'>
@ -207,7 +242,7 @@ let PrizeJurySettings = React.createClass({
return ( return (
<ActionPanel <ActionPanel
name={member.email} name={member.email}
key={i} key={member.email}
content={ content={
<div> <div>
<div className='ascribe-panel-title'> <div className='ascribe-panel-title'>
@ -235,7 +270,7 @@ let PrizeJurySettings = React.createClass({
return ( return (
<ActionPanel <ActionPanel
name={member.email} name={member.email}
key={i} key={member.email}
content={ content={
<div> <div>
<div className='ascribe-panel-title'> <div className='ascribe-panel-title'>
@ -260,9 +295,8 @@ let PrizeJurySettings = React.createClass({
}, },
getMembers() { getMembers() {
let content = <AscribeSpinner color='dark-blue' size='md' />;
if (this.state.members.length > -1) { if (this.state.members.length > -1) {
content = ( return (
<div> <div>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Active Jury Members')} title={getLangText('Active Jury Members')}
@ -280,9 +314,11 @@ let PrizeJurySettings = React.createClass({
{this.getMembersInactive()} {this.getMembersInactive()}
</CollapsibleParagraph> </CollapsibleParagraph>
</div>); </div>);
} else {
return <AscribeSpinner color='dark-blue' size='md' />;
} }
return content;
}, },
render() { render() {
return ( return (
<div> <div>

3
sass/ascribe_modal.scss Normal file
View File

@ -0,0 +1,3 @@
.ascribe-modal-content {
margin: 20px 0;
}

View File

@ -42,6 +42,7 @@ $BASE_URL: '<%= BASE_URL %>';
@import 'ascribe_custom_style'; @import 'ascribe_custom_style';
@import 'ascribe_button'; @import 'ascribe_button';
@import 'ascribe_spinner'; @import 'ascribe_spinner';
@import 'ascribe_modal';
@import 'whitelabel/index'; @import 'whitelabel/index';

View File

@ -22,6 +22,26 @@ $pr--button-color: $pr--nav-fg-prim-color;
} }
} }
.btn-secondary {
background-color: white;
border-color: $pr--button-color;
color: $pr--button-color;
&:hover,
&:active,
&:focus,
&:active:hover,
&:active:focus,
&:active.focus,
&.active:hover,
&.active:focus,
&.active.focus {
background-color: lighten($pr--button-color, 20%);
border-color: lighten($pr--button-color, 20%);
color: white;
}
}
.navbar-default { .navbar-default {
.navbar-nav > .ascribe-powered-by, li > a { .navbar-nav > .ascribe-powered-by, li > a {
color: $pr--button-color !important; color: $pr--button-color !important;