mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 09:23:13 +01:00
Finalizing basic submission flow with lazy evaluated form
This commit is contained in:
parent
deceb61c60
commit
9ae6b10add
@ -2,6 +2,7 @@
|
||||
|
||||
import AppPrizeConstants from './prize_application_constants';
|
||||
|
||||
|
||||
function getPrizeApiUrls(subdomain) {
|
||||
return {
|
||||
'users_login': AppPrizeConstants.prizeApiEndpoint + subdomain + '/users/login/',
|
||||
@ -21,7 +22,6 @@ function getPrizeApiUrls(subdomain) {
|
||||
'select_piece': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/select/',
|
||||
'notes': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/',
|
||||
'note': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/${piece_id}/'
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -5,30 +5,107 @@ import React from 'react';
|
||||
import Form from '../../../../../ascribe_forms/form';
|
||||
import Property from '../../../../../ascribe_forms/property';
|
||||
import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_toggable';
|
||||
import InputCheckbox from '../../../../../ascribe_forms/input_checkbox';
|
||||
|
||||
import UploadFileButton from '../../../../../ascribe_buttons/upload_file_button';
|
||||
|
||||
import GlobalNotificationModel from '../../../../../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
|
||||
|
||||
import AppConstants from '../../../../../../constants/application_constants';
|
||||
import ApiUrls from '../../../../../../constants/api_urls';
|
||||
|
||||
import requests from '../../../../../../utils/requests';
|
||||
|
||||
import { getLangText } from '../../../../../../utils/lang_utils';
|
||||
import { setCookie } from '../../../../../../utils/fetch_api_utils';
|
||||
|
||||
|
||||
const { object } = React.PropTypes;
|
||||
|
||||
const PRRegisterPieceForm = React.createClass({
|
||||
propTypes: {
|
||||
location: object
|
||||
location: object,
|
||||
history: object,
|
||||
currentUser: object
|
||||
},
|
||||
|
||||
getInitialState(){
|
||||
return {
|
||||
isUploadReady: false
|
||||
isUploadReady: false,
|
||||
piece: null
|
||||
};
|
||||
},
|
||||
|
||||
handleSuccess() {
|
||||
/**
|
||||
* 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() {
|
||||
const { currentUser } = this.props;
|
||||
const { registerPieceForm,
|
||||
digitalWorkForm,
|
||||
proofOfPaymentForm,
|
||||
supportingMaterialsForm,
|
||||
additionalDataForm } = this.refs;
|
||||
const additionalDataFormData = additionalDataForm.getFormData();
|
||||
|
||||
// composing data for piece registration
|
||||
let registerPieceFormData = registerPieceForm.getFormData();
|
||||
registerPieceFormData.digital_work_key = digitalWorkForm.state.file ? digitalWorkForm.state.file.key : '';
|
||||
registerPieceFormData.terms = true;
|
||||
|
||||
// submitting the piece
|
||||
requests
|
||||
.post(ApiUrls.pieces_list, { body: registerPieceFormData })
|
||||
.then(({ success, piece, notification }) => {
|
||||
if(success) {
|
||||
this.setState({
|
||||
piece
|
||||
}, () => {
|
||||
supportingMaterialsForm.createBlobRoutine();
|
||||
proofOfPaymentForm.createBlobRoutine();
|
||||
//thumbnailForm.createBlobRoutine();
|
||||
});
|
||||
|
||||
setCookie(currentUser.email, piece.id);
|
||||
|
||||
return requests.post(ApiUrls.piece_extradata, {
|
||||
body: {
|
||||
extradata: additionalDataFormData,
|
||||
piece_id: piece.id
|
||||
},
|
||||
piece_id: piece.id
|
||||
});
|
||||
} else {
|
||||
const notificationMessage = new GlobalNotificationModel(notification, 'danger', 5000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notificationMessage);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
getCreateBlobRoutine(fileClass) {
|
||||
const { piece } = this.state;
|
||||
|
||||
if(piece && piece.id) {
|
||||
if(fileClass === 'other_data') {
|
||||
return {
|
||||
url: ApiUrls.blob_otherdatas,
|
||||
pieceId: piece.id
|
||||
};
|
||||
} else if(fileClass === 'thumbnail') {
|
||||
return {
|
||||
url: ApiUrls.blob_thumbnail,
|
||||
pieceId: piece.id
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
@ -37,8 +114,9 @@ const PRRegisterPieceForm = React.createClass({
|
||||
return (
|
||||
<div className="register-piece--form">
|
||||
<Form
|
||||
buttons={{}}
|
||||
className="ascribe-form-bordered"
|
||||
ref="registerPieceFields">
|
||||
ref="registerPieceForm">
|
||||
<Property
|
||||
name='artist_name'
|
||||
label={getLangText('Full name')}>
|
||||
@ -64,35 +142,40 @@ const PRRegisterPieceForm = React.createClass({
|
||||
min={1}
|
||||
required/>
|
||||
</Property>
|
||||
</Form>
|
||||
<Form
|
||||
className="ascribe-form-bordered"
|
||||
ref="additionalData">
|
||||
<Property
|
||||
name='biography'
|
||||
label={getLangText('Biography')}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('THIS NEEDS TEXT')}/>
|
||||
</Property>
|
||||
<Property
|
||||
name='artist_statement'
|
||||
label={getLangText("Artist's statement")}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('THIS NEEDS TEXT')}/>
|
||||
placeholder={getLangText('Enter your statement')}/>
|
||||
</Property>
|
||||
</Form>
|
||||
<Form
|
||||
buttons={{}}
|
||||
className="ascribe-form-bordered"
|
||||
ref="additionalDataForm">
|
||||
<Property
|
||||
name='artist_bio'
|
||||
label={getLangText('Biography')}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('Enter your biography')}/>
|
||||
</Property>
|
||||
<Property
|
||||
name='exhibition'
|
||||
label={getLangText('Exhibition / Publication history (optional)')}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
placeholder={getLangText('THIS NEEDS TEXT')}/>
|
||||
placeholder={getLangText('Enter exhibitions and publication history')}/>
|
||||
</Property>
|
||||
</Form>
|
||||
<div className="input-upload-file-button-property">
|
||||
{getLangText('Select the PDF with your work')}
|
||||
<UploadFileButton
|
||||
ref="digitalWorkForm"
|
||||
createBlobRoutine={{
|
||||
url: ApiUrls.blob_digitalworks
|
||||
}}
|
||||
keyRoutine={{
|
||||
url: AppConstants.serverUrl + 's3/key/',
|
||||
fileClass: 'digitalwork'
|
||||
@ -111,6 +194,8 @@ const PRRegisterPieceForm = React.createClass({
|
||||
<div className="input-upload-file-button-property">
|
||||
{getLangText('Featured Cover photo')}
|
||||
<UploadFileButton
|
||||
ref="thumbnailForm"
|
||||
createBlobRoutine={this.getCreateBlobRoutine('thumbnail')}
|
||||
keyRoutine={{
|
||||
url: AppConstants.serverUrl + 's3/key/',
|
||||
fileClass: 'thumbnail'
|
||||
@ -129,6 +214,8 @@ const PRRegisterPieceForm = React.createClass({
|
||||
<div className="input-upload-file-button-property">
|
||||
{getLangText('Supporting Materials (Optional)')}
|
||||
<UploadFileButton
|
||||
ref="supportingMaterialsForm"
|
||||
createBlobRoutine={this.getCreateBlobRoutine('other_data')}
|
||||
keyRoutine={{
|
||||
url: AppConstants.serverUrl + 's3/key/',
|
||||
fileClass: 'other_data'
|
||||
@ -146,13 +233,16 @@ const PRRegisterPieceForm = React.createClass({
|
||||
<div className="input-upload-file-button-property">
|
||||
{getLangText('Proof of payment')}
|
||||
<UploadFileButton
|
||||
ref="proofOfPaymentForm"
|
||||
createBlobRoutine={this.getCreateBlobRoutine('other_data')}
|
||||
keyRoutine={{
|
||||
url: AppConstants.serverUrl + 's3/key/',
|
||||
fileClass: 'other_data'
|
||||
}}
|
||||
validation={{
|
||||
itemLimit: AppConstants.fineUploader.validation.registerWork.itemLimit,
|
||||
sizeLimit: AppConstants.fineUploader.validation.additionalData.sizeLimit
|
||||
sizeLimit: AppConstants.fineUploader.validation.additionalData.sizeLimit,
|
||||
allowedExtensions: ['png', 'jpg']
|
||||
}}
|
||||
location={location}
|
||||
fileClassToUpload={{
|
||||
@ -161,23 +251,23 @@ const PRRegisterPieceForm = React.createClass({
|
||||
}}/>
|
||||
</div>
|
||||
<Form
|
||||
className="ascribe-form-bordered"
|
||||
ref="terms">
|
||||
buttons={{}}
|
||||
className="ascribe-form-bordered">
|
||||
<Property
|
||||
ref="termsForm"
|
||||
name="terms"
|
||||
className="ascribe-property-collapsible-toggle"
|
||||
style={{paddingBottom: 0}}>
|
||||
<InputCheckbox
|
||||
key="terms_explicitly"
|
||||
defaultChecked={false}>
|
||||
{getLangText('I agree to the Terms and Conditions of the Portfolio Review')}
|
||||
</InputCheckbox>
|
||||
<span>
|
||||
<input type="checkbox" value="true" />
|
||||
{getLangText('By submitting this form, you agree to the Terms of Service of Portfolio Review.')}
|
||||
</span>
|
||||
</Property>
|
||||
</Form>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-default btn-wide"
|
||||
disabled={!this.state.isUploadReady}>
|
||||
onClick={this.submit}>
|
||||
{getLangText('Submit to Portfolio Review')}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -1,14 +1,19 @@
|
||||
'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 UserStore from '../../../../../stores/user_store';
|
||||
import UserActions from '../../../../../actions/user_actions';
|
||||
|
||||
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;
|
||||
@ -18,7 +23,37 @@ const PRRegisterPiece = React.createClass({
|
||||
location: object
|
||||
},
|
||||
|
||||
mixins: [History],
|
||||
|
||||
getInitialState() {
|
||||
return UserStore.getState();
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
UserStore.listen(this.onChange);
|
||||
UserActions.fetchCurrentUser();
|
||||
},
|
||||
|
||||
componentDidUpdate() {
|
||||
const { currentUser } = this.state;
|
||||
if(currentUser && currentUser.email) {
|
||||
const submittedPieceId = getCookie(currentUser.email);
|
||||
if(submittedPieceId) {
|
||||
this.history.pushState(null, `/pieces/${submittedPieceId}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
UserStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
render() {
|
||||
const { currentUser } = this.state;
|
||||
const { location } = this.props;
|
||||
|
||||
setDocumentTitle(getLangText('Submission form'));
|
||||
@ -28,14 +63,25 @@ const PRRegisterPiece = React.createClass({
|
||||
<div className="register-piece--hero">
|
||||
<h1>Portfolio Review</h1>
|
||||
<h2>{getLangText('Submission closing on %s', ' 21 Dec 2015')}</h2>
|
||||
<p>{getLangText('Submissions are open to everyone, we accept only PDFs.')}</p>
|
||||
<p>{getLangText('We accept only one PDF with up to 20 images from every participant.')}</p>
|
||||
<p>{getLangText('You need to pay 50€ in order to apply. We only accept PayPal.')}</p>
|
||||
<p>
|
||||
{getLangText('Submissions are open to everyone, we accept only PDFs.')}
|
||||
</p>
|
||||
<p>
|
||||
{getLangText('We accept only one PDF with up to 20 images from every participant.')}
|
||||
</p>
|
||||
<p>
|
||||
{getLangText('You need to pay 50€ in order to apply. We only accept PayPal.')}
|
||||
</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}/>
|
||||
location={location}
|
||||
currentUser={currentUser}/>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
|
@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import Footer from '../../../footer';
|
||||
import GlobalNotification from '../../../global_notification';
|
||||
|
||||
import { getSubdomain } from '../../../../utils/general_utils';
|
||||
@ -26,7 +25,6 @@ let PrizeApp = React.createClass({
|
||||
{children}
|
||||
<GlobalNotification />
|
||||
<div id="modal" className="container"></div>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ const ROUTES = {
|
||||
<Route
|
||||
path='password_reset'
|
||||
component={AuthProxyHandler({to: '/register_piece', when: 'loggedIn'})(PasswordResetContainer)} />
|
||||
<Route path='pieces/:pieceId' component={SPPieceContainer} />
|
||||
<Route path='*' component={ErrorNotFoundPage} />
|
||||
</Route>
|
||||
)
|
||||
|
@ -14,6 +14,7 @@ let ApiUrls = {
|
||||
'blob_digitalworks': AppConstants.apiEndpoint + 'blob/digitalworks/',
|
||||
'blob_otherdatas': AppConstants.apiEndpoint + 'blob/otherdatas/',
|
||||
'blob_contracts': AppConstants.apiEndpoint + 'blob/contracts/',
|
||||
'blob_thumbnails': AppConstants.apiEndpoint + 'blob/thumbnails/',
|
||||
'coa': AppConstants.apiEndpoint + 'coa/${id}/',
|
||||
'coa_create': AppConstants.apiEndpoint + 'coa/',
|
||||
'coa_verify': AppConstants.apiEndpoint + 'coa/verify_coa/',
|
||||
|
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
import Q from 'q';
|
||||
import moment from 'moment';
|
||||
|
||||
import { sanitize } from './general_utils';
|
||||
import AppConstants from '../constants/application_constants';
|
||||
@ -70,12 +71,20 @@ export function getCookie(name) {
|
||||
let parts = document.cookie.split(';');
|
||||
|
||||
for(let i = 0; i < parts.length; i++) {
|
||||
if(parts[i].indexOf(AppConstants.csrftoken + '=') > -1) {
|
||||
if(parts[i].indexOf(name + '=') > -1) {
|
||||
return parts[i].split('=').pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function setCookie(key, value, days) {
|
||||
const exdate = moment();
|
||||
exdate.add(days, 'days');
|
||||
console.log(exdate.utc());
|
||||
value = window.escape(value) + ((days === null) ? '' : `; expires= ${exdate.utc()}`);
|
||||
document.cookie = `${key}=${value}`;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Given a url for an image, this method fetches it and returns a promise that resolves to
|
||||
|
@ -222,7 +222,7 @@ $ascribe-red-error: rgb(169, 68, 66);
|
||||
|
||||
.input-upload-file-button-property {
|
||||
background-color: white;
|
||||
padding: 1.5em 0 1.5em 0;
|
||||
padding: 1em 0 1em 0;
|
||||
text-align: right;
|
||||
|
||||
button {
|
||||
|
@ -31,7 +31,8 @@
|
||||
}
|
||||
|
||||
.register-piece--form {
|
||||
|
||||
margin-bottom: 3em;
|
||||
|
||||
form {
|
||||
border-top: none;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user