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:
parent
70bf11dd6c
commit
e9c52765a8
@ -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;
|
@ -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,8 +77,14 @@ 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 (
|
||||||
|
<div>
|
||||||
<CollapsibleParagraph
|
<CollapsibleParagraph
|
||||||
title={'Prize Settings for ' + this.state.prize.name}
|
title={'Prize Settings for ' + this.state.prize.name}
|
||||||
defaultExpanded={true}>
|
defaultExpanded={true}>
|
||||||
@ -90,28 +95,56 @@ let PrizeSettings = React.createClass({
|
|||||||
editable={false}>
|
editable={false}>
|
||||||
<pre className="ascribe-pre">{this.state.prize.name}</pre>
|
<pre className="ascribe-pre">{this.state.prize.name}</pre>
|
||||||
</Property>
|
</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
|
<Property
|
||||||
name='num_submissions'
|
name='num_submissions'
|
||||||
label={getLangText('Allowed number of submissions per user')}
|
label={getLangText('Allowed number of submissions per user')}
|
||||||
editable={false}>
|
editable={false}>
|
||||||
<pre className="ascribe-pre">{this.state.prize.num_submissions}</pre>
|
<pre className="ascribe-pre">{this.state.prize.num_submissions}</pre>
|
||||||
</Property>
|
</Property>
|
||||||
<hr />
|
|
||||||
</Form>
|
</Form>
|
||||||
|
<hr />
|
||||||
|
<Form
|
||||||
|
buttons={(
|
||||||
|
<div className="row" style={{margin: 0}}>
|
||||||
|
<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
|
<PrizeJurySettings
|
||||||
prize={this.state.prize}/>
|
prize={this.state.prize}/>
|
||||||
</CollapsibleParagraph>
|
</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
3
sass/ascribe_modal.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.ascribe-modal-content {
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
@ -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';
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user