mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 09:23:13 +01:00
Remove prize whitelabels
This commit is contained in:
parent
53ef5248ca
commit
37e4b68afb
@ -1,89 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Form from './form';
|
||||
import Property from './property';
|
||||
import InputTextAreaToggable from './input_textarea_toggable';
|
||||
import InputCheckbox from './input_checkbox';
|
||||
|
||||
import Alert from 'react-bootstrap/lib/Alert';
|
||||
|
||||
import AscribeSpinner from '../ascribe_spinner';
|
||||
import ApiUrls from '../../constants/api_urls';
|
||||
|
||||
import { getLangText } from '../../utils/lang_utils.js';
|
||||
|
||||
import requests from '../../utils/requests';
|
||||
|
||||
let PieceSubmitToPrizeForm = React.createClass({
|
||||
propTypes: {
|
||||
piece: React.PropTypes.object,
|
||||
handleSuccess: React.PropTypes.func
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Form
|
||||
ref='form'
|
||||
url={requests.prepareUrl(ApiUrls.piece_submit_to_prize, {piece_id: this.props.piece.id})}
|
||||
handleSuccess={this.props.handleSuccess}
|
||||
buttons={
|
||||
<div className="modal-footer">
|
||||
<p className="pull-right">
|
||||
<button
|
||||
className="btn btn-default btn-sm ascribe-margin-1px"
|
||||
type="submit">
|
||||
{getLangText('SUBMIT TO PRIZE')}
|
||||
</button>
|
||||
</p>
|
||||
</div>}
|
||||
spinner={
|
||||
<div className="modal-footer">
|
||||
<p className="pull-right">
|
||||
<AscribeSpinner color='dark-blue' size='md'/>
|
||||
</p>
|
||||
</div>}>
|
||||
<Property
|
||||
name='artist_statement'
|
||||
label={getLangText('Artist statement')}
|
||||
editable={true}
|
||||
overrideForm={true}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('Enter your statement')}
|
||||
required />
|
||||
</Property>
|
||||
<Property
|
||||
name='work_description'
|
||||
label={getLangText('Work description')}
|
||||
editable={true}
|
||||
overrideForm={true}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('Enter the description for your work')}
|
||||
required />
|
||||
</Property>
|
||||
<Property
|
||||
name="terms"
|
||||
className="ascribe-property-collapsible-toggle">
|
||||
<InputCheckbox>
|
||||
<span>
|
||||
{' ' + getLangText('I agree to the Terms of Service the art price') + ' '}
|
||||
(<a href="https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/sluice/terms.pdf" target="_blank" style={{fontSize: '0.9em', color: 'rgba(0,0,0,0.7)'}}>
|
||||
{getLangText('read')}
|
||||
</a>)
|
||||
</span>
|
||||
</InputCheckbox>
|
||||
</Property>
|
||||
<Alert bsStyle='warning'>
|
||||
<p>{getLangText('Are you sure you want to submit to the prize?')}</p>
|
||||
<p>{getLangText('This is an irrevocable action%s', '.')}</p>
|
||||
</Alert>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export default PieceSubmitToPrizeForm;
|
@ -1,28 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import AppPrizeConstants from './prize_application_constants';
|
||||
|
||||
|
||||
function getPrizeApiUrls(subdomain) {
|
||||
return {
|
||||
'users_login': AppPrizeConstants.prizeApiEndpoint + subdomain + '/users/login/',
|
||||
'users_signup': AppPrizeConstants.prizeApiEndpoint + subdomain + '/users/',
|
||||
'user': AppPrizeConstants.prizeApiEndpoint + subdomain + '/users/',
|
||||
'piece_submit_to_prize': AppPrizeConstants.prizeApiEndpoint + subdomain + '/pieces/${piece_id}/submit/',
|
||||
'pieces_list': AppPrizeConstants.prizeApiEndpoint + subdomain + '/pieces/',
|
||||
'piece': AppPrizeConstants.prizeApiEndpoint + subdomain + '/pieces/${piece_id}/',
|
||||
'prize': AppPrizeConstants.prizeApiEndpoint + subdomain + '/',
|
||||
'jurys': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/',
|
||||
'jury': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/${email}/',
|
||||
'jury_activate': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/${email}/activate/',
|
||||
'jury_resend': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/${email}/resend/',
|
||||
'ratings': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/',
|
||||
'rating': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/',
|
||||
'rating_average': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/average/',
|
||||
'select_piece': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/select/',
|
||||
'notes': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/',
|
||||
'note': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/${piece_id}/'
|
||||
};
|
||||
}
|
||||
|
||||
export default getPrizeApiUrls;
|
@ -1,9 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import AppConstants from '../../../../constants/application_constants';
|
||||
|
||||
let prizeConstants = {
|
||||
prizeApiEndpoint: AppConstants.apiEndpoint + 'prizes/'
|
||||
};
|
||||
|
||||
export default prizeConstants;
|
@ -1,417 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import { History } from 'react-router';
|
||||
|
||||
import GlobalNotificationModel from '../../../../../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
|
||||
|
||||
import Form from '../../../../../ascribe_forms/form';
|
||||
import Property from '../../../../../ascribe_forms/property';
|
||||
import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_toggable';
|
||||
|
||||
import InputFineuploader from '../../../../../ascribe_forms/input_fineuploader';
|
||||
import UploadButton from '../../../../../ascribe_uploader/ascribe_upload_button/upload_button';
|
||||
|
||||
import AscribeSpinner from '../../../../../ascribe_spinner';
|
||||
|
||||
import ApiUrls from '../../../../../../constants/api_urls';
|
||||
import AppConstants from '../../../../../../constants/application_constants';
|
||||
import { validationParts, validationTypes } from '../../../../../../constants/uploader_constants';
|
||||
|
||||
import requests from '../../../../../../utils/requests';
|
||||
|
||||
import { getErrorNotificationMessage } from '../../../../../../utils/error_utils';
|
||||
import { setCookie } from '../../../../../../utils/fetch_api_utils';
|
||||
import { validateForms } from '../../../../../../utils/form_utils';
|
||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||
import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils';
|
||||
|
||||
|
||||
const { object } = React.PropTypes;
|
||||
|
||||
const PRRegisterPieceForm = React.createClass({
|
||||
propTypes: {
|
||||
currentUser: object.isRequired,
|
||||
location: object
|
||||
},
|
||||
|
||||
mixins: [History],
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
digitalWorkKeyReady: true,
|
||||
thumbnailKeyReady: true,
|
||||
|
||||
// we set this to true, as it is not required
|
||||
supportingMaterialsReady: true,
|
||||
proofOfPaymentReady: true,
|
||||
piece: null,
|
||||
submitted: false
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* In this method, we're composing all fields on the page
|
||||
* in two steps, first submitting the registration of the piece and
|
||||
* second adding all the additional details
|
||||
*/
|
||||
submit() {
|
||||
if (!this.validateForms()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// disable the submission button right after the user
|
||||
// clicks on it to avoid double submission
|
||||
this.setState({
|
||||
submitted: true
|
||||
});
|
||||
|
||||
const { currentUser } = this.props;
|
||||
const { registerPieceForm,
|
||||
additionalDataForm,
|
||||
uploadersForm } = this.refs;
|
||||
const { digitalWorkKey,
|
||||
thumbnailKey,
|
||||
supportingMaterials,
|
||||
proofOfPayment } = uploadersForm.refs;
|
||||
const additionalDataFormData = additionalDataForm.getFormData();
|
||||
|
||||
// composing data for piece registration
|
||||
const registerPieceFormData = registerPieceForm.getFormData();
|
||||
registerPieceFormData.digital_work_key = digitalWorkKey.state.value;
|
||||
registerPieceFormData.thumbnail_file = thumbnailKey.state.value;
|
||||
registerPieceFormData.terms = true;
|
||||
|
||||
// submitting the piece
|
||||
requests
|
||||
.post(ApiUrls.pieces_list, { body: registerPieceFormData })
|
||||
.then(({ piece, notification }) => {
|
||||
this.setState({piece}, () => {
|
||||
supportingMaterials.refs.input.createBlobRoutine();
|
||||
proofOfPayment.refs.input.createBlobRoutine();
|
||||
});
|
||||
|
||||
setCookie(currentUser.email, piece.id);
|
||||
|
||||
return requests
|
||||
.post(ApiUrls.piece_extradata, {
|
||||
body: {
|
||||
extradata: additionalDataFormData,
|
||||
piece_id: piece.id
|
||||
},
|
||||
piece_id: piece.id
|
||||
})
|
||||
.then(() => {
|
||||
const notificationMessage = new GlobalNotificationModel(notification || getLangText('You have successfully submitted "%s" to Portfolio Review 2015', piece.title), 'success', 5000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notificationMessage);
|
||||
});
|
||||
})
|
||||
.then(() => this.history.push(`/pieces/${this.state.piece.id}`))
|
||||
.catch((err) => {
|
||||
const errMessage = (getErrorNotificationMessage(err) || getLangText("Oops! We weren't able to send your submission.")) +
|
||||
getLangText(' Please contact support@ascribe.io');
|
||||
|
||||
const notificationMessage = new GlobalNotificationModel(errMessage, 'danger', 10000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notificationMessage);
|
||||
|
||||
console.logGlobal(new Error('Portfolio Review piece registration failed'), err);
|
||||
|
||||
// Reset the submit button
|
||||
this.setState({
|
||||
submitted: false
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
validateForms() {
|
||||
const { registerPieceForm,
|
||||
additionalDataForm,
|
||||
uploadersForm } = this.refs;
|
||||
|
||||
return validateForms([registerPieceForm, additionalDataForm, uploadersForm], true);
|
||||
},
|
||||
|
||||
getCreateBlobRoutine() {
|
||||
const { piece } = this.state;
|
||||
|
||||
if(piece && piece.id) {
|
||||
return {
|
||||
url: ApiUrls.blob_otherdatas,
|
||||
pieceId: piece.id
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* These two methods are overloaded so that we can track the ready-state
|
||||
* of each uploader in the component
|
||||
* @param {string} uploaderKey Name of the uploader's key to track
|
||||
*/
|
||||
setIsUploadReady(uploaderKey) {
|
||||
return (isUploadReady) => {
|
||||
this.setState({
|
||||
[uploaderKey]: isUploadReady
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
handleOptionalFileValidationFailed(uploaderKey) {
|
||||
return () => {
|
||||
this.setState({
|
||||
[uploaderKey]: true
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
getSubmitButton() {
|
||||
const { digitalWorkKeyReady,
|
||||
thumbnailKeyReady,
|
||||
supportingMaterialsReady,
|
||||
proofOfPaymentReady,
|
||||
submitted } = this.state;
|
||||
|
||||
if(submitted) {
|
||||
return (
|
||||
<span disabled className="btn btn-default btn-wide btn-spinner">
|
||||
<AscribeSpinner color="dark-blue" size="md" />
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-default btn-wide"
|
||||
disabled={!(digitalWorkKeyReady && thumbnailKeyReady && proofOfPaymentReady && supportingMaterialsReady)}
|
||||
onClick={this.submit}>
|
||||
{getLangText('Submit to Portfolio Review')}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
const { location } = this.props;
|
||||
const maxThumbnailSize = validationTypes.workThumbnail.sizeLimit / 1000000;
|
||||
|
||||
return (
|
||||
<div className="register-piece--form">
|
||||
<Form
|
||||
buttons={null}
|
||||
className="ascribe-form-bordered"
|
||||
ref="registerPieceForm">
|
||||
<Property
|
||||
name='artist_name'
|
||||
label={getLangText('Full name')}>
|
||||
<input
|
||||
type="text"
|
||||
placeholder={getLangText('(e.g. Andy Warhol)')}
|
||||
required/>
|
||||
</Property>
|
||||
<Property
|
||||
name='title'
|
||||
label={getLangText('Title of the Work')}>
|
||||
<input
|
||||
type="text"
|
||||
placeholder={getLangText("(e.g. 32 Campbell's Soup Cans)")}
|
||||
required/>
|
||||
</Property>
|
||||
<Property
|
||||
name='date_created'
|
||||
label={getLangText('Year of creation')}>
|
||||
<input
|
||||
type="number"
|
||||
placeholder={getLangText('(e.g. 1962)')}
|
||||
min={1}
|
||||
required/>
|
||||
</Property>
|
||||
<Property
|
||||
name='artist_statement'
|
||||
label={getLangText("Artist's statement")}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('Enter your statement')}/>
|
||||
</Property>
|
||||
</Form>
|
||||
<Form
|
||||
buttons={null}
|
||||
className="ascribe-form-bordered"
|
||||
ref="additionalDataForm">
|
||||
<Property
|
||||
name='1-date_of_birth'
|
||||
label={getLangText('Date of Birth')}>
|
||||
<input
|
||||
type="number"
|
||||
placeholder={getLangText('(e.g. 1962)')}
|
||||
min={1900}
|
||||
required/>
|
||||
</Property>
|
||||
<Property
|
||||
name='2-artist_bio'
|
||||
label={getLangText('Biography')}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('Enter your biography')}/>
|
||||
</Property>
|
||||
<Property
|
||||
name='3-exhibition'
|
||||
label={getLangText('Exhibition / Publication history (optional)')}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('Enter exhibitions and publication history')}/>
|
||||
</Property>
|
||||
<Property
|
||||
name='4-phone_number'
|
||||
label={getLangText('Phone Number')}>
|
||||
<input
|
||||
type="tel"
|
||||
placeholder={getLangText('Enter your phone number')}
|
||||
required/>
|
||||
</Property>
|
||||
<Property
|
||||
name='5-email'
|
||||
label={getLangText('Email Address')}>
|
||||
<input
|
||||
type="email"
|
||||
placeholder={getLangText('Enter your email')}
|
||||
required/>
|
||||
</Property>
|
||||
<Property
|
||||
name='6-website'
|
||||
label={getLangText('Website')}>
|
||||
<input
|
||||
type="url"
|
||||
placeholder={getLangText('Enter your website')}
|
||||
required/>
|
||||
</Property>
|
||||
</Form>
|
||||
<Form
|
||||
buttons={null}
|
||||
className="ascribe-form-bordered"
|
||||
ref="uploadersForm">
|
||||
<Property
|
||||
name="digitalWorkKey"
|
||||
label={getLangText('Select the PDF with your work')}>
|
||||
<InputFineuploader
|
||||
fileInputElement={UploadButton()}
|
||||
isReadyForFormSubmission={formSubmissionValidation.atLeastOneUploadedFile}
|
||||
setIsUploadReady={this.setIsUploadReady('digitalWorkKeyReady')}
|
||||
createBlobRoutine={{
|
||||
url: ApiUrls.blob_digitalworks
|
||||
}}
|
||||
keyRoutine={{
|
||||
url: AppConstants.serverUrl + 's3/key/',
|
||||
fileClass: 'digitalwork'
|
||||
}}
|
||||
validation={{
|
||||
itemLimit: validationTypes.registerWork.itemLimit,
|
||||
sizeLimit: validationTypes.additionalData.sizeLimit,
|
||||
allowedExtensions: ['pdf']
|
||||
}}
|
||||
location={location}
|
||||
fileClassToUpload={{
|
||||
singular: getLangText('Select the Portfolio'),
|
||||
plural: getLangText('Select the Portfolios')
|
||||
}}
|
||||
required/>
|
||||
</Property>
|
||||
<Property
|
||||
name="thumbnailKey"
|
||||
label={`${getLangText('Featured Cover photo')} (max ${maxThumbnailSize}MB)`}>
|
||||
<InputFineuploader
|
||||
fileInputElement={UploadButton()}
|
||||
createBlobRoutine={{
|
||||
url: ApiUrls.blob_thumbnails
|
||||
}}
|
||||
isReadyForFormSubmission={formSubmissionValidation.atLeastOneUploadedFile}
|
||||
setIsUploadReady={this.setIsUploadReady('thumbnailKeyReady')}
|
||||
keyRoutine={{
|
||||
url: AppConstants.serverUrl + 's3/key/',
|
||||
fileClass: 'thumbnail'
|
||||
}}
|
||||
validation={{
|
||||
itemLimit: validationTypes.workThumbnail.itemLimit,
|
||||
sizeLimit: validationTypes.workThumbnail.sizeLimit,
|
||||
allowedExtensions: validationParts.allowedExtensions.images
|
||||
}}
|
||||
location={location}
|
||||
fileClassToUpload={{
|
||||
singular: getLangText('Select cover photo'),
|
||||
plural: getLangText('Select cover photos')
|
||||
}}
|
||||
required/>
|
||||
</Property>
|
||||
<Property
|
||||
name="supportingMaterials"
|
||||
label={getLangText('Supporting Materials (Optional)')}>
|
||||
<InputFineuploader
|
||||
fileInputElement={UploadButton()}
|
||||
isReadyForFormSubmission={formSubmissionValidation.atLeastOneUploadedFile}
|
||||
setIsUploadReady={this.setIsUploadReady('supportingMaterialsReady')}
|
||||
onValidationFailed={this.handleOptionalFileValidationFailed('supportingMaterialsReady')}
|
||||
createBlobRoutine={this.getCreateBlobRoutine()}
|
||||
keyRoutine={{
|
||||
url: AppConstants.serverUrl + 's3/key/',
|
||||
fileClass: 'otherdata'
|
||||
}}
|
||||
validation={{
|
||||
itemLimit: validationParts.itemLimit.single,
|
||||
sizeLimit: validationTypes.additionalData.sizeLimit
|
||||
}}
|
||||
location={location}
|
||||
fileClassToUpload={{
|
||||
singular: getLangText('Select supporting material'),
|
||||
plural: getLangText('Select supporting materials')
|
||||
}}/>
|
||||
</Property>
|
||||
<Property
|
||||
name="proofOfPayment"
|
||||
label={getLangText('Proof of payment')}>
|
||||
<InputFineuploader
|
||||
fileInputElement={UploadButton()}
|
||||
isReadyForFormSubmission={formSubmissionValidation.atLeastOneUploadedFile}
|
||||
setIsUploadReady={this.setIsUploadReady('proofOfPaymentReady')}
|
||||
createBlobRoutine={this.getCreateBlobRoutine()}
|
||||
keyRoutine={{
|
||||
url: AppConstants.serverUrl + 's3/key/',
|
||||
fileClass: 'otherdata'
|
||||
}}
|
||||
validation={{
|
||||
itemLimit: validationParts.itemLimit.single,
|
||||
sizeLimit: validationTypes.additionalData.sizeLimit,
|
||||
allowedExtensions: validationParts.allowedExtensions.images
|
||||
}}
|
||||
location={location}
|
||||
fileClassToUpload={{
|
||||
singular: getLangText('Select Screenshot'),
|
||||
plural: getLangText('Select Screenshots')
|
||||
}}
|
||||
required/>
|
||||
</Property>
|
||||
</Form>
|
||||
<Form
|
||||
buttons={null}
|
||||
className="ascribe-form-bordered">
|
||||
<Property
|
||||
name="terms"
|
||||
className="ascribe-property-collapsible-toggle">
|
||||
<span>
|
||||
{getLangText('By submitting this form, you agree to the') + ' '}
|
||||
<a
|
||||
href="https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/portfolioreview/tos-portfolioreview.pdf"
|
||||
target="_blank">
|
||||
{getLangText('Terms of Service')}
|
||||
</a>
|
||||
{' of Portfolio Review.'}
|
||||
</span>
|
||||
</Property>
|
||||
</Form>
|
||||
{this.getSubmitButton()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default PRRegisterPieceForm;
|
@ -1,33 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
|
||||
|
||||
const PRHero = React.createClass({
|
||||
propTypes: {
|
||||
currentUser: React.PropTypes.shape({
|
||||
email: React.PropTypes.object
|
||||
}).isRequired
|
||||
},
|
||||
|
||||
render() {
|
||||
const { currentUser } = this.props;
|
||||
|
||||
return (
|
||||
<div className="piece--hero">
|
||||
<h2><Glyphicon glyph="ok" />
|
||||
{getLangText('Congratulations') + (currentUser.email ? ` ${currentUser.email}!` : '!')}
|
||||
</h2>
|
||||
<h1>{getLangText('You have successfully submitted to Portfolio Review 2016.')}</h1>
|
||||
<p>Not you? <Link to="/logout">{getLangText('Change account.')}</Link></p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default PRHero;
|
@ -1,124 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import { History } from 'react-router';
|
||||
|
||||
import Button from 'react-bootstrap/lib/Button';
|
||||
import ButtonGroup from 'react-bootstrap/lib/ButtonGroup';
|
||||
|
||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||
|
||||
import PrizeActions from '../../simple_prize/actions/prize_actions';
|
||||
import PrizeStore from '../../simple_prize/stores/prize_store';
|
||||
|
||||
import { omitFromObject } from '../../../../../utils/general_utils';
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
|
||||
|
||||
const PRLanding = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
// Provided from router
|
||||
location: React.PropTypes.object
|
||||
},
|
||||
|
||||
mixins: [History],
|
||||
|
||||
getInitialState() {
|
||||
return PrizeStore.getState();
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
const { location } = this.props;
|
||||
|
||||
PrizeStore.listen(this.onChange);
|
||||
PrizeActions.fetchPrize();
|
||||
|
||||
if (location.query.redirect) {
|
||||
window.setTimeout(() => this.history.replace({
|
||||
pathname: `/${location.query.redirect}`,
|
||||
query: omitFromObject(location.query, ['redirect'])
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PrizeStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
getButtons() {
|
||||
if (this.state.prize && this.state.prize.active) {
|
||||
return (
|
||||
<ButtonGroup className="enter" bsSize="large" vertical>
|
||||
<LinkContainer to="/signup">
|
||||
<Button>
|
||||
{getLangText('Sign up to submit')}
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
|
||||
<p>
|
||||
{getLangText('or, already an ascribe user?')}
|
||||
</p>
|
||||
<LinkContainer to="/login">
|
||||
<Button>
|
||||
{getLangText('Log in to submit')}
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
</ButtonGroup>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<ButtonGroup className="enter" bsSize="large" vertical>
|
||||
<a className="btn btn-default" href="https://www.ascribe.io/app/signup">
|
||||
{getLangText('Sign up to ascribe')}
|
||||
</a>
|
||||
|
||||
<p>
|
||||
{getLangText('or, already an ascribe user?')}
|
||||
</p>
|
||||
<LinkContainer to="/login">
|
||||
<Button>
|
||||
{getLangText('Log in')}
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
</ButtonGroup>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
getTitle() {
|
||||
const { prize } = this.state;
|
||||
|
||||
return (
|
||||
<p>
|
||||
{getLangText(prize && prize.active ? 'This is the submission page for Portfolio Review 2016.'
|
||||
: 'Submissions for Portfolio Review 2016 are now closed.')}
|
||||
</p>
|
||||
);
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col-xs-12 wp-landing-wrapper">
|
||||
<h1>
|
||||
{getLangText('Welcome to Portfolio Review 2016')}
|
||||
</h1>
|
||||
{this.getTitle()}
|
||||
{this.getButtons()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default PRLanding;
|
@ -1,72 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import { Link, History } from 'react-router';
|
||||
|
||||
import Col from 'react-bootstrap/lib/Col';
|
||||
import Row from 'react-bootstrap/lib/Row';
|
||||
|
||||
import PRRegisterPieceForm from './pr_forms/pr_register_piece_form';
|
||||
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
import { getCookie } from '../../../../../utils/fetch_api_utils';
|
||||
|
||||
|
||||
const { object } = React.PropTypes;
|
||||
|
||||
const PRRegisterPiece = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
// Provided from router
|
||||
location: object
|
||||
},
|
||||
|
||||
mixins: [History],
|
||||
|
||||
componentDidUpdate() {
|
||||
const { currentUser } = this.props;
|
||||
if (currentUser.email) {
|
||||
const submittedPieceId = getCookie(currentUser.email);
|
||||
if (submittedPieceId) {
|
||||
this.history.push(`/pieces/${submittedPieceId}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
const { currentUser, location } = this.props;
|
||||
|
||||
setDocumentTitle(getLangText('Submit to Portfolio Review'));
|
||||
|
||||
return (
|
||||
<Row>
|
||||
<Col xs={6}>
|
||||
<div className="register-piece--info">
|
||||
<h1>Portfolio Review</h1>
|
||||
<h2>{getLangText('Submission closing on %s', ' 27 Dec 2015')}</h2>
|
||||
<p>For more information, visit:
|
||||
<a href="http://www.portfolio-review.de/submission/" target="_blank">
|
||||
portfolio-review.de
|
||||
</a>
|
||||
</p>
|
||||
<p style={{marginTop: '1em'}}>
|
||||
{getLangText("You're submitting as %s. ", currentUser.email)}
|
||||
<Link to="/logout">{getLangText('Change account?')}</Link>
|
||||
</p>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs={6}>
|
||||
<PRRegisterPieceForm
|
||||
location={location}
|
||||
currentUser={currentUser} />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default PRRegisterPiece;
|
@ -1,26 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import history from '../../../../../../history';
|
||||
|
||||
|
||||
export function AuthPrizeRoleRedirect({ to, when }) {
|
||||
if (when.constructor !== Array || !when.length) {
|
||||
throw new Error('`when` of AuthPrizeRoleRedirect must be an array containing values');
|
||||
}
|
||||
if (!to || to.indexOf('/') === -1) {
|
||||
throw new Error('`to` of AuthPrizeRoleRedirect must be defined and contain a valid route');
|
||||
}
|
||||
|
||||
return function(currentUser, query) {
|
||||
const exprToValidate = when
|
||||
.map(role => currentUser[role])
|
||||
.reduce((a, b) => a || b);
|
||||
|
||||
if (exprToValidate) {
|
||||
window.setTimeout(() => history.replace({ query, pathname: to }));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import EventActions from '../../../../actions/event_actions';
|
||||
|
||||
import UserStore from '../../../../stores/user_store';
|
||||
import UserActions from '../../../../actions/user_actions';
|
||||
|
||||
import Hero from './components/pr_hero';
|
||||
|
||||
import AppBase from '../../../app_base';
|
||||
import AppRouteWrapper from '../../../app_route_wrapper';
|
||||
import Header from '../../../header';
|
||||
|
||||
import { getSubdomain } from '../../../../utils/general_utils';
|
||||
import { getCookie } from '../../../../utils/fetch_api_utils';
|
||||
|
||||
|
||||
let PRApp = React.createClass({
|
||||
propTypes: {
|
||||
activeRoute: React.PropTypes.object.isRequired,
|
||||
children: React.PropTypes.element.isRequired,
|
||||
history: React.PropTypes.object.isRequired,
|
||||
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
|
||||
|
||||
// Provided from AppBase
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object
|
||||
},
|
||||
|
||||
render() {
|
||||
const { activeRoute, children, currentUser, history, routes, whitelabel } = this.props;
|
||||
const subdomain = getSubdomain();
|
||||
const path = activeRoute && activeRoute.path;
|
||||
const Footer = activeRoute && activeRoute.footer;
|
||||
|
||||
let style = {};
|
||||
let header;
|
||||
if (currentUser && currentUser.email && history.isActive(`/pieces/${getCookie(currentUser.email)}`)) {
|
||||
header = (<Hero currentUser={currentUser} />);
|
||||
style = { paddingTop: '0 !important' };
|
||||
} else if (currentUser && (currentUser.is_admin || currentUser.is_jury || currentUser.is_judge)) {
|
||||
header = (
|
||||
<Header
|
||||
currentUser={currentUser}
|
||||
routes={routes}
|
||||
whitelabel={whitelabel}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
style = { paddingTop: '0 !important' };
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={style}
|
||||
className={classNames('ascribe-app', 'ascribe-prize-app', `route--${(path ? path.split('/')[0] : 'landing')}`)}>
|
||||
{header}
|
||||
<AppRouteWrapper
|
||||
currentUser={currentUser}
|
||||
whitelabel={whitelabel}>
|
||||
{/* Routes are injected here */}
|
||||
{children}
|
||||
</AppRouteWrapper>
|
||||
{Footer ? <Footer /> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default AppBase(PRApp);
|
@ -1,137 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import { Route, IndexRoute } from 'react-router';
|
||||
|
||||
import { ProxyHandler, AuthRedirect } from '../../../components/ascribe_routes/proxy_handler';
|
||||
import { AuthPrizeRoleRedirect } from './portfolioreview/components/pr_routes/pr_proxy_handler';
|
||||
|
||||
// General components
|
||||
import EditionContainer from '../../ascribe_detail/edition_container';
|
||||
import LogoutContainer from '../../logout_container';
|
||||
import PasswordResetContainer from '../../password_reset_container';
|
||||
import CoaVerifyContainer from '../../coa_verify_container';
|
||||
import ErrorNotFoundPage from '../../error_not_found_page';
|
||||
|
||||
import SPApp from './simple_prize/prize_app';
|
||||
import SPLanding from './simple_prize/components/prize_landing';
|
||||
import SPLoginContainer from './simple_prize/components/prize_login_container';
|
||||
import SPSignupContainer from './simple_prize/components/prize_signup_container';
|
||||
import SPRegisterPiece from './simple_prize/components/prize_register_piece';
|
||||
import SPPieceList from './simple_prize/components/prize_piece_list';
|
||||
import SPPieceContainer from './simple_prize/components/ascribe_detail/prize_piece_container';
|
||||
import SPSettingsContainer from './simple_prize/components/prize_settings_container';
|
||||
|
||||
import SluicePieceContainer from './sluice/components/sluice_detail/sluice_piece_container';
|
||||
|
||||
import PRApp from './portfolioreview/pr_app';
|
||||
import PRLanding from './portfolioreview/components/pr_landing';
|
||||
import PRRegisterPiece from './portfolioreview/components/pr_register_piece';
|
||||
|
||||
import { getLangText } from '../../../utils/lang_utils';
|
||||
|
||||
|
||||
const ROUTES = {
|
||||
sluice: (
|
||||
<Route path='/' component={SPApp}>
|
||||
<IndexRoute
|
||||
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SPLanding)} />
|
||||
<Route
|
||||
path='login'
|
||||
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SPLoginContainer)} />
|
||||
<Route
|
||||
path='logout'
|
||||
component={ProxyHandler(AuthRedirect({to: '/', when: 'loggedOut'}))(LogoutContainer)} />
|
||||
<Route
|
||||
path='signup'
|
||||
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(SPSignupContainer)} />
|
||||
<Route
|
||||
path='password_reset'
|
||||
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(PasswordResetContainer)} />
|
||||
<Route
|
||||
path='settings'
|
||||
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SPSettingsContainer)} />
|
||||
<Route
|
||||
path='register_piece'
|
||||
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SPRegisterPiece)}
|
||||
headerTitle={getLangText('+ NEW WORK')} />
|
||||
<Route
|
||||
path='collection'
|
||||
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SPPieceList)}
|
||||
headerTitle={getLangText('COLLECTION')} />
|
||||
<Route
|
||||
path='pieces/:pieceId'
|
||||
component={SluicePieceContainer} />
|
||||
<Route
|
||||
path='editions/:editionId'
|
||||
component={EditionContainer} />
|
||||
<Route
|
||||
path='coa_verify'
|
||||
component={CoaVerifyContainer} />
|
||||
<Route
|
||||
path='*'
|
||||
component={ErrorNotFoundPage} />
|
||||
</Route>
|
||||
),
|
||||
portfolioreview: (
|
||||
<Route path='/' component={PRApp}>
|
||||
<IndexRoute
|
||||
component={ProxyHandler(AuthPrizeRoleRedirect({ to: '/collection', when: ['is_admin', 'is_judge', 'is_jury'] }))(PRLanding)} />
|
||||
<Route
|
||||
path='register_piece'
|
||||
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(PRRegisterPiece)} />
|
||||
<Route
|
||||
path='collection'
|
||||
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SPPieceList)}
|
||||
headerTitle={getLangText('SUBMISSIONS')} />
|
||||
<Route
|
||||
path='login'
|
||||
component={ProxyHandler(
|
||||
AuthPrizeRoleRedirect({ to: '/collection', when: ['is_admin', 'is_judge', 'is_jury'] }),
|
||||
AuthRedirect({to: '/register_piece', when: 'loggedIn'})
|
||||
)(SPLoginContainer)} />
|
||||
<Route
|
||||
path='logout'
|
||||
component={ProxyHandler(AuthRedirect({to: '/', when: 'loggedOut'}))(LogoutContainer)} />
|
||||
<Route
|
||||
path='signup'
|
||||
component={ProxyHandler(
|
||||
AuthPrizeRoleRedirect({ to: '/collection', when: ['is_admin', 'is_judge', 'is_jury'] }),
|
||||
AuthRedirect({to: '/register_piece', when: 'loggedIn'})
|
||||
)(SPSignupContainer)} />
|
||||
<Route
|
||||
path='password_reset'
|
||||
component={ProxyHandler(
|
||||
AuthPrizeRoleRedirect({ to: '/collection', when: ['is_admin', 'is_judge', 'is_jury'] }),
|
||||
AuthRedirect({to: '/register_piece', when: 'loggedIn'})
|
||||
)(PasswordResetContainer)} />
|
||||
<Route
|
||||
path='settings'
|
||||
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SPSettingsContainer)} />
|
||||
<Route
|
||||
path='pieces/:pieceId'
|
||||
component={SPPieceContainer} />
|
||||
<Route
|
||||
path='editions/:editionId'
|
||||
component={EditionContainer} />
|
||||
<Route
|
||||
path='coa_verify'
|
||||
component={CoaVerifyContainer} />
|
||||
<Route
|
||||
path='*'
|
||||
component={ErrorNotFoundPage} />
|
||||
</Route>
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
function getRoutes(commonRoutes, subdomain) {
|
||||
if(subdomain in ROUTES) {
|
||||
return ROUTES[subdomain];
|
||||
} else {
|
||||
throw new Error('Subdomain wasn\'t specified in the wallet app.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default getRoutes;
|
@ -1,28 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import { alt } from '../../../../../alt';
|
||||
|
||||
import PrizeFetcher from '../fetchers/prize_fetcher';
|
||||
|
||||
class PrizeActions {
|
||||
constructor() {
|
||||
this.generateActions(
|
||||
'updatePrize'
|
||||
);
|
||||
}
|
||||
|
||||
fetchPrize() {
|
||||
PrizeFetcher
|
||||
.fetch()
|
||||
.then((res) => {
|
||||
this.actions.updatePrize({
|
||||
prize: res
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default alt.createActions(PrizeActions);
|
@ -1,76 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import { alt } from '../../../../../alt';
|
||||
import Q from 'q';
|
||||
|
||||
import PrizeJuryFetcher from '../fetchers/prize_jury_fetcher';
|
||||
|
||||
class PrizeJuryActions {
|
||||
constructor() {
|
||||
this.generateActions(
|
||||
'updatePrizeJury',
|
||||
'removePrizeJury',
|
||||
'activatePrizeJury'
|
||||
);
|
||||
}
|
||||
|
||||
fetchJury() {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
PrizeJuryFetcher
|
||||
.fetch()
|
||||
.then((res) => {
|
||||
this.actions.updatePrizeJury(res.members);
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
activateJury(email) {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
PrizeJuryFetcher
|
||||
.activate(email)
|
||||
.then((res) => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
revokeJury(email) {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
PrizeJuryFetcher
|
||||
.delete(email)
|
||||
.then((res) => {
|
||||
this.actions.removePrizeJury(email);
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
resendJuryInvitation(email) {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
PrizeJuryFetcher
|
||||
.resend(email)
|
||||
.then((res) => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default alt.createActions(PrizeJuryActions);
|
@ -1,76 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import { alt } from '../../../../../alt';
|
||||
import Q from 'q';
|
||||
|
||||
import PrizeRatingFetcher from '../fetchers/prize_rating_fetcher';
|
||||
|
||||
class PrizeRatingActions {
|
||||
constructor() {
|
||||
this.generateActions(
|
||||
'updatePrizeRatings',
|
||||
'updatePrizeRatingAverage',
|
||||
'updatePrizeRating',
|
||||
'resetPrizeRatings'
|
||||
);
|
||||
}
|
||||
|
||||
fetchAverage(pieceId, round) {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
PrizeRatingFetcher
|
||||
.fetchAverage(pieceId, round)
|
||||
.then((res) => {
|
||||
this.actions.updatePrizeRatingAverage(res.data);
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fetchOne(pieceId, round) {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
PrizeRatingFetcher
|
||||
.fetchOne(pieceId, round)
|
||||
.then((res) => {
|
||||
this.actions.updatePrizeRating(res.rating.rating);
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
createRating(pieceId, rating, round) {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
PrizeRatingFetcher
|
||||
.rate(pieceId, rating, round)
|
||||
.then((res) => {
|
||||
this.actions.updatePrizeRating(res.rating.rating);
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
toggleShortlist(pieceId) {
|
||||
return Q.Promise((resolve, reject) => {
|
||||
PrizeRatingFetcher
|
||||
.select(pieceId)
|
||||
.then((res) => {
|
||||
this.actions.updatePrizeRatings(res.data.ratings);
|
||||
resolve(res);
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default alt.createActions(PrizeRatingActions);
|
@ -1,191 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import StarRating from 'react-star-rating';
|
||||
import Moment from 'moment';
|
||||
|
||||
import PieceListActions from '../../../../../../actions/piece_list_actions';
|
||||
import PieceListStore from '../../../../../../stores/piece_list_store';
|
||||
|
||||
import PrizeRatingActions from '../../actions/prize_rating_actions';
|
||||
|
||||
import InputCheckbox from '../../../../../ascribe_forms/input_checkbox';
|
||||
|
||||
import AccordionListItemPiece from '../../../../../ascribe_accordion_list/accordion_list_item_piece';
|
||||
|
||||
import GlobalNotificationModel from '../../../../../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
|
||||
|
||||
import AclProxy from '../../../../../acl_proxy';
|
||||
import SubmitToPrizeButton from './../ascribe_buttons/submit_to_prize_button';
|
||||
|
||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||
|
||||
|
||||
let AccordionListItemPrize = React.createClass({
|
||||
propTypes: {
|
||||
content: React.PropTypes.object.isRequired,
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
|
||||
children: React.PropTypes.oneOfType([
|
||||
React.PropTypes.arrayOf(React.PropTypes.element),
|
||||
React.PropTypes.element
|
||||
]),
|
||||
className: React.PropTypes.string
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return PieceListStore.getState();
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
PieceListStore.listen(this.onChange);
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PieceListStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
handleSubmitPrizeSuccess(response) {
|
||||
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||
|
||||
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||
|
||||
const notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
},
|
||||
|
||||
getPrizeButtons() {
|
||||
const { currentUser, content: { id, ratings } } = this.props;
|
||||
|
||||
if (currentUser && (currentUser.is_jury || currentUser.is_judge)) {
|
||||
if (ratings && (ratings.rating || ratings.average)) {
|
||||
// jury and rating available
|
||||
let rating = null;
|
||||
let caption = null;
|
||||
|
||||
if (ratings.rating) {
|
||||
rating = parseInt(ratings.rating, 10);
|
||||
caption = getLangText('Your rating');
|
||||
} else if (ratings.average) {
|
||||
rating = ratings.average;
|
||||
caption = getLangText('Average of ' + ratings.num_ratings + ' rating(s)');
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="list-rating" className="pull-right">
|
||||
<Link to={`/pieces/${id}`}>
|
||||
<StarRating
|
||||
ref='rating'
|
||||
name="prize-rating"
|
||||
caption={caption}
|
||||
step={0.5}
|
||||
size='sm'
|
||||
rating={rating}
|
||||
ratingAmount={5} />
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
if (currentUser.is_judge) {
|
||||
return (
|
||||
<div className="react-rating-caption pull-right">
|
||||
{getLangText('Not rated')}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
// jury and no rating yet
|
||||
return (
|
||||
<div className="react-rating-caption pull-right">
|
||||
<Link to={`/pieces/${id}`}>
|
||||
{getLangText('Submit your rating')}
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return this.getPrizeButtonsParticipant();
|
||||
}
|
||||
},
|
||||
|
||||
getPrizeButtonsParticipant() {
|
||||
return (
|
||||
<AclProxy
|
||||
aclObject={this.props.content.acl}
|
||||
aclName="acl_wallet_submit">
|
||||
<SubmitToPrizeButton
|
||||
className="pull-right"
|
||||
piece={this.props.content}
|
||||
handleSuccess={this.handleSubmitPrizeSuccess} />
|
||||
</AclProxy>
|
||||
);
|
||||
},
|
||||
|
||||
handleShortlistSuccess(message) {
|
||||
const notification = new GlobalNotificationModel(message, 'success', 2000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
},
|
||||
|
||||
refreshPieceData() {
|
||||
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||
|
||||
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||
},
|
||||
|
||||
onSelectChange() {
|
||||
PrizeRatingActions.toggleShortlist(this.props.content.id)
|
||||
.then((res) => {
|
||||
this.refreshPieceData();
|
||||
this.handleShortlistSuccess(res.notification);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
getPrizeBadge() {
|
||||
const { currentUser } = this.props;
|
||||
|
||||
if (currentUser && currentUser.is_judge) {
|
||||
return (
|
||||
<span className="pull-right ascribe-checkbox-wrapper ascribe-checkbox-badge">
|
||||
<InputCheckbox
|
||||
defaultChecked={this.props.content.selected}
|
||||
onChange={this.onSelectChange} />
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
const { children, className, content, currentUser } = this.props;
|
||||
|
||||
// Only show the artist name if you are the participant or if you are a judge and the piece is shortlisted
|
||||
const artistName = ((currentUser.is_jury && !currentUser.is_judge) || (currentUser.is_judge && !content.selected )) ?
|
||||
<span className="glyphicon glyphicon-eye-close" aria-hidden="true"/> : content.artist_name;
|
||||
|
||||
return (
|
||||
<AccordionListItemPiece
|
||||
className={className}
|
||||
piece={content}
|
||||
artistName={artistName}
|
||||
subsubheading={
|
||||
<div>
|
||||
<span>{Moment(content.date_created, 'YYYY-MM-DD').year()}</span>
|
||||
</div>
|
||||
}
|
||||
buttons={this.getPrizeButtons()}
|
||||
badge={this.getPrizeBadge()}>
|
||||
{children}
|
||||
</AccordionListItemPiece>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default AccordionListItemPrize;
|
@ -1,55 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper';
|
||||
import PieceSubmitToPrizeForm from '../../../../../ascribe_forms/form_submit_to_prize';
|
||||
|
||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||
|
||||
|
||||
let SubmitToPrizeButton = React.createClass({
|
||||
propTypes: {
|
||||
className: React.PropTypes.string,
|
||||
handleSuccess: React.PropTypes.func,
|
||||
piece: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
getSubmitButton() {
|
||||
if (this.props.piece.prize) {
|
||||
return (
|
||||
<button
|
||||
disabled
|
||||
className="btn btn-default btn-xs pull-right">
|
||||
{getLangText('Submitted to prize') + ' '}
|
||||
<span className='ascribe-icon icon-ascribe-ok'/>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
else {
|
||||
return (
|
||||
<button
|
||||
className={classNames('btn', 'btn-default', 'btn-xs', this.props.className)}>
|
||||
{getLangText('Submit to prize')}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ModalWrapper
|
||||
trigger={this.getSubmitButton()}
|
||||
handleSuccess={this.props.handleSuccess}
|
||||
title={getLangText('Submit to prize')}>
|
||||
<PieceSubmitToPrizeForm
|
||||
piece={this.props.piece}
|
||||
handleSuccess={this.props.handleSuccess}/>
|
||||
</ModalWrapper>
|
||||
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default SubmitToPrizeButton;
|
@ -1,495 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import Moment from 'moment';
|
||||
|
||||
import StarRating from 'react-star-rating';
|
||||
|
||||
import ReactError from '../../../../../../mixins/react_error';
|
||||
import { ResourceNotFoundError } from '../../../../../../models/errors';
|
||||
|
||||
import PrizeActions from '../../actions/prize_actions';
|
||||
import PrizeStore from '../../stores/prize_store';
|
||||
import PrizeRatingActions from '../../actions/prize_rating_actions';
|
||||
import PrizeRatingStore from '../../stores/prize_rating_store';
|
||||
|
||||
import PieceListStore from '../../../../../../stores/piece_list_store';
|
||||
import PieceListActions from '../../../../../../actions/piece_list_actions';
|
||||
import PieceActions from '../../../../../../actions/piece_actions';
|
||||
import PieceStore from '../../../../../../stores/piece_store';
|
||||
|
||||
import Piece from '../../../../../../components/ascribe_detail/piece';
|
||||
import Note from '../../../../../../components/ascribe_detail/note';
|
||||
|
||||
import AscribeSpinner from '../../../../../ascribe_spinner';
|
||||
|
||||
import Form from '../../../../../../components/ascribe_forms/form';
|
||||
import Property from '../../../../../../components/ascribe_forms/property';
|
||||
import InputTextAreaToggable from '../../../../../../components/ascribe_forms/input_textarea_toggable';
|
||||
import CollapsibleParagraph from '../../../../../../components/ascribe_collapsible/collapsible_paragraph';
|
||||
|
||||
import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader';
|
||||
|
||||
import InputCheckbox from '../../../../../ascribe_forms/input_checkbox';
|
||||
import ListRequestActions from '../../../../../ascribe_forms/list_form_request_actions';
|
||||
|
||||
import GlobalNotificationModel from '../../../../../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
|
||||
|
||||
import DetailProperty from '../../../../../ascribe_detail/detail_property';
|
||||
|
||||
import ApiUrls from '../../../../../../constants/api_urls';
|
||||
import { mergeOptions } from '../../../../../../utils/general_utils';
|
||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||
import { setDocumentTitle } from '../../../../../../utils/dom_utils';
|
||||
|
||||
|
||||
/**
|
||||
* This is the component that implements resource/data specific functionality
|
||||
*/
|
||||
let PrizePieceContainer = React.createClass({
|
||||
propTypes: {
|
||||
selectedPrizeActionButton: React.PropTypes.func,
|
||||
|
||||
// Provided from PrizeApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
// Provided from router
|
||||
location: React.PropTypes.object,
|
||||
params: React.PropTypes.object
|
||||
},
|
||||
|
||||
mixins: [ReactError],
|
||||
|
||||
getInitialState() {
|
||||
return PieceStore.getInitialState();
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
PieceStore.listen(this.onChange);
|
||||
|
||||
this.loadPiece();
|
||||
},
|
||||
|
||||
// This is done to update the container when the user clicks on the prev or next
|
||||
// button to update the URL parameter (and therefore to switch pieces) or
|
||||
// when the user clicks on a notification while being in another piece view
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.params.pieceId !== nextProps.params.pieceId) {
|
||||
PieceActions.flushPiece();
|
||||
this.loadPiece(nextProps.params.pieceId);
|
||||
}
|
||||
},
|
||||
|
||||
componentDidUpdate() {
|
||||
const { pieceMeta: { err: pieceErr } } = this.state;
|
||||
|
||||
if (pieceErr && pieceErr.status === 404) {
|
||||
this.throws(new ResourceNotFoundError(getLangText("Oops, the piece you're looking for doesn't exist.")));
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PieceStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
getActions() {
|
||||
const { currentUser } = this.props;
|
||||
const { piece } = this.state;
|
||||
|
||||
if (piece.notifications && piece.notifications.length > 0) {
|
||||
return (
|
||||
<ListRequestActions
|
||||
pieceOrEditions={piece}
|
||||
currentUser={currentUser}
|
||||
handleSuccess={this.loadPiece}
|
||||
notifications={piece.notifications} />);
|
||||
}
|
||||
},
|
||||
|
||||
loadPiece(pieceId = this.props.params.pieceId) {
|
||||
PieceActions.fetchPiece(pieceId);
|
||||
},
|
||||
|
||||
render() {
|
||||
const { currentUser, selectedPrizeActionButton } = this.props;
|
||||
const { piece } = this.state;
|
||||
|
||||
if (piece.id) {
|
||||
/*
|
||||
|
||||
This really needs a refactor!
|
||||
|
||||
- Tim
|
||||
|
||||
*/
|
||||
// Only show the artist name if you are the participant or if you are a judge and the piece is shortlisted
|
||||
let artistName;
|
||||
if ((currentUser.is_jury && !currentUser.is_judge) || (currentUser.is_judge && !piece.selected )) {
|
||||
artistName = <span className="glyphicon glyphicon-eye-close" aria-hidden="true" />;
|
||||
setDocumentTitle(piece.title);
|
||||
} else {
|
||||
artistName = piece.artist_name;
|
||||
setDocumentTitle(`${artistName}, ${piece.title}`);
|
||||
}
|
||||
|
||||
// Only show the artist email if you are a judge and the piece is shortlisted
|
||||
const artistEmail = currentUser.is_judge && piece.selected ? (
|
||||
<DetailProperty
|
||||
label={getLangText('REGISTREE')}
|
||||
value={piece.user_registered} />
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<Piece
|
||||
piece={piece}
|
||||
currentUser={currentUser}
|
||||
header={
|
||||
<div className="ascribe-detail-header">
|
||||
<NavigationHeader
|
||||
piece={piece}
|
||||
currentUser={currentUser} />
|
||||
|
||||
<h1 className="ascribe-detail-title">{piece.title}</h1>
|
||||
<DetailProperty label={getLangText('BY')} value={artistName} />
|
||||
<DetailProperty label={getLangText('DATE')} value={Moment(piece.date_created, 'YYYY-MM-DD').year()} />
|
||||
{artistEmail}
|
||||
{this.getActions()}
|
||||
<hr />
|
||||
</div>
|
||||
}
|
||||
subheader={
|
||||
<PrizePieceRatings
|
||||
loadPiece={this.loadPiece}
|
||||
piece={piece}
|
||||
currentUser={currentUser}
|
||||
selectedPrizeActionButton={selectedPrizeActionButton} />
|
||||
}>
|
||||
<PrizePieceDetails piece={piece} />
|
||||
</Piece>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="fullpage-spinner">
|
||||
<AscribeSpinner color='dark-blue' size='lg' />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let NavigationHeader = React.createClass({
|
||||
propTypes: {
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
piece: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
render() {
|
||||
const { currentUser, piece } = this.props;
|
||||
|
||||
if (currentUser.email && currentUser.is_judge && currentUser.is_jury && !currentUser.is_admin && piece.navigation) {
|
||||
const nav = piece.navigation;
|
||||
|
||||
return (
|
||||
<div style={{marginBottom: '1em'}}>
|
||||
<div className="row no-margin">
|
||||
<Link className="disable-select" to={`/pieces/${ nav.prev_index || piece.id }`}>
|
||||
<span className="glyphicon glyphicon-chevron-left pull-left link-ascribe" aria-hidden="true">
|
||||
{getLangText('Previous')}
|
||||
</span>
|
||||
</Link>
|
||||
<Link className="disable-select" to={`/pieces/${ nav.next_index || piece.id }`}>
|
||||
<span className="pull-right link-ascribe">
|
||||
{getLangText('Next')}
|
||||
<span className="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
<hr/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let PrizePieceRatings = React.createClass({
|
||||
propTypes: {
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
loadPiece: React.PropTypes.func.isRequired,
|
||||
piece: React.PropTypes.object.isRequired,
|
||||
|
||||
selectedPrizeActionButton: React.PropTypes.func
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return mergeOptions(
|
||||
PieceListStore.getState(),
|
||||
PrizeStore.getState(),
|
||||
PrizeRatingStore.getInitialState()
|
||||
);
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
PrizeRatingStore.listen(this.onChange);
|
||||
PrizeStore.listen(this.onChange);
|
||||
PieceListStore.listen(this.onChange);
|
||||
|
||||
PrizeActions.fetchPrize();
|
||||
this.fetchRatingsIfAuthorized();
|
||||
},
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.currentUser.email !== this.props.currentUser.email) {
|
||||
this.fetchRatingsIfAuthorized();
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PieceListStore.unlisten(this.onChange);
|
||||
PrizeStore.unlisten(this.onChange);
|
||||
PrizeRatingStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
// The StarRating component does not have a property that lets us set
|
||||
// a default value at initialization. Since the ratingCache would otherwise on
|
||||
// every mouseover be overridden, we need to set it ourselves initially to deal
|
||||
// with the problem.
|
||||
onChange(state) {
|
||||
if (state.prize && state.prize.active_round != this.state.prize.active_round) {
|
||||
this.fetchRatingsIfAuthorized(state);
|
||||
}
|
||||
|
||||
this.setState(state);
|
||||
|
||||
if (this.refs.rating) {
|
||||
this.refs.rating.state.ratingCache = {
|
||||
pos: this.refs.rating.state.pos,
|
||||
rating: this.state.currentRating,
|
||||
caption: this.refs.rating.props.caption,
|
||||
name: this.refs.rating.props.name
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
fetchRatingsIfAuthorized(state = this.state) {
|
||||
const { currentUser: {
|
||||
is_admin: isAdmin,
|
||||
is_judge: isJudge,
|
||||
is_jury: isJury
|
||||
},
|
||||
piece: { id: pieceId } } = this.props;
|
||||
|
||||
if (state.prize && 'active_round' in state.prize && (isAdmin || isJudge || isJury)) {
|
||||
PrizeRatingActions.fetchOne(pieceId, state.prize.active_round);
|
||||
PrizeRatingActions.fetchAverage(pieceId, state.prize.active_round);
|
||||
}
|
||||
},
|
||||
|
||||
onRatingClick(event, args) {
|
||||
event.preventDefault();
|
||||
PrizeRatingActions
|
||||
.createRating(this.props.piece.id, args.rating, this.state.prize.active_round)
|
||||
.then(this.refreshPieceData);
|
||||
},
|
||||
|
||||
getSelectedActionButton() {
|
||||
const { currentUser, piece, selectedPrizeActionButton: SelectedPrizeActionButton } = this.props;
|
||||
|
||||
if (piece.selected && SelectedPrizeActionButton) {
|
||||
return (
|
||||
<span className="pull-right">
|
||||
<SelectedPrizeActionButton
|
||||
piece={piece}
|
||||
currentUser={currentUser} />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
refreshPieceData() {
|
||||
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||
|
||||
this.props.loadPiece();
|
||||
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||
},
|
||||
|
||||
onSelectChange() {
|
||||
PrizeRatingActions
|
||||
.toggleShortlist(this.props.piece.id)
|
||||
.then((res) => {
|
||||
this.refreshPieceData();
|
||||
|
||||
if (res && res.notification) {
|
||||
const notification = new GlobalNotificationModel(res.notification, 'success', 2000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
if (this.props.piece.id && this.props.currentUser.is_judge && this.state.average) {
|
||||
// Judge sees shortlisting, average and per-jury notes
|
||||
return (
|
||||
<div>
|
||||
<CollapsibleParagraph
|
||||
title={getLangText('Shortlisting')}
|
||||
defaultExpanded={true}>
|
||||
<div className="row no-margin">
|
||||
<span className="ascribe-checkbox-wrapper" style={{marginLeft: '1.5em'}}>
|
||||
<InputCheckbox
|
||||
defaultChecked={this.props.piece.selected}
|
||||
onChange={this.onSelectChange}>
|
||||
<span>
|
||||
{getLangText('Select for the prize')}
|
||||
</span>
|
||||
</InputCheckbox>
|
||||
</span>
|
||||
{this.getSelectedActionButton()}
|
||||
</div>
|
||||
<hr />
|
||||
</CollapsibleParagraph>
|
||||
<CollapsibleParagraph
|
||||
title={getLangText('Average Rating')}
|
||||
defaultExpanded={true}>
|
||||
<div id="list-rating" style={{marginLeft: '1.5em', marginBottom: '1em'}}>
|
||||
<StarRating
|
||||
ref='average-rating'
|
||||
name="average-rating"
|
||||
caption=""
|
||||
size='md'
|
||||
step={0.5}
|
||||
rating={this.state.average}
|
||||
ratingAmount={5} />
|
||||
</div>
|
||||
<hr />
|
||||
{this.state.ratings.map((item, i) => {
|
||||
let note = item.note ? (
|
||||
<div className="rating-note">
|
||||
note: {item.note}
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={item.user}
|
||||
className="rating-list">
|
||||
<div
|
||||
id="list-rating"
|
||||
className="row no-margin">
|
||||
<span className="pull-right">
|
||||
<StarRating
|
||||
ref={'rating' + i}
|
||||
name={'rating' + i}
|
||||
caption=""
|
||||
size='sm'
|
||||
step={0.5}
|
||||
rating={item.rating}
|
||||
ratingAmount={5} />
|
||||
</span>
|
||||
<span> {item.user}</span>
|
||||
{note}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
<hr />
|
||||
</CollapsibleParagraph>
|
||||
</div>);
|
||||
} else if (this.props.currentUser.is_jury) {
|
||||
// Jury can set rating and note
|
||||
return (
|
||||
<CollapsibleParagraph
|
||||
title={getLangText('Rating')}
|
||||
defaultExpanded={true}>
|
||||
<div style={{marginLeft: '1.5em', marginBottom: '1em'}}>
|
||||
<StarRating
|
||||
ref='rating'
|
||||
name="prize-rating"
|
||||
caption=""
|
||||
step={1}
|
||||
size='md'
|
||||
rating={this.state.currentRating}
|
||||
onRatingClick={this.onRatingClick}
|
||||
ratingAmount={5} />
|
||||
</div>
|
||||
<Note
|
||||
id={() => ({ 'piece_id': this.props.piece.id })}
|
||||
label={getLangText('Jury note')}
|
||||
defaultValue={this.props.piece.note_from_user || null}
|
||||
placeholder={getLangText('Enter your comments ...')}
|
||||
editable={true}
|
||||
successMessage={getLangText('Jury note saved')}
|
||||
url={ApiUrls.notes}
|
||||
currentUser={this.props.currentUser} />
|
||||
</CollapsibleParagraph>);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let PrizePieceDetails = React.createClass({
|
||||
propTypes: {
|
||||
piece: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
render() {
|
||||
const { piece } = this.props;
|
||||
|
||||
if (piece.prize && piece.prize.name && Object.keys(piece.extra_data).length) {
|
||||
return (
|
||||
<CollapsibleParagraph
|
||||
title={getLangText('Prize Details')}
|
||||
defaultExpanded={true}>
|
||||
<Form>
|
||||
{Object
|
||||
.keys(piece.extra_data)
|
||||
.sort()
|
||||
.map((data) => {
|
||||
// Remove leading number (for sorting), if any, and underscores with spaces
|
||||
const label = data.replace(/^\d-/, '').replace(/_/g, ' ');
|
||||
const value = piece.extra_data[data] || 'N/A';
|
||||
|
||||
return (
|
||||
<Property
|
||||
key={label}
|
||||
name={data}
|
||||
label={label}
|
||||
editable={false}
|
||||
overrideForm={true}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
defaultValue={value} />
|
||||
</Property>
|
||||
);
|
||||
})
|
||||
}
|
||||
<FurtherDetailsFileuploader
|
||||
submitFile={() => {}}
|
||||
setIsUploadReady={() => {}}
|
||||
isReadyForFormSubmission={() => {}}
|
||||
editable={false}
|
||||
overrideForm={true}
|
||||
pieceId={piece.id}
|
||||
otherData={piece.other_data}
|
||||
multiple={true} />
|
||||
</Form>
|
||||
</CollapsibleParagraph>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default PrizePieceContainer;
|
@ -1,20 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import constants from '../../../../../constants/application_constants';
|
||||
|
||||
|
||||
let Hero = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<div className="hero">
|
||||
<img
|
||||
className="logo" src={constants.whitelabel.logo}
|
||||
alt="Sluice Art Prize"
|
||||
height="200px"/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default Hero;
|
@ -1,111 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Button from 'react-bootstrap/lib/Button';
|
||||
import ButtonGroup from 'react-bootstrap/lib/ButtonGroup';
|
||||
|
||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||
|
||||
import PrizeActions from '../actions/prize_actions';
|
||||
import PrizeStore from '../stores/prize_store';
|
||||
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
|
||||
|
||||
let Landing = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
// Provided from router
|
||||
location: React.PropTypes.object
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return PrizeStore.getState();
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
PrizeStore.listen(this.onChange);
|
||||
PrizeActions.fetchPrize();
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PrizeStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
getButtons() {
|
||||
if (this.state.prize && this.state.prize.active) {
|
||||
return (
|
||||
<ButtonGroup className="enter" bsSize="large" vertical>
|
||||
<LinkContainer to="/signup">
|
||||
<Button>
|
||||
{getLangText('Sign up to submit')}
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
|
||||
<p>
|
||||
{getLangText('or, already an ascribe user?')}
|
||||
</p>
|
||||
<LinkContainer to="/login">
|
||||
<Button>
|
||||
{getLangText('Log in to submit')}
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
</ButtonGroup>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<ButtonGroup className="enter" bsSize="large" vertical>
|
||||
<a className="btn btn-default" href="https://www.ascribe.io/app/signup">
|
||||
{getLangText('Sign up to ascribe')}
|
||||
</a>
|
||||
|
||||
<p>
|
||||
{getLangText('or, already an ascribe user?')}
|
||||
</p>
|
||||
<LinkContainer to="/login">
|
||||
<Button>
|
||||
{getLangText('Log in')}
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
</ButtonGroup>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
getTitle() {
|
||||
const { prize } = this.state;
|
||||
|
||||
return (
|
||||
<p>
|
||||
{getLangText(prize && prize.active ? 'This is the submission page for Sluice_screens ↄc Prize 2015.'
|
||||
: 'Submissions for Sluice_screens ↄc Prize 2015 are now closed.')}
|
||||
</p>
|
||||
);
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col-xs-12 wp-landing-wrapper">
|
||||
<h1>
|
||||
{getLangText('Sluice_screens ↄc Prize 2015')}
|
||||
</h1>
|
||||
{this.getTitle()}
|
||||
{this.getButtons()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default Landing;
|
@ -1,45 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
import LoginForm from '../../../../ascribe_forms/form_login';
|
||||
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
|
||||
let LoginContainer = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
// Provided from router
|
||||
location: React.PropTypes.object
|
||||
},
|
||||
|
||||
render() {
|
||||
setDocumentTitle(getLangText('Log in'));
|
||||
|
||||
return (
|
||||
<div className="ascribe-login-wrapper">
|
||||
<LoginForm
|
||||
headerMessage={getLangText('Log in with ascribe')}
|
||||
location={this.props.location} />
|
||||
<div className="ascribe-login-text">
|
||||
{getLangText('I\'m not a user') + ' '}
|
||||
<Link to="/signup">{getLangText('Sign up...')}</Link>
|
||||
<br />
|
||||
|
||||
{getLangText('I forgot my password') + ' '}
|
||||
<Link to="/password_reset">{getLangText('Rescue me...')}</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
export default LoginContainer;
|
@ -1,94 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Button from 'react-bootstrap/lib/Button';
|
||||
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
|
||||
|
||||
import PrizeActions from '../actions/prize_actions';
|
||||
import PrizeStore from '../stores/prize_store';
|
||||
|
||||
import AccordionListItemPrize from './ascribe_accordion_list/accordion_list_item_prize';
|
||||
import PieceList from '../../../../piece_list';
|
||||
|
||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
let PrizePieceList = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
// Provided from router
|
||||
location: React.PropTypes.object
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return PrizeStore.getState();
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
PrizeStore.listen(this.onChange);
|
||||
PrizeActions.fetchPrize();
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PrizeStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
getButtonSubmit() {
|
||||
const { currentUser } = this.props;
|
||||
const { prize } = this.state;
|
||||
if (prize && prize.active && !currentUser.is_jury && !currentUser.is_admin && !currentUser.is_judge) {
|
||||
return (
|
||||
<LinkContainer to="/register_piece">
|
||||
<Button>
|
||||
{getLangText('Submit to prize')}
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
shouldRedirect(pieceCount) {
|
||||
const { currentUser } = this.props;
|
||||
|
||||
return !currentUser.is_admin && !currentUser.is_jury && !currentUser.is_judge && !pieceCount;
|
||||
},
|
||||
|
||||
render() {
|
||||
const { currentUser, location } = this.props;
|
||||
|
||||
setDocumentTitle(getLangText('Collection'));
|
||||
|
||||
let orderParams = ['artist_name', 'title'];
|
||||
if (currentUser.is_jury) {
|
||||
orderParams = ['rating', 'title'];
|
||||
}
|
||||
if (currentUser.is_judge) {
|
||||
orderParams = ['rating', 'title', 'selected'];
|
||||
}
|
||||
|
||||
return (
|
||||
<PieceList
|
||||
ref="list"
|
||||
{...this.props}
|
||||
accordionListItemType={AccordionListItemPrize}
|
||||
customSubmitButton={this.getButtonSubmit()}
|
||||
filterParams={[]}
|
||||
orderParams={orderParams}
|
||||
orderBy={currentUser.is_jury ? 'rating' : null}
|
||||
shouldRedirect={this.shouldRedirect} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default PrizePieceList;
|
@ -1,102 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import PrizeActions from '../actions/prize_actions';
|
||||
import PrizeStore from '../stores/prize_store';
|
||||
|
||||
import RegisterPiece from '../../../../register_piece';
|
||||
import Property from '../../../../ascribe_forms/property';
|
||||
import InputTextAreaToggable from '../../../../ascribe_forms/input_textarea_toggable';
|
||||
import InputCheckbox from '../../../../ascribe_forms/input_checkbox';
|
||||
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
|
||||
let PrizeRegisterPiece = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
// Provided from router
|
||||
location: React.PropTypes.object
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return PrizeStore.getState();
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
PrizeStore.listen(this.onChange);
|
||||
PrizeActions.fetchPrize();
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PrizeStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
render() {
|
||||
const { prize } = this.state;
|
||||
|
||||
setDocumentTitle(getLangText('Submit to the prize'));
|
||||
|
||||
if (prize && prize.active) {
|
||||
return (
|
||||
<RegisterPiece
|
||||
{...this.props}
|
||||
enableLocalHashing={false}
|
||||
headerMessage={''}
|
||||
submitMessage={getLangText('Submit')}>
|
||||
<Property
|
||||
name='artist_statement'
|
||||
label={getLangText('Artist statement')}
|
||||
editable={true}
|
||||
overrideForm={true}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('Enter your statement')}
|
||||
required />
|
||||
</Property>
|
||||
<Property
|
||||
name='work_description'
|
||||
label={getLangText('Work description')}
|
||||
editable={true}
|
||||
overrideForm={true}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('Enter the description for your work')}
|
||||
required />
|
||||
</Property>
|
||||
<Property
|
||||
name="terms"
|
||||
className="ascribe-property-collapsible-toggle">
|
||||
<InputCheckbox>
|
||||
<span>
|
||||
{' ' + getLangText('I agree to the Terms of Service the art price') + ' '}
|
||||
(<a href="https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/sluice/terms.pdf" target="_blank" style={{fontSize: '0.9em', color: 'rgba(0,0,0,0.7)'}}>
|
||||
{getLangText('read')}
|
||||
</a>)
|
||||
</span>
|
||||
</InputCheckbox>
|
||||
</Property>
|
||||
</RegisterPiece>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className='row'>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
{getLangText('The prize is no longer active')}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default PrizeRegisterPiece;
|
@ -1,302 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
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 '../../../../ascribe_settings/settings_container';
|
||||
import CollapsibleParagraph from '../../../../ascribe_collapsible/collapsible_paragraph';
|
||||
|
||||
import Form from '../../../../ascribe_forms/form';
|
||||
import Property from '../../../../ascribe_forms/property';
|
||||
|
||||
import ActionPanel from '../../../../ascribe_panel/action_panel';
|
||||
|
||||
import GlobalNotificationModel from '../../../../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
|
||||
|
||||
import AscribeSpinner from '../../../../ascribe_spinner';
|
||||
import ApiUrls from '../../../../../constants/api_urls';
|
||||
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
|
||||
let Settings = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
// Provided from router
|
||||
location: React.PropTypes.object
|
||||
},
|
||||
|
||||
render() {
|
||||
setDocumentTitle(getLangText('Account settings'));
|
||||
|
||||
return (
|
||||
<SettingsContainer {...this.props}>
|
||||
{this.props.currentUser.is_admin ? <PrizeSettings /> : null}
|
||||
</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={getLangText('Prize Settings for ') + this.state.prize.name}
|
||||
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();
|
||||
this.displayNotification(response);
|
||||
this.refs.form.refs.email.refs.input.getDOMNode().value = null;
|
||||
},
|
||||
|
||||
handleActivate(event) {
|
||||
let email = event.target.getAttribute('data-id');
|
||||
PrizeJuryActions
|
||||
.activateJury(email)
|
||||
.then((response) => {
|
||||
PrizeJuryActions.fetchJury();
|
||||
this.displayNotification(response);
|
||||
});
|
||||
},
|
||||
|
||||
handleRevoke(event) {
|
||||
let email = event.target.getAttribute('data-id');
|
||||
PrizeJuryActions
|
||||
.revokeJury(email)
|
||||
.then(this.displayNotification);
|
||||
},
|
||||
|
||||
handleResend(event) {
|
||||
let email = event.target.getAttribute('data-id');
|
||||
PrizeJuryActions
|
||||
.resendJuryInvitation(email)
|
||||
.then(this.displayNotification);
|
||||
},
|
||||
|
||||
displayNotification(response) {
|
||||
let notification = new GlobalNotificationModel(response.notification, 'success', 5000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
},
|
||||
|
||||
getMembersPending() {
|
||||
return this.state.membersPending.map(function(member, i) {
|
||||
return (
|
||||
<ActionPanel
|
||||
name={member.email}
|
||||
key={i}
|
||||
content={
|
||||
<div>
|
||||
<div className='ascribe-panel-title'>
|
||||
{member.email}
|
||||
</div>
|
||||
<div className="ascribe-panel-subtitle">
|
||||
{member.status}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
buttons={
|
||||
<div className="pull-right">
|
||||
<button
|
||||
className="btn btn-default btn-sm margin-left-2px"
|
||||
onClick={this.handleResend}
|
||||
data-id={member.email}>
|
||||
{getLangText('RESEND')}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-warning btn-sm margin-left-2px"
|
||||
onClick={this.handleRevoke}
|
||||
data-id={member.email}>
|
||||
{getLangText('REVOKE')}
|
||||
</button>
|
||||
</div>
|
||||
}/>
|
||||
);
|
||||
}, this);
|
||||
},
|
||||
getMembersActive() {
|
||||
return this.state.membersActive.map(function(member, i) {
|
||||
return (
|
||||
<ActionPanel
|
||||
name={member.email}
|
||||
key={i}
|
||||
content={
|
||||
<div>
|
||||
<div className='ascribe-panel-title'>
|
||||
{member.email}
|
||||
</div>
|
||||
<div className="ascribe-panel-subtitle">
|
||||
{member.status}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
buttons={
|
||||
<button
|
||||
className="btn btn-warning btn-sm"
|
||||
onClick={this.handleRevoke}
|
||||
data-id={member.email}>
|
||||
{getLangText('REVOKE')}
|
||||
</button>
|
||||
}/>
|
||||
);
|
||||
|
||||
}, this);
|
||||
},
|
||||
getMembersInactive() {
|
||||
return this.state.membersInactive.map(function(member, i) {
|
||||
return (
|
||||
<ActionPanel
|
||||
name={member.email}
|
||||
key={i}
|
||||
content={
|
||||
<div>
|
||||
<div className='ascribe-panel-title'>
|
||||
{member.email}
|
||||
</div>
|
||||
<div className="ascribe-panel-subtitle">
|
||||
{member.status}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
buttons={
|
||||
<button
|
||||
className="btn btn-default btn-sm"
|
||||
onClick={this.handleActivate}
|
||||
data-id={member.email}>
|
||||
{getLangText('ACTIVATE')}
|
||||
</button>
|
||||
}/>
|
||||
);
|
||||
|
||||
}, this);
|
||||
},
|
||||
|
||||
getMembers() {
|
||||
let content = <AscribeSpinner color='dark-blue' size='md' />;
|
||||
if (this.state.members.length > -1) {
|
||||
content = (
|
||||
<div>
|
||||
<CollapsibleParagraph
|
||||
title={getLangText('Active Jury Members')}
|
||||
defaultExpanded={true}>
|
||||
{this.getMembersActive()}
|
||||
</CollapsibleParagraph>
|
||||
<CollapsibleParagraph
|
||||
title={getLangText('Pending Jury Invitations')}
|
||||
defaultExpanded={true}>
|
||||
{this.getMembersPending()}
|
||||
</CollapsibleParagraph>
|
||||
<CollapsibleParagraph
|
||||
title={getLangText('Deactivated Jury Members')}
|
||||
defaultExpanded={false}>
|
||||
{this.getMembersInactive()}
|
||||
</CollapsibleParagraph>
|
||||
</div>);
|
||||
}
|
||||
return content;
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Form
|
||||
url={ApiUrls.jurys}
|
||||
handleSuccess={this.handleCreateSuccess}
|
||||
ref='form'
|
||||
buttonSubmitText={getLangText('INVITE')}>
|
||||
<div className="ascribe-form-header">
|
||||
<h4 style={{margin: '30px 0px 10px 10px'}}>
|
||||
{getLangText('Jury Members')}
|
||||
</h4>
|
||||
</div>
|
||||
<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>
|
||||
{this.getMembers()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export default Settings;
|
@ -1,61 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import SignupForm from '../../../../ascribe_forms/form_signup';
|
||||
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
let SignupContainer = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
// Provided from router
|
||||
location: React.PropTypes.object
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
submitted: false,
|
||||
message: null
|
||||
};
|
||||
},
|
||||
|
||||
handleSuccess(message) {
|
||||
this.setState({
|
||||
submitted: true,
|
||||
message: message
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
const { location } = this.props;
|
||||
const { message, submitted } = this.state;
|
||||
setDocumentTitle(getLangText('Sign up'));
|
||||
|
||||
if (submitted) {
|
||||
return (
|
||||
<div className="ascribe-login-wrapper">
|
||||
<div className="ascribe-login-text ascribe-login-header">
|
||||
{message}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="ascribe-login-wrapper">
|
||||
<SignupForm
|
||||
headerMessage={getLangText('Create account for submission')}
|
||||
submitMessage={getLangText('Sign up')}
|
||||
handleSuccess={this.handleSuccess}
|
||||
location={location} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export default SignupContainer;
|
@ -1,12 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import requests from '../../../../../utils/requests';
|
||||
|
||||
|
||||
let PrizeFetcher = {
|
||||
fetch() {
|
||||
return requests.get('prize');
|
||||
}
|
||||
};
|
||||
|
||||
export default PrizeFetcher;
|
@ -1,24 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import requests from '../../../../../utils/requests';
|
||||
|
||||
|
||||
let PrizeJuryFetcher = {
|
||||
fetch() {
|
||||
return requests.get('jurys');
|
||||
},
|
||||
|
||||
activate(email) {
|
||||
return requests.post('jury_activate', {'email': email});
|
||||
},
|
||||
|
||||
delete(email) {
|
||||
return requests.delete('jury', {'email': email});
|
||||
},
|
||||
|
||||
resend(email) {
|
||||
return requests.post('jury_resend', {'email': email});
|
||||
}
|
||||
};
|
||||
|
||||
export default PrizeJuryFetcher;
|
@ -1,49 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import requests from '../../../../../utils/requests';
|
||||
|
||||
|
||||
let PrizeRatingFetcher = {
|
||||
fetchAverage(pieceId, round) {
|
||||
const params = {
|
||||
'piece_id': pieceId
|
||||
};
|
||||
|
||||
if (typeof round === 'number') {
|
||||
params['prize_round'] = round;
|
||||
}
|
||||
|
||||
return requests.get('rating_average', params);
|
||||
},
|
||||
|
||||
fetchOne(pieceId, round) {
|
||||
const params = {
|
||||
'piece_id': pieceId
|
||||
};
|
||||
|
||||
if (typeof round === 'number') {
|
||||
params['prize_round'] = round;
|
||||
}
|
||||
|
||||
return requests.get('rating', params);
|
||||
},
|
||||
|
||||
rate(pieceId, rating, round) {
|
||||
const body = {
|
||||
'piece_id': pieceId,
|
||||
'note': rating
|
||||
};
|
||||
|
||||
if (typeof round === 'number') {
|
||||
body['prize_round'] = round;
|
||||
}
|
||||
|
||||
return requests.post('ratings', { body });
|
||||
},
|
||||
|
||||
select(pieceId) {
|
||||
return requests.post('select_piece', {'piece_id': pieceId});
|
||||
}
|
||||
};
|
||||
|
||||
export default PrizeRatingFetcher;
|
@ -1,61 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import Hero from './components/prize_hero';
|
||||
|
||||
import AppBase from '../../../app_base';
|
||||
import AppRouteWrapper from '../../../app_route_wrapper';
|
||||
import Header from '../../../header';
|
||||
|
||||
import { getSubdomain } from '../../../../utils/general_utils';
|
||||
|
||||
|
||||
let PrizeApp = React.createClass({
|
||||
propTypes: {
|
||||
activeRoute: React.PropTypes.object.isRequired,
|
||||
children: React.PropTypes.element.isRequired,
|
||||
history: React.PropTypes.object.isRequired,
|
||||
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
|
||||
|
||||
// Provided from AppBase
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object
|
||||
},
|
||||
|
||||
render() {
|
||||
const { activeRoute, children, currentUser, history, routes, whitelabel } = this.props;
|
||||
const subdomain = getSubdomain();
|
||||
const path = activeRoute && activeRoute.path;
|
||||
const Footer = activeRoute && activeRoute.footer;
|
||||
|
||||
let header = null;
|
||||
// if the path of the current activeRoute is not defined, then this is the IndexRoute
|
||||
if (!path || history.isActive('/login') || history.isActive('/signup')) {
|
||||
header = (<Hero />);
|
||||
} else {
|
||||
header = (
|
||||
<Header
|
||||
currentUser={currentUser}
|
||||
routes={routes}
|
||||
whitelabel={whitelabel} />
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames('ascribe-app', 'ascribe-prize-app', `route--${(path ? path.split('/')[0] : 'landing')}`)}>
|
||||
{header}
|
||||
<AppRouteWrapper
|
||||
currentUser={currentUser}
|
||||
whitelabel={whitelabel}>
|
||||
{/* Routes are injected here */}
|
||||
{children}
|
||||
</AppRouteWrapper>
|
||||
{Footer ? <Footer /> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default AppBase(PrizeApp);
|
@ -1,35 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import { alt } from '../../../../../alt';
|
||||
|
||||
import PrizeJuryActions from '../actions/prize_jury_actions';
|
||||
|
||||
class PrizeJuryStore {
|
||||
constructor() {
|
||||
this.members = [];
|
||||
this.membersActive = [];
|
||||
this.membersPending = [];
|
||||
this.membersInactive = [];
|
||||
this.bindActions(PrizeJuryActions);
|
||||
}
|
||||
|
||||
onUpdatePrizeJury( members ) {
|
||||
this.members = members;
|
||||
this.splitJuryMembers();
|
||||
}
|
||||
|
||||
onRemovePrizeJury( email ) {
|
||||
let memberInactive = this.members.filter((item)=> item.email === email );
|
||||
this.membersActive = this.membersActive.filter((item)=> item.email !== email );
|
||||
this.membersPending = this.membersPending.filter((item)=> item.email !== email );
|
||||
this.membersInactive = this.membersInactive.concat(memberInactive);
|
||||
}
|
||||
|
||||
splitJuryMembers(){
|
||||
this.membersActive = this.members.filter((item)=> item.status === 'Invitation accepted' );
|
||||
this.membersPending = this.members.filter((item)=> item.status === 'Invitation pending' );
|
||||
this.membersInactive = this.members.filter((item)=> item.status === 'Deactivated' );
|
||||
}
|
||||
}
|
||||
|
||||
export default alt.createStore(PrizeJuryStore, 'PrizeJuryStore');
|
@ -1,47 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import { alt } from '../../../../../alt';
|
||||
|
||||
import PrizeRatingActions from '../actions/prize_rating_actions';
|
||||
|
||||
class PrizeRatingStore {
|
||||
constructor() {
|
||||
this.getInitialState();
|
||||
|
||||
this.bindActions(PrizeRatingActions);
|
||||
this.exportPublicMethods({
|
||||
getInitialState: this.getInitialState.bind(this)
|
||||
});
|
||||
}
|
||||
|
||||
getInitialState() {
|
||||
this.ratings = [];
|
||||
this.currentRating = null;
|
||||
this.average = null;
|
||||
|
||||
return {
|
||||
ratings: this.ratings,
|
||||
currentRating: this.currentRating,
|
||||
average: this.average
|
||||
};
|
||||
}
|
||||
|
||||
onUpdatePrizeRatings(ratings) {
|
||||
this.ratings = ratings;
|
||||
}
|
||||
|
||||
onUpdatePrizeRating(rating) {
|
||||
this.currentRating = parseInt(rating, 10);
|
||||
}
|
||||
|
||||
onUpdatePrizeRatingAverage(data) {
|
||||
this.average = data.average;
|
||||
this.ratings = data.ratings;
|
||||
}
|
||||
|
||||
onResetPrizeRatings() {
|
||||
this.getInitialState();
|
||||
}
|
||||
}
|
||||
|
||||
export default alt.createStore(PrizeRatingStore, 'PrizeRatingStore');
|
@ -1,18 +0,0 @@
|
||||
'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');
|
@ -1,71 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import Moment from 'moment';
|
||||
|
||||
import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper';
|
||||
|
||||
import LoanForm from '../../../../../ascribe_forms/form_loan';
|
||||
|
||||
import GlobalNotificationModel from '../../../../../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
|
||||
|
||||
import ApiUrls from '../../../../../../constants/api_urls';
|
||||
|
||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||
|
||||
const SluiceSelectedPrizeActionButton = React.createClass({
|
||||
propTypes: {
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
piece: React.PropTypes.object.isRequired,
|
||||
|
||||
startLoanDate: React.PropTypes.object,
|
||||
endLoanDate: React.PropTypes.object,
|
||||
className: React.PropTypes.string,
|
||||
handleSuccess: React.PropTypes.func
|
||||
},
|
||||
|
||||
handleSuccess(res) {
|
||||
const notification = new GlobalNotificationModel(res && res.notification || getLangText('You have successfully requested the loan, pending their confirmation.'), 'success', 4000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
|
||||
if (typeof this.props.handleSuccess === 'function') {
|
||||
this.props.handleSuccess(res);
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
const { currentUser, piece } = this.props;
|
||||
|
||||
// Can't use default props since those are only created once
|
||||
const startLoanDate = this.props.startLoanDate || new Moment();
|
||||
const endLoanDate = this.props.endLoanDate || new Moment().add(6, 'months');
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
trigger={
|
||||
<button className='btn btn-default btn-sm'>
|
||||
{getLangText('SEND LOAN REQUEST')}
|
||||
</button>
|
||||
}
|
||||
handleSuccess={this.handleSuccess}
|
||||
title={getLangText('REQUEST LOAN')}>
|
||||
<LoanForm
|
||||
loanHeading={null}
|
||||
message={getLangText('Congratulations,\nYou have been selected for the prize.\n' +
|
||||
'Please accept the loan request to proceed.')}
|
||||
id={{ piece_id: piece.id }}
|
||||
url={ApiUrls.ownership_loans_pieces_request}
|
||||
email={currentUser.email}
|
||||
gallery={piece.prize.name}
|
||||
startDate={startLoanDate}
|
||||
endDate={endLoanDate}
|
||||
showPersonalMessage={true}
|
||||
showPassword={false} />
|
||||
</ModalWrapper>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default SluiceSelectedPrizeActionButton;
|
||||
|
@ -1,29 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import SluiceSelectedPrizeActionButton from '../sluice_buttons/sluice_selected_prize_action_button';
|
||||
|
||||
import PrizePieceContainer from '../../../simple_prize/components/ascribe_detail/prize_piece_container';
|
||||
|
||||
const SluicePieceContainer = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
// Provided from router
|
||||
location: React.PropTypes.object,
|
||||
params: React.PropTypes.object
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<PrizePieceContainer
|
||||
{...this.props}
|
||||
selectedPrizeActionButton={SluiceSelectedPrizeActionButton} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default SluicePieceContainer;
|
@ -8,7 +8,7 @@ import MarketPieceList from '../market/market_piece_list';
|
||||
|
||||
let Vivi23PieceList = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
|
@ -11,7 +11,7 @@ import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
let ArtcityLanding = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
@ -31,7 +31,7 @@ import { mergeOptions } from '../../../../../../utils/general_utils';
|
||||
|
||||
let CylandPieceContainer = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
let CylandLanding = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object.isRequired,
|
||||
|
||||
|
@ -10,7 +10,7 @@ import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
let CylandPieceList = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object.isRequired,
|
||||
|
||||
|
@ -36,7 +36,7 @@ import { getAclFormMessage } from '../../../../../utils/form_utils';
|
||||
|
||||
let CylandRegisterPiece = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object.isRequired,
|
||||
|
||||
|
@ -25,7 +25,7 @@ import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
let IkonotvContractNotifications = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object.isRequired,
|
||||
|
||||
|
@ -32,7 +32,7 @@ import { mergeOptions } from '../../../../../../utils/general_utils';
|
||||
|
||||
let IkonotvPieceContainer = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
|
@ -12,7 +12,7 @@ import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
let IkonotvLanding = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object,
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { getLangText } from '../../../../../utils/lang_utils';
|
||||
|
||||
let IkonotvPieceList = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object.isRequired,
|
||||
|
||||
|
@ -34,7 +34,7 @@ let IkonotvRegisterPiece = React.createClass({
|
||||
propTypes: {
|
||||
handleSuccess: React.PropTypes.func,
|
||||
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object.isRequired,
|
||||
|
||||
|
@ -11,7 +11,7 @@ import { setDocumentTitle } from '../../../../../utils/dom_utils';
|
||||
|
||||
let LumenusLanding = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object.isRequired,
|
||||
|
||||
|
@ -14,7 +14,7 @@ let MarketPieceList = React.createClass({
|
||||
propTypes: {
|
||||
customThumbnailPlaceholder: React.PropTypes.func,
|
||||
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object.isRequired,
|
||||
whitelabel: React.PropTypes.object.isRequired,
|
||||
|
||||
|
@ -25,7 +25,7 @@ import { mergeOptions } from '../../../../../utils/general_utils';
|
||||
|
||||
let MarketRegisterPiece = React.createClass({
|
||||
propTypes: {
|
||||
// Provided from PrizeApp
|
||||
// Provided from WalletApp
|
||||
currentUser: React.PropTypes.object,
|
||||
whitelabel: React.PropTypes.object.isRequired,
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
import AppConstants from './application_constants';
|
||||
|
||||
import getPrizeApiUrls from '../components/whitelabel/prize/constants/prize_api_urls';
|
||||
import getWalletApiUrls from '../components/whitelabel/wallet/constants/wallet_api_urls';
|
||||
|
||||
import { update } from '../utils/general_utils';
|
||||
@ -81,14 +80,9 @@ let ApiUrls = {
|
||||
|
||||
|
||||
export function updateApiUrls(type, subdomain) {
|
||||
let newUrls = {};
|
||||
|
||||
if (type === 'prize') {
|
||||
newUrls = getPrizeApiUrls(subdomain);
|
||||
} else if(type === 'wallet') {
|
||||
newUrls = getWalletApiUrls(subdomain);
|
||||
if (type === 'wallet') {
|
||||
update(getWalletApiUrls(subdomain));
|
||||
}
|
||||
update(ApiUrls, newUrls);
|
||||
}
|
||||
|
||||
export default ApiUrls;
|
||||
|
@ -27,12 +27,6 @@ const constants = {
|
||||
'type': 'wallet',
|
||||
'ga': 'UA-60614729-4'
|
||||
},
|
||||
{
|
||||
'subdomain': 'sluice',
|
||||
'name': 'Sluice Art Fair',
|
||||
'type': 'prize',
|
||||
'ga': 'UA-60614729-5'
|
||||
},
|
||||
{
|
||||
'subdomain': 'cyland',
|
||||
'name': 'Cyland media art lab',
|
||||
@ -72,11 +66,6 @@ const constants = {
|
||||
'subdomain': 'liquidgallery',
|
||||
'name': 'Liquid Gallery',
|
||||
'type': 'wallet'
|
||||
},
|
||||
{
|
||||
'subdomain': 'portfolioreview',
|
||||
'name': 'Portfolio Review',
|
||||
'type': 'prize'
|
||||
}
|
||||
],
|
||||
'defaultDomain': {
|
||||
|
@ -3,7 +3,6 @@
|
||||
import React from 'react';
|
||||
import { Route } from 'react-router';
|
||||
|
||||
import getPrizeRoutes from './components/whitelabel/prize/prize_routes';
|
||||
import getWalletRoutes from './components/whitelabel/wallet/wallet_routes';
|
||||
|
||||
import AscribeApp from './components/ascribe_app';
|
||||
@ -82,9 +81,7 @@ const COMMON_ROUTES = (
|
||||
|
||||
|
||||
function getRoutes(type, subdomain) {
|
||||
if (type === 'prize') {
|
||||
return getPrizeRoutes(COMMON_ROUTES, subdomain);
|
||||
} else if(type === 'wallet') {
|
||||
if (type === 'wallet') {
|
||||
return getWalletRoutes(COMMON_ROUTES, subdomain);
|
||||
} else {
|
||||
return COMMON_ROUTES;
|
||||
|
Loading…
Reference in New Issue
Block a user