file.status === 'uploading');
},
- handleOnClick() {
- let uploadingFiles = this.getUploadingFiles();
+ getUploadedFile() {
+ return this.props.filesToUpload.filter((file) => file.status === 'upload successful')[0];
+ },
- // We only want the button to be clickable if there are no files currently uploading
+ handleOnClick() {
+ const uploadingFiles = this.getUploadingFiles();
+ const uploadedFile = this.getUploadedFile();
+
+ if(uploadedFile) {
+ this.props.handleCancelFile(uploadedFile.id);
+ }
if(uploadingFiles.length === 0) {
+ // We only want the button to be clickable if there are no files currently uploading
+
// Firefox only recognizes the simulated mouse click if bubbles is set to true,
// but since Google Chrome propagates the event much further than needed, we
// need to stop propagation as soon as the event is created
@@ -62,40 +77,61 @@ let UploadButton = React.createClass({
// filter invalid files that might have been deleted or canceled...
filesToUpload = filesToUpload.filter(displayValidProgressFilesFilter);
- // Depending on wether there is an upload going on or not we
- // display the progress
- if(filesToUpload.length > 0) {
+ if(this.getUploadingFiles().length !== 0) {
return getLangText('Upload progress') + ': ' + Math.ceil(filesToUpload[0].progress) + '%';
} else {
return fileClassToUpload.singular;
}
},
- render() {
- let {
- multiple,
- fileClassToUpload,
- allowedExtensions
- } = this.props;
+ getUploadedFileLabel() {
+ const uploadedFile = this.getUploadedFile();
+ if(uploadedFile) {
+ return (
+
+
+ {' ' + truncateTextAtCharIndex(uploadedFile.name, 40)}
+
+ );
+ } else {
+ return (
+ {getLangText('No file chosen')}
+ );
+ }
+ },
+
+ render() {
+ let { multiple,
+ allowedExtensions } = this.props;
+
+ /*
+ * We do not want a button that submits here.
+ * As UploadButton could be used in forms that want to be submitted independent
+ * of clicking the selector.
+ * Therefore the wrapping component needs to be an `anchor` tag instead of a `button`
+ */
return (
-
- {this.getButtonLabel()}
-
-
+
);
}
});
diff --git a/js/components/ascribe_uploader/react_s3_fine_uploader.js b/js/components/ascribe_uploader/react_s3_fine_uploader.js
index e8cc8bfa..bd2da199 100644
--- a/js/components/ascribe_uploader/react_s3_fine_uploader.js
+++ b/js/components/ascribe_uploader/react_s3_fine_uploader.js
@@ -298,18 +298,27 @@ let ReactS3FineUploader = React.createClass({
resolve(res.key);
})
.catch((err) => {
- console.logGlobal(err, false, {
- files: this.state.filesToUpload,
- chunks: this.state.chunks
- });
+ this.onErrorPromiseProxy(err);
reject(err);
});
});
},
createBlob(file) {
+ const { createBlobRoutine } = this.props;
+
return Q.Promise((resolve, reject) => {
- window.fetch(this.props.createBlobRoutine.url, {
+
+ // if createBlobRoutine is not defined,
+ // we're progressing right away without posting to S3
+ // so that this can be done manually by the form
+ if(!createBlobRoutine) {
+ // still we warn the user of this component
+ console.warn('createBlobRoutine was not defined for ReactS3FineUploader. Continuing without creating the blob on the server.');
+ resolve();
+ }
+
+ window.fetch(createBlobRoutine.url, {
method: 'post',
headers: {
'Accept': 'application/json',
@@ -320,7 +329,7 @@ let ReactS3FineUploader = React.createClass({
body: JSON.stringify({
'filename': file.name,
'key': file.key,
- 'piece_id': this.props.createBlobRoutine.pieceId
+ 'piece_id': createBlobRoutine.pieceId
})
})
.then((res) => {
@@ -336,16 +345,16 @@ let ReactS3FineUploader = React.createClass({
} else if(res.contractblob) {
file.s3Url = res.contractblob.url_safe;
file.s3UrlSafe = res.contractblob.url_safe;
+ } else if(res.thumbnail) {
+ file.s3Url = res.thumbnail.url_safe;
+ file.s3UrlSafe = res.thumbnail.url_safe;
} else {
throw new Error(getLangText('Could not find a url to download.'));
}
resolve(res);
})
.catch((err) => {
- console.logGlobal(err, false, {
- files: this.state.filesToUpload,
- chunks: this.state.chunks
- });
+ this.onErrorPromiseProxy(err);
reject(err);
});
});
@@ -412,9 +421,8 @@ let ReactS3FineUploader = React.createClass({
if(this.props.submitFile) {
this.props.submitFile(files[id]);
} else {
- console.warn('You didn\'t define submitFile in as a prop in react-s3-fine-uploader');
+ console.warn('You didn\'t define submitFile as a prop in react-s3-fine-uploader');
}
-
// for explanation, check comment of if statement above
if(this.props.isReadyForFormSubmission && this.props.setIsUploadReady) {
// also, lets check if after the completion of this upload,
@@ -429,22 +437,27 @@ let ReactS3FineUploader = React.createClass({
console.warn('You didn\'t define the functions isReadyForFormSubmission and/or setIsUploadReady in as a prop in react-s3-fine-uploader');
}
})
- .catch((err) => {
- console.logGlobal(err, false, {
- files: this.state.filesToUpload,
- chunks: this.state.chunks
- });
- let notification = new GlobalNotificationModel(err.message, 'danger', 5000);
- GlobalNotificationActions.appendGlobalNotification(notification);
- });
+ .catch(this.onErrorPromiseProxy);
}
},
+ /**
+ * We want to channel all errors in this component through one single method.
+ * As fineuploader's `onError` method cannot handle the callback parameters of
+ * a promise we define this proxy method to crunch them into the correct form.
+ *
+ * @param {error} err a plain Javascript error
+ */
+ onErrorPromiseProxy(err) {
+ this.onError(null, null, err.message);
+ },
+
onError(id, name, errorReason) {
console.logGlobal(errorReason, false, {
files: this.state.filesToUpload,
chunks: this.state.chunks
});
+ this.props.setIsUploadReady(true);
this.state.uploader.cancelAll();
let notification = new GlobalNotificationModel(errorReason || this.props.defaultErrorMessage, 'danger', 5000);
@@ -609,6 +622,10 @@ let ReactS3FineUploader = React.createClass({
},
handleUploadFile(files) {
+ // While files are being uploaded, the form cannot be ready
+ // for submission
+ this.props.setIsUploadReady(false);
+
// If multiple set and user already uploaded its work,
// cancel upload
if(!this.props.multiple && this.state.filesToUpload.filter(displayValidFilesFilter).length > 0) {
diff --git a/js/components/register_piece.js b/js/components/register_piece.js
index f127c149..43ac7bb7 100644
--- a/js/components/register_piece.js
+++ b/js/components/register_piece.js
@@ -40,12 +40,6 @@ let RegisterPiece = React.createClass( {
mixins: [History],
- getDefaultProps() {
- return {
- canSpecifyEditions: true
- };
- },
-
getInitialState(){
return mergeOptions(
UserStore.getState(),
diff --git a/js/components/whitelabel/prize/actions/prize_actions.js b/js/components/whitelabel/prize/actions/prize_actions.js
deleted file mode 100644
index fcd9e91e..00000000
--- a/js/components/whitelabel/prize/actions/prize_actions.js
+++ /dev/null
@@ -1,33 +0,0 @@
-'use strict';
-
-import { alt } from '../../../../alt';
-import Q from 'q';
-
-import PrizeFetcher from '../fetchers/prize_fetcher';
-
-class PrizeActions {
- constructor() {
- this.generateActions(
- 'updatePrize'
- );
- }
-
- fetchPrize() {
- return Q.Promise((resolve, reject) => {
- PrizeFetcher
- .fetch()
- .then((res) => {
- this.actions.updatePrize({
- prize: res.prize
- });
- resolve(res);
- })
- .catch((err) => {
- console.logGlobal(err);
- reject(err);
- });
- });
- }
-}
-
-export default alt.createActions(PrizeActions);
\ No newline at end of file
diff --git a/js/components/whitelabel/prize/components/prize_register_piece.js b/js/components/whitelabel/prize/components/prize_register_piece.js
deleted file mode 100644
index 87a23591..00000000
--- a/js/components/whitelabel/prize/components/prize_register_piece.js
+++ /dev/null
@@ -1,91 +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({
- getInitialState() {
- return PrizeStore.getState();
- },
-
- componentDidMount() {
- PrizeStore.listen(this.onChange);
- PrizeActions.fetchPrize();
- },
-
- componentWillUnmount() {
- PrizeStore.unlisten(this.onChange);
- },
-
- onChange(state) {
- this.setState(state);
- },
-
- render() {
- setDocumentTitle(getLangText('Submit to the prize'));
-
- if(this.state.prize && this.state.prize.active){
- return (
-
-
-
-
-
-
-
-
-
-
- {' ' + getLangText('I agree to the Terms of Service the art price') + ' '}
- (
- {getLangText('read')}
- )
-
-
-
- );
- }
- else {
- return (
-
-
- {getLangText('The prize is no longer active')}
-
-
- );
- }
- }
-});
-
-export default PrizeRegisterPiece;
diff --git a/js/components/whitelabel/prize/constants/prize_api_urls.js b/js/components/whitelabel/prize/constants/prize_api_urls.js
index 2d35cf19..cb4e2e44 100644
--- a/js/components/whitelabel/prize/constants/prize_api_urls.js
+++ b/js/components/whitelabel/prize/constants/prize_api_urls.js
@@ -2,6 +2,7 @@
import AppPrizeConstants from './prize_application_constants';
+
function getPrizeApiUrls(subdomain) {
return {
'users_login': AppPrizeConstants.prizeApiEndpoint + subdomain + '/users/login/',
@@ -18,10 +19,9 @@ function getPrizeApiUrls(subdomain) {
'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/',
+ 'select_piece': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/select/',
'notes': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/',
'note': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/${piece_id}/'
-
};
}
diff --git a/js/components/whitelabel/prize/portfolioreview/components/pr_forms/pr_register_piece_form.js b/js/components/whitelabel/prize/portfolioreview/components/pr_forms/pr_register_piece_form.js
new file mode 100644
index 00000000..0c293b15
--- /dev/null
+++ b/js/components/whitelabel/prize/portfolioreview/components/pr_forms/pr_register_piece_form.js
@@ -0,0 +1,375 @@
+'use strict';
+
+import React from 'react';
+import { History } from 'react-router';
+
+import Form from '../../../../../ascribe_forms/form';
+import Property from '../../../../../ascribe_forms/property';
+import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_toggable';
+
+import UploadButton from '../../../../../ascribe_uploader/ascribe_upload_button/upload_button';
+import InputFineuploader from '../../../../../ascribe_forms/input_fineuploader';
+import AscribeSpinner from '../../../../../ascribe_spinner';
+
+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';
+import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils';
+
+
+const { object } = React.PropTypes;
+
+const PRRegisterPieceForm = React.createClass({
+ propTypes: {
+ location: object,
+ history: object,
+ currentUser: 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;
+ } else {
+ // 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
+ let 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(({ success, piece, notification }) => {
+ if(success) {
+ 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
+ });
+ } else {
+ const notificationMessage = new GlobalNotificationModel(notification, 'danger', 5000);
+ GlobalNotificationActions.appendGlobalNotification(notificationMessage);
+ }
+ })
+ .then(() => this.history.pushState(null, `/pieces/${this.state.piece.id}`))
+ .catch(() => {
+ const notificationMessage = new GlobalNotificationModel(getLangText("Ups! We weren't able to send your submission. Contact: support@ascribe.io"), 'danger', 5000);
+ GlobalNotificationActions.appendGlobalNotification(notificationMessage);
+ });
+ },
+
+ validateForms() {
+ const { registerPieceForm,
+ additionalDataForm,
+ uploadersForm } = this.refs;
+
+ const registerPieceFormValidation = registerPieceForm.validate();
+ const additionalDataFormValidation = additionalDataForm.validate();
+ const uploaderFormValidation = uploadersForm.validate();
+
+ return registerPieceFormValidation && additionalDataFormValidation && uploaderFormValidation;
+ },
+
+ getCreateBlobRoutine() {
+ const { piece } = this.state;
+
+ if(piece && piece.id) {
+ return {
+ url: ApiUrls.blob_otherdatas,
+ pieceId: piece.id
+ };
+ } else {
+ return null;
+ }
+ },
+
+ /**
+ * This method is 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
+ });
+ };
+ },
+
+ getSubmitButton() {
+ const { digitalWorkKeyReady,
+ thumbnailKeyReady,
+ supportingMaterialsReady,
+ proofOfPaymentReady,
+ submitted } = this.state;
+
+ if(submitted) {
+ return (
+
+
+
+ );
+ } else {
+ return (
+
+ {getLangText('Submit to Portfolio Review')}
+
+ );
+ }
+ },
+
+ render() {
+ const { location } = this.props;
+
+ return (
+
+
+
+
+
+ {this.getSubmitButton()}
+
+ );
+ }
+});
+
+export default PRRegisterPieceForm;
\ No newline at end of file
diff --git a/js/components/whitelabel/prize/portfolioreview/components/pr_hero.js b/js/components/whitelabel/prize/portfolioreview/components/pr_hero.js
new file mode 100644
index 00000000..a0fa0811
--- /dev/null
+++ b/js/components/whitelabel/prize/portfolioreview/components/pr_hero.js
@@ -0,0 +1,42 @@
+'use strict';
+
+import React from 'react';
+
+import UserStore from '../../../../../stores/user_store';
+import UserActions from '../../../../../actions/user_actions';
+
+import Glyphicon from 'react-bootstrap/lib/Glyphicon';
+
+
+const PRHero = React.createClass({
+ getInitialState() {
+ return UserStore.getState();
+ },
+
+ componentDidMount() {
+ UserStore.listen(this.onChange);
+ UserActions.fetchCurrentUser();
+ },
+
+ componentWillUnmount() {
+ UserStore.unlisten(this.onChange);
+ },
+
+ onChange(state) {
+ this.setState(state);
+ },
+
+ render() {
+ const { currentUser } = this.state;
+
+ return (
+
+
Congratulations {currentUser.email}!
+
You have successfully submitted to Portfolio Review 2016
+
See below, your uploaded portfolio:
+
+ );
+ }
+});
+
+export default PRHero;
\ No newline at end of file
diff --git a/js/components/whitelabel/prize/portfolioreview/components/pr_landing.js b/js/components/whitelabel/prize/portfolioreview/components/pr_landing.js
new file mode 100644
index 00000000..cdada68b
--- /dev/null
+++ b/js/components/whitelabel/prize/portfolioreview/components/pr_landing.js
@@ -0,0 +1,128 @@
+'use strict';
+
+import React from 'react';
+import { History } from 'react-router';
+
+import PrizeActions from '../../simple_prize/actions/prize_actions';
+import PrizeStore from '../../simple_prize/stores/prize_store';
+
+import Button from 'react-bootstrap/lib/Button';
+import ButtonGroup from 'react-bootstrap/lib/ButtonGroup';
+
+import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
+
+import UserStore from '../../../../../stores/user_store';
+import UserActions from '../../../../../actions/user_actions';
+
+import { mergeOptions } from '../../../../../utils/general_utils';
+import { getLangText } from '../../../../../utils/lang_utils';
+
+
+const PRLanding = React.createClass({
+ propTypes: {
+ location: React.PropTypes.object
+ },
+
+ mixins: [History],
+
+ getInitialState() {
+ return mergeOptions(
+ PrizeStore.getState(),
+ UserStore.getState()
+ );
+ },
+
+ componentDidMount() {
+ const { location } = this.props;
+ UserStore.listen(this.onChange);
+ UserActions.fetchCurrentUser();
+ PrizeStore.listen(this.onChange);
+ PrizeActions.fetchPrize();
+
+ if(location && location.query && location.query.redirect) {
+ let queryCopy = JSON.parse(JSON.stringify(location.query));
+ delete queryCopy.redirect;
+ window.setTimeout(() => this.history.replaceState(null, `/${location.query.redirect}`, queryCopy));
+ }
+ },
+
+ componentWillUnmount() {
+ UserStore.unlisten(this.onChange);
+ PrizeStore.unlisten(this.onChange);
+ },
+
+ onChange(state) {
+ this.setState(state);
+ },
+
+ getButtons() {
+ if (this.state.prize && this.state.prize.active){
+ return (
+
+
+
+ {getLangText('Sign up to submit')}
+
+
+
+
+ {getLangText('or, already an ascribe user?')}
+
+
+
+ {getLangText('Log in to submit')}
+
+
+
+ );
+ }
+ return (
+
+
+ {getLangText('Sign up to ascribe')}
+
+
+
+ {getLangText('or, already an ascribe user?')}
+
+
+
+ {getLangText('Log in')}
+
+
+
+ );
+ },
+
+ getTitle() {
+ if (this.state.prize && this.state.prize.active){
+ return (
+
+ {getLangText('This is the submission page for Portfolio Review 2016.')}
+
+ );
+ }
+ return (
+
+ {getLangText('Submissions for Portfolio Review 2016 are now closed.')}
+
+ );
+ },
+ render() {
+ return (
+
+
+
+
+ {getLangText('Welcome to Portfolio Review 2016')}
+
+ {this.getTitle()}
+ {this.getButtons()}
+
+
+
+ );
+ }
+});
+
+export default PRLanding;
\ No newline at end of file
diff --git a/js/components/whitelabel/prize/portfolioreview/components/pr_register_piece.js b/js/components/whitelabel/prize/portfolioreview/components/pr_register_piece.js
new file mode 100644
index 00000000..a2a70a97
--- /dev/null
+++ b/js/components/whitelabel/prize/portfolioreview/components/pr_register_piece.js
@@ -0,0 +1,82 @@
+'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;
+
+const PRRegisterPiece = React.createClass({
+ propTypes: {
+ 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('Submit to Portfolio Review'));
+ return (
+
+
+
+
Portfolio Review
+
{getLangText('Submission closing on %s', ' 22 Dec 2015')}
+
+ {getLangText("You're submitting as %s. ", currentUser.email)}
+ {getLangText('Change account?')}
+
+
+
+
+
+
+
+ );
+ }
+});
+
+export default PRRegisterPiece;
\ No newline at end of file
diff --git a/js/components/whitelabel/prize/portfolioreview/pr_app.js b/js/components/whitelabel/prize/portfolioreview/pr_app.js
new file mode 100644
index 00000000..7e66c43c
--- /dev/null
+++ b/js/components/whitelabel/prize/portfolioreview/pr_app.js
@@ -0,0 +1,65 @@
+'use strict';
+
+import React from 'react';
+import GlobalNotification from '../../../global_notification';
+
+import Hero from './components/pr_hero';
+
+import UserStore from '../../../../stores/user_store';
+import UserActions from '../../../../actions/user_actions';
+
+import { getSubdomain } from '../../../../utils/general_utils';
+import { getCookie } from '../../../../utils/fetch_api_utils';
+
+
+let PRApp = React.createClass({
+ propTypes: {
+ children: React.PropTypes.oneOfType([
+ React.PropTypes.arrayOf(React.PropTypes.element),
+ React.PropTypes.element
+ ]),
+ history: React.PropTypes.object,
+ routes: React.PropTypes.arrayOf(React.PropTypes.object)
+ },
+
+ getInitialState() {
+ return UserStore.getState();
+ },
+
+ componentDidMount() {
+ UserStore.listen(this.onChange);
+ UserActions.fetchCurrentUser();
+ },
+
+ componentWillUnmount() {
+ UserStore.unlisten(this.onChange);
+ },
+
+ onChange(state) {
+ this.setState(state);
+ },
+
+ render() {
+ const { history, children } = this.props;
+ const { currentUser } = this.state;
+ let subdomain = getSubdomain();
+ let header;
+
+ if (currentUser && currentUser.email && history.isActive(`/pieces/${getCookie(currentUser.email)}`)) {
+ header = ;
+ }
+
+ return (
+
+ );
+ }
+});
+
+export default PRApp;
diff --git a/js/components/whitelabel/prize/prize_routes.js b/js/components/whitelabel/prize/prize_routes.js
index 14d8b4d9..1f2c6374 100644
--- a/js/components/whitelabel/prize/prize_routes.js
+++ b/js/components/whitelabel/prize/prize_routes.js
@@ -3,58 +3,94 @@
import React from 'react';
import { Route, IndexRoute } from 'react-router';
-import Landing from './components/prize_landing';
-import LoginContainer from './components/prize_login_container';
-import LogoutContainer from '../../../components/logout_container';
-import SignupContainer from './components/prize_signup_container';
-import PasswordResetContainer from '../../../components/password_reset_container';
-import PrizeRegisterPiece from './components/prize_register_piece';
-import PrizePieceList from './components/prize_piece_list';
-import PrizePieceContainer from './components/ascribe_detail/prize_piece_container';
-import EditionContainer from '../../ascribe_detail/edition_container';
-import SettingsContainer from './components/prize_settings_container';
-import CoaVerifyContainer from '../../../components/coa_verify_container';
-import ErrorNotFoundPage from '../../../components/error_not_found_page';
+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 SPApp from './simple_prize/prize_app';
-import App from './prize_app';
+import PRApp from './portfolioreview/pr_app';
+import PRLanding from './portfolioreview/components/pr_landing';
+import PRRegisterPiece from './portfolioreview/components/pr_register_piece';
+
+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 AuthProxyHandler from '../../../components/ascribe_routes/proxy_routes/auth_proxy_handler';
-function getRoutes() {
- return (
-
-
+const ROUTES = {
+ sluice: (
+
+
+ component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(SPLoginContainer)} />
+ component={AuthProxyHandler({to: '/collection', when: 'loggedIn'})(SPSignupContainer)} />
+ component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(SPSettingsContainer)}/>
-
+
- );
+ ),
+ portfolioreview: (
+
+
+
+
+
+
+
+
+
+
+ )
+};
+
+
+function getRoutes(commonRoutes, subdomain) {
+ if(subdomain in ROUTES) {
+ return ROUTES[subdomain];
+ } else {
+ throw new Error('Subdomain wasn\'t specified in the wallet app.');
+ }
}
diff --git a/js/components/whitelabel/prize/simple_prize/actions/prize_actions.js b/js/components/whitelabel/prize/simple_prize/actions/prize_actions.js
new file mode 100644
index 00000000..dbca1b5d
--- /dev/null
+++ b/js/components/whitelabel/prize/simple_prize/actions/prize_actions.js
@@ -0,0 +1,28 @@
+'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.prize
+ });
+ })
+ .catch((err) => {
+ console.logGlobal(err);
+ });
+ }
+}
+
+export default alt.createActions(PrizeActions);
\ No newline at end of file
diff --git a/js/components/whitelabel/prize/actions/prize_jury_actions.js b/js/components/whitelabel/prize/simple_prize/actions/prize_jury_actions.js
similarity index 97%
rename from js/components/whitelabel/prize/actions/prize_jury_actions.js
rename to js/components/whitelabel/prize/simple_prize/actions/prize_jury_actions.js
index 9bd03f59..24cf08e8 100644
--- a/js/components/whitelabel/prize/actions/prize_jury_actions.js
+++ b/js/components/whitelabel/prize/simple_prize/actions/prize_jury_actions.js
@@ -1,6 +1,6 @@
'use strict';
-import { alt } from '../../../../alt';
+import { alt } from '../../../../../alt';
import Q from 'q';
import PrizeJuryFetcher from '../fetchers/prize_jury_fetcher';
diff --git a/js/components/whitelabel/prize/actions/prize_rating_actions.js b/js/components/whitelabel/prize/simple_prize/actions/prize_rating_actions.js
similarity index 98%
rename from js/components/whitelabel/prize/actions/prize_rating_actions.js
rename to js/components/whitelabel/prize/simple_prize/actions/prize_rating_actions.js
index 184d84e7..68b5334b 100644
--- a/js/components/whitelabel/prize/actions/prize_rating_actions.js
+++ b/js/components/whitelabel/prize/simple_prize/actions/prize_rating_actions.js
@@ -1,6 +1,6 @@
'use strict';
-import { alt } from '../../../../alt';
+import { alt } from '../../../../../alt';
import Q from 'q';
import PrizeRatingFetcher from '../fetchers/prize_rating_fetcher';
diff --git a/js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js b/js/components/whitelabel/prize/simple_prize/components/ascribe_accordion_list/accordion_list_item_prize.js
similarity index 89%
rename from js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js
rename to js/components/whitelabel/prize/simple_prize/components/ascribe_accordion_list/accordion_list_item_prize.js
index 08ebce42..965b9012 100644
--- a/js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js
+++ b/js/components/whitelabel/prize/simple_prize/components/ascribe_accordion_list/accordion_list_item_prize.js
@@ -5,25 +5,25 @@ 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 PieceListActions from '../../../../../../actions/piece_list_actions';
+import PieceListStore from '../../../../../../stores/piece_list_store';
import PrizeRatingActions from '../../actions/prize_rating_actions';
-import UserStore from '../../../../../stores/user_store';
+import UserStore from '../../../../../../stores/user_store';
-import InputCheckbox from '../../../../ascribe_forms/input_checkbox';
+import InputCheckbox from '../../../../../ascribe_forms/input_checkbox';
-import AccordionListItemPiece from '../../../../ascribe_accordion_list/accordion_list_item_piece';
+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 GlobalNotificationModel from '../../../../../../models/global_notification_model';
+import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
-import AclProxy from '../../../../acl_proxy';
+import AclProxy from '../../../../../acl_proxy';
import SubmitToPrizeButton from './../ascribe_buttons/submit_to_prize_button';
-import { getLangText } from '../../../../../utils/lang_utils';
-import { mergeOptions } from '../../../../../utils/general_utils';
+import { getLangText } from '../../../../../../utils/lang_utils';
+import { mergeOptions } from '../../../../../../utils/general_utils';
let AccordionListItemPrize = React.createClass({
diff --git a/js/components/whitelabel/prize/components/ascribe_buttons/submit_to_prize_button.js b/js/components/whitelabel/prize/simple_prize/components/ascribe_buttons/submit_to_prize_button.js
similarity index 86%
rename from js/components/whitelabel/prize/components/ascribe_buttons/submit_to_prize_button.js
rename to js/components/whitelabel/prize/simple_prize/components/ascribe_buttons/submit_to_prize_button.js
index 409b8aa1..8ceb87ea 100644
--- a/js/components/whitelabel/prize/components/ascribe_buttons/submit_to_prize_button.js
+++ b/js/components/whitelabel/prize/simple_prize/components/ascribe_buttons/submit_to_prize_button.js
@@ -3,10 +3,10 @@
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 ModalWrapper from '../../../../../ascribe_modal/modal_wrapper';
+import PieceSubmitToPrizeForm from '../../../../../ascribe_forms/form_submit_to_prize';
-import { getLangText } from '../../../../../utils/lang_utils';
+import { getLangText } from '../../../../../../utils/lang_utils';
let SubmitToPrizeButton = React.createClass({
propTypes: {
diff --git a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js b/js/components/whitelabel/prize/simple_prize/components/ascribe_detail/prize_piece_container.js
similarity index 82%
rename from js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
rename to js/components/whitelabel/prize/simple_prize/components/ascribe_detail/prize_piece_container.js
index 30a91607..93ca50f3 100644
--- a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
+++ b/js/components/whitelabel/prize/simple_prize/components/ascribe_detail/prize_piece_container.js
@@ -6,41 +6,44 @@ import Moment from 'moment';
import StarRating from 'react-star-rating';
-import PieceActions from '../../../../../actions/piece_actions';
-import PieceStore from '../../../../../stores/piece_store';
+import PieceActions from '../../../../../../actions/piece_actions';
+import PieceStore from '../../../../../../stores/piece_store';
-import PieceListStore from '../../../../../stores/piece_list_store';
-import PieceListActions from '../../../../../actions/piece_list_actions';
+import PieceListStore from '../../../../../../stores/piece_list_store';
+import PieceListActions from '../../../../../../actions/piece_list_actions';
import PrizeRatingActions from '../../actions/prize_rating_actions';
import PrizeRatingStore from '../../stores/prize_rating_store';
-import UserStore from '../../../../../stores/user_store';
+import UserStore from '../../../../../../stores/user_store';
+import UserActions from '../../../../../../actions/user_actions';
-import Piece from '../../../../../components/ascribe_detail/piece';
-import Note from '../../../../../components/ascribe_detail/note';
+import Piece from '../../../../../../components/ascribe_detail/piece';
+import Note from '../../../../../../components/ascribe_detail/note';
-import AscribeSpinner from '../../../../ascribe_spinner';
+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 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 InputCheckbox from '../../../../ascribe_forms/input_checkbox';
-import LoanForm from '../../../../ascribe_forms/form_loan';
-import ListRequestActions from '../../../../ascribe_forms/list_form_request_actions';
-import ModalWrapper from '../../../../ascribe_modal/modal_wrapper';
+import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader';
-import GlobalNotificationModel from '../../../../../models/global_notification_model';
-import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
+import InputCheckbox from '../../../../../ascribe_forms/input_checkbox';
+import LoanForm from '../../../../../ascribe_forms/form_loan';
+import ListRequestActions from '../../../../../ascribe_forms/list_form_request_actions';
+import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper';
-import DetailProperty from '../../../../ascribe_detail/detail_property';
+import GlobalNotificationModel from '../../../../../../models/global_notification_model';
+import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
-import ApiUrls from '../../../../../constants/api_urls';
-import { mergeOptions } from '../../../../../utils/general_utils';
-import { getLangText } from '../../../../../utils/lang_utils';
-import { setDocumentTitle } from '../../../../../utils/dom_utils';
+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';
/**
@@ -48,7 +51,8 @@ import { setDocumentTitle } from '../../../../../utils/dom_utils';
*/
let PieceContainer = React.createClass({
propTypes: {
- params: React.PropTypes.object
+ params: React.PropTypes.object,
+ location: React.PropTypes.object
},
getInitialState() {
@@ -62,6 +66,7 @@ let PieceContainer = React.createClass({
PieceStore.listen(this.onChange);
PieceActions.fetchOne(this.props.params.pieceId);
UserStore.listen(this.onChange);
+ UserActions.fetchCurrentUser();
// Every time we enter the piece detail page, just reset the piece
// store as it will otherwise display wrong/old data once the user loads
@@ -142,7 +147,7 @@ let PieceContainer = React.createClass({
-
+
{this.state.piece.title}
@@ -157,7 +162,7 @@ let PieceContainer = React.createClass({
piece={this.state.piece}
currentUser={this.state.currentUser}/>
}>
-
+
);
} else {
@@ -177,24 +182,28 @@ let NavigationHeader = React.createClass({
},
render() {
- if (this.props.currentUser && this.props.currentUser.email && this.props.piece && this.props.piece.navigation) {
- let nav = this.props.piece.navigation;
+ const { currentUser, piece } = this.props;
+
+ if (currentUser && currentUser.email && currentUser.is_judge && currentUser.is_jury &&
+ !currentUser.is_admin && piece && piece.navigation) {
+ let nav = piece.navigation;
return (
-
+
{getLangText('Previous')}
-
+
{getLangText('Next')}
+
);
}
@@ -417,7 +426,8 @@ let PrizePieceRatings = React.createClass({
let PrizePieceDetails = React.createClass({
propTypes: {
- piece: React.PropTypes.object
+ piece: React.PropTypes.object,
+ location: React.PropTypes.object
},
render() {
@@ -432,6 +442,8 @@ let PrizePieceDetails = React.createClass({
);
diff --git a/js/components/whitelabel/prize/components/prize_hero.js b/js/components/whitelabel/prize/simple_prize/components/prize_hero.js
similarity index 83%
rename from js/components/whitelabel/prize/components/prize_hero.js
rename to js/components/whitelabel/prize/simple_prize/components/prize_hero.js
index b98f407e..8842acf9 100644
--- a/js/components/whitelabel/prize/components/prize_hero.js
+++ b/js/components/whitelabel/prize/simple_prize/components/prize_hero.js
@@ -1,7 +1,7 @@
'use strict';
import React from 'react';
-import constants from '../../../../constants/application_constants';
+import constants from '../../../../../constants/application_constants';
let Hero = React.createClass({
diff --git a/js/components/whitelabel/prize/components/prize_landing.js b/js/components/whitelabel/prize/simple_prize/components/prize_landing.js
similarity index 93%
rename from js/components/whitelabel/prize/components/prize_landing.js
rename to js/components/whitelabel/prize/simple_prize/components/prize_landing.js
index 355b3786..e26a05b5 100644
--- a/js/components/whitelabel/prize/components/prize_landing.js
+++ b/js/components/whitelabel/prize/simple_prize/components/prize_landing.js
@@ -11,11 +11,11 @@ import ButtonGroup from 'react-bootstrap/lib/ButtonGroup';
import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
-import UserStore from '../../../../stores/user_store';
-import UserActions from '../../../../actions/user_actions';
+import UserStore from '../../../../../stores/user_store';
+import UserActions from '../../../../../actions/user_actions';
-import { mergeOptions } from '../../../../utils/general_utils';
-import { getLangText } from '../../../../utils/lang_utils';
+import { mergeOptions } from '../../../../../utils/general_utils';
+import { getLangText } from '../../../../../utils/lang_utils';
let Landing = React.createClass({
diff --git a/js/components/whitelabel/prize/components/prize_login_container.js b/js/components/whitelabel/prize/simple_prize/components/prize_login_container.js
similarity index 83%
rename from js/components/whitelabel/prize/components/prize_login_container.js
rename to js/components/whitelabel/prize/simple_prize/components/prize_login_container.js
index 9a0de06d..e168ca68 100644
--- a/js/components/whitelabel/prize/components/prize_login_container.js
+++ b/js/components/whitelabel/prize/simple_prize/components/prize_login_container.js
@@ -3,10 +3,10 @@
import React from 'react';
import { Link } from 'react-router';
-import LoginForm from '../../../ascribe_forms/form_login';
+import LoginForm from '../../../../ascribe_forms/form_login';
-import { getLangText } from '../../../../utils/lang_utils';
-import { setDocumentTitle } from '../../../../utils/dom_utils';
+import { getLangText } from '../../../../../utils/lang_utils';
+import { setDocumentTitle } from '../../../../../utils/dom_utils';
let LoginContainer = React.createClass({
diff --git a/js/components/whitelabel/prize/components/prize_piece_list.js b/js/components/whitelabel/prize/simple_prize/components/prize_piece_list.js
similarity index 86%
rename from js/components/whitelabel/prize/components/prize_piece_list.js
rename to js/components/whitelabel/prize/simple_prize/components/prize_piece_list.js
index 7a6a90ac..8e602012 100644
--- a/js/components/whitelabel/prize/components/prize_piece_list.js
+++ b/js/components/whitelabel/prize/simple_prize/components/prize_piece_list.js
@@ -1,10 +1,10 @@
'use strict';
import React from 'react';
-import PieceList from '../../../piece_list';
+import PieceList from '../../../../piece_list';
-import UserActions from '../../../../actions/user_actions';
-import UserStore from '../../../../stores/user_store';
+import UserActions from '../../../../../actions/user_actions';
+import UserStore from '../../../../../stores/user_store';
import PrizeActions from '../actions/prize_actions';
import PrizeStore from '../stores/prize_store';
@@ -15,9 +15,9 @@ import LinkContainer from 'react-router-bootstrap/lib/LinkContainer';
import AccordionListItemPrize from './ascribe_accordion_list/accordion_list_item_prize';
-import { mergeOptions } from '../../../../utils/general_utils';
-import { getLangText } from '../../../../utils/lang_utils';
-import { setDocumentTitle } from '../../../../utils/dom_utils';
+import { mergeOptions } from '../../../../../utils/general_utils';
+import { getLangText } from '../../../../../utils/lang_utils';
+import { setDocumentTitle } from '../../../../../utils/dom_utils';
let PrizePieceList = React.createClass({
propTypes: {
diff --git a/js/components/whitelabel/prize/simple_prize/components/prize_register_piece.js b/js/components/whitelabel/prize/simple_prize/components/prize_register_piece.js
new file mode 100644
index 00000000..ca4e8fa9
--- /dev/null
+++ b/js/components/whitelabel/prize/simple_prize/components/prize_register_piece.js
@@ -0,0 +1,101 @@
+'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: {
+ 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 { location } = this.props;
+
+ setDocumentTitle(getLangText('Submit to the prize'));
+
+ if(this.state.prize && this.state.prize.active){
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ {' ' + getLangText('I agree to the Terms of Service the art price') + ' '}
+ (
+ {getLangText('read')}
+ )
+
+
+
+
+
+ );
+ }
+ else {
+ return (
+
+
+ {getLangText('The prize is no longer active')}
+
+
+ );
+ }
+ }
+});
+
+export default PrizeRegisterPiece;
diff --git a/js/components/whitelabel/prize/components/prize_settings_container.js b/js/components/whitelabel/prize/simple_prize/components/prize_settings_container.js
similarity index 91%
rename from js/components/whitelabel/prize/components/prize_settings_container.js
rename to js/components/whitelabel/prize/simple_prize/components/prize_settings_container.js
index 81d62380..145a9d24 100644
--- a/js/components/whitelabel/prize/components/prize_settings_container.js
+++ b/js/components/whitelabel/prize/simple_prize/components/prize_settings_container.js
@@ -2,29 +2,29 @@
import React from 'react';
-import UserStore from '../../../../stores/user_store';
-import UserActions from '../../../../actions/user_actions';
+import UserStore from '../../../../../stores/user_store';
+import UserActions from '../../../../../actions/user_actions';
import PrizeActions from '../actions/prize_actions';
import PrizeStore from '../stores/prize_store';
import PrizeJuryActions from '../actions/prize_jury_actions';
import PrizeJuryStore from '../stores/prize_jury_store';
-import SettingsContainer from '../../../ascribe_settings/settings_container';
-import CollapsibleParagraph from '../../../ascribe_collapsible/collapsible_paragraph';
+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 Form from '../../../../ascribe_forms/form';
+import Property from '../../../../ascribe_forms/property';
-import ActionPanel from '../../../ascribe_panel/action_panel';
+import ActionPanel from '../../../../ascribe_panel/action_panel';
-import GlobalNotificationModel from '../../../../models/global_notification_model';
-import GlobalNotificationActions from '../../../../actions/global_notification_actions';
+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 AscribeSpinner from '../../../../ascribe_spinner';
+import ApiUrls from '../../../../../constants/api_urls';
-import { getLangText } from '../../../../utils/lang_utils';
-import { setDocumentTitle } from '../../../../utils/dom_utils';
+import { getLangText } from '../../../../../utils/lang_utils';
+import { setDocumentTitle } from '../../../../../utils/dom_utils';
let Settings = React.createClass({
diff --git a/js/components/whitelabel/prize/components/prize_signup_container.js b/js/components/whitelabel/prize/simple_prize/components/prize_signup_container.js
similarity index 86%
rename from js/components/whitelabel/prize/components/prize_signup_container.js
rename to js/components/whitelabel/prize/simple_prize/components/prize_signup_container.js
index 884062da..7a44d521 100644
--- a/js/components/whitelabel/prize/components/prize_signup_container.js
+++ b/js/components/whitelabel/prize/simple_prize/components/prize_signup_container.js
@@ -1,10 +1,10 @@
'use strict';
import React from 'react';
-import SignupForm from '../../../ascribe_forms/form_signup';
+import SignupForm from '../../../../ascribe_forms/form_signup';
-import { getLangText } from '../../../../utils/lang_utils';
-import { setDocumentTitle } from '../../../../utils/dom_utils';
+import { getLangText } from '../../../../../utils/lang_utils';
+import { setDocumentTitle } from '../../../../../utils/dom_utils';
let SignupContainer = React.createClass({
propTypes: {
diff --git a/js/components/whitelabel/prize/fetchers/prize_fetcher.js b/js/components/whitelabel/prize/simple_prize/fetchers/prize_fetcher.js
similarity index 70%
rename from js/components/whitelabel/prize/fetchers/prize_fetcher.js
rename to js/components/whitelabel/prize/simple_prize/fetchers/prize_fetcher.js
index 0bf9fc55..410d63a2 100644
--- a/js/components/whitelabel/prize/fetchers/prize_fetcher.js
+++ b/js/components/whitelabel/prize/simple_prize/fetchers/prize_fetcher.js
@@ -1,6 +1,6 @@
'use strict';
-import requests from '../../../../utils/requests';
+import requests from '../../../../../utils/requests';
let PrizeFetcher = {
diff --git a/js/components/whitelabel/prize/fetchers/prize_jury_fetcher.js b/js/components/whitelabel/prize/simple_prize/fetchers/prize_jury_fetcher.js
similarity index 88%
rename from js/components/whitelabel/prize/fetchers/prize_jury_fetcher.js
rename to js/components/whitelabel/prize/simple_prize/fetchers/prize_jury_fetcher.js
index 1c5b0a0d..973107b4 100644
--- a/js/components/whitelabel/prize/fetchers/prize_jury_fetcher.js
+++ b/js/components/whitelabel/prize/simple_prize/fetchers/prize_jury_fetcher.js
@@ -1,6 +1,6 @@
'use strict';
-import requests from '../../../../utils/requests';
+import requests from '../../../../../utils/requests';
let PrizeJuryFetcher = {
diff --git a/js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js b/js/components/whitelabel/prize/simple_prize/fetchers/prize_rating_fetcher.js
similarity index 90%
rename from js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js
rename to js/components/whitelabel/prize/simple_prize/fetchers/prize_rating_fetcher.js
index 33450dd6..38d0576e 100644
--- a/js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js
+++ b/js/components/whitelabel/prize/simple_prize/fetchers/prize_rating_fetcher.js
@@ -1,6 +1,6 @@
'use strict';
-import requests from '../../../../utils/requests';
+import requests from '../../../../../utils/requests';
let PrizeRatingFetcher = {
diff --git a/js/components/whitelabel/prize/prize_app.js b/js/components/whitelabel/prize/simple_prize/prize_app.js
similarity index 87%
rename from js/components/whitelabel/prize/prize_app.js
rename to js/components/whitelabel/prize/simple_prize/prize_app.js
index aadb0b05..d95d7772 100644
--- a/js/components/whitelabel/prize/prize_app.js
+++ b/js/components/whitelabel/prize/simple_prize/prize_app.js
@@ -2,11 +2,11 @@
import React from 'react';
import Hero from './components/prize_hero';
-import Header from '../../header';
-import Footer from '../../footer';
-import GlobalNotification from '../../global_notification';
+import Header from '../../../header';
+import Footer from '../../../footer';
+import GlobalNotification from '../../../global_notification';
-import { getSubdomain } from '../../../utils/general_utils';
+import { getSubdomain } from '../../../../utils/general_utils';
let PrizeApp = React.createClass({
diff --git a/js/components/whitelabel/prize/stores/prize_jury_store.js b/js/components/whitelabel/prize/simple_prize/stores/prize_jury_store.js
similarity index 96%
rename from js/components/whitelabel/prize/stores/prize_jury_store.js
rename to js/components/whitelabel/prize/simple_prize/stores/prize_jury_store.js
index 69d73e3a..536b8633 100644
--- a/js/components/whitelabel/prize/stores/prize_jury_store.js
+++ b/js/components/whitelabel/prize/simple_prize/stores/prize_jury_store.js
@@ -1,6 +1,6 @@
'use strict';
-import { alt } from '../../../../alt';
+import { alt } from '../../../../../alt';
import PrizeJuryActions from '../actions/prize_jury_actions';
diff --git a/js/components/whitelabel/prize/stores/prize_rating_store.js b/js/components/whitelabel/prize/simple_prize/stores/prize_rating_store.js
similarity index 93%
rename from js/components/whitelabel/prize/stores/prize_rating_store.js
rename to js/components/whitelabel/prize/simple_prize/stores/prize_rating_store.js
index d67fa603..9f1552bb 100644
--- a/js/components/whitelabel/prize/stores/prize_rating_store.js
+++ b/js/components/whitelabel/prize/simple_prize/stores/prize_rating_store.js
@@ -1,6 +1,6 @@
'use strict';
-import { alt } from '../../../../alt';
+import { alt } from '../../../../../alt';
import PrizeRatingActions from '../actions/prize_rating_actions';
diff --git a/js/components/whitelabel/prize/stores/prize_store.js b/js/components/whitelabel/prize/simple_prize/stores/prize_store.js
similarity index 87%
rename from js/components/whitelabel/prize/stores/prize_store.js
rename to js/components/whitelabel/prize/simple_prize/stores/prize_store.js
index 68cc9264..8d9c4bbe 100644
--- a/js/components/whitelabel/prize/stores/prize_store.js
+++ b/js/components/whitelabel/prize/simple_prize/stores/prize_store.js
@@ -1,6 +1,6 @@
'use strict';
-import { alt } from '../../../../alt';
+import { alt } from '../../../../../alt';
import PrizeActions from '../actions/prize_actions';
diff --git a/js/constants/api_urls.js b/js/constants/api_urls.js
index 2ff689fe..a07f29b1 100644
--- a/js/constants/api_urls.js
+++ b/js/constants/api_urls.js
@@ -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/',
diff --git a/js/constants/application_constants.js b/js/constants/application_constants.js
index 0fe5e210..b175c158 100644
--- a/js/constants/application_constants.js
+++ b/js/constants/application_constants.js
@@ -46,6 +46,13 @@ let constants = {
'logo': 'https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/ikonotv/ikono-logo-black.png',
'permissions': ['register', 'edit', 'share', 'del_from_collection'],
'type': 'wallet'
+ },
+ {
+ 'subdomain': 'portfolioreview',
+ 'name': 'Portfolio Review',
+ 'logo': 'http://notfoundlogo.de',
+ 'permissions': ['register', 'edit', 'share', 'del_from_collection'],
+ 'type': 'prize'
}
],
'defaultDomain': {
diff --git a/js/utils/fetch_api_utils.js b/js/utils/fetch_api_utils.js
index 3ed964ba..72b5b82b 100644
--- a/js/utils/fetch_api_utils.js
+++ b/js/utils/fetch_api_utils.js
@@ -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,19 @@ 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');
+ 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
diff --git a/sass/ascribe_custom_style.scss b/sass/ascribe_custom_style.scss
index 05d39027..98cce937 100644
--- a/sass/ascribe_custom_style.scss
+++ b/sass/ascribe_custom_style.scss
@@ -508,7 +508,10 @@ fieldset[disabled] .btn-secondary.active {
> pre,
> select,
> span:not(.glyphicon),
+ > p,
+ > p > span,
> textarea {
+ color: $ascribe-dark-blue;
font-family: $ascribe--font;
font-weight: $ascribe--font-weight-light;
}
diff --git a/sass/ascribe_form.scss b/sass/ascribe_form.scss
index 41e17de1..1b265e91 100644
--- a/sass/ascribe_form.scss
+++ b/sass/ascribe_form.scss
@@ -23,4 +23,4 @@
@media (max-width: 550px) {
width: 100%;
}
-}
+}
\ No newline at end of file
diff --git a/sass/ascribe_property.scss b/sass/ascribe_property.scss
index e938a7c3..0bfd5496 100644
--- a/sass/ascribe_property.scss
+++ b/sass/ascribe_property.scss
@@ -30,11 +30,14 @@ $ascribe-red-error: rgb(169, 68, 66);
border-left: 3px solid rgba($ascribe-red-error, 1);
> div {
- > span {
- color: rgba($ascribe-red-error, 1);
- font-size: .9em;
- margin-right: 1em;
+ > p {
+ > span {
+ color: rgba($ascribe-red-error, 1);
+ font-size: .9em;
+ margin-right: 1em;
+ }
}
+
> input,
> textarea {
@@ -86,10 +89,13 @@ $ascribe-red-error: rgb(169, 68, 66);
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
- > span {
- color: rgba(0, 0, 0, .5);
- font-size: .9em;
- font-weight: normal;
+ > p {
+ height: 20px;
+ margin-bottom: 0;
+ > span {
+ font-size: .9em;
+ font-weight: normal;
+ }
}
> div {
@@ -107,6 +113,11 @@ $ascribe-red-error: rgb(169, 68, 66);
margin-top: 0 !important;
}
+ > .upload-button-wrapper {
+ margin-top: 1em;
+ margin-bottom: 1em;
+ }
+
> input,
> pre,
> textarea,
@@ -139,7 +150,7 @@ $ascribe-red-error: rgb(169, 68, 66);
padding: 0;
}
- > textarea{
+ > textarea {
color: #666;
margin-top: 1em;
padding: 0;
@@ -218,4 +229,4 @@ $ascribe-red-error: rgb(169, 68, 66);
> span > span {
margin-top: 0;
}
-}
+}
\ No newline at end of file
diff --git a/sass/ascribe_uploader.scss b/sass/ascribe_uploader.scss
index 7819eda0..49bc70e9 100644
--- a/sass/ascribe_uploader.scss
+++ b/sass/ascribe_uploader.scss
@@ -177,3 +177,15 @@
height: 12px;
}
+.upload-button-wrapper {
+ text-align: left;
+
+ .btn {
+ font-size: 1em;
+ margin-right: 1em;
+ }
+
+ span + .btn {
+ margin-left: 1em;
+ }
+}
\ No newline at end of file
diff --git a/sass/whitelabel/prize/index.scss b/sass/whitelabel/prize/index.scss
index 5bc75746..24645c8a 100644
--- a/sass/whitelabel/prize/index.scss
+++ b/sass/whitelabel/prize/index.scss
@@ -1,4 +1,5 @@
-@import 'sluice/sluice_custom_style';
+@import 'simple_prize/simple_prize_custom_style';
+@import 'portfolioreview/portfolioreview_custom_style';
.ascribe-prize-app {
border-radius: 0;
diff --git a/sass/whitelabel/prize/portfolioreview/portfolioreview_custom_style.scss b/sass/whitelabel/prize/portfolioreview/portfolioreview_custom_style.scss
new file mode 100644
index 00000000..d8ccd858
--- /dev/null
+++ b/sass/whitelabel/prize/portfolioreview/portfolioreview_custom_style.scss
@@ -0,0 +1,100 @@
+$pr--nav-fg-prim-color: black;
+$pr--button-color: $pr--nav-fg-prim-color;
+
+.client--portfolioreview {
+ padding-top: 0 !important;
+
+ .btn-wide,
+ .btn-default {
+ background-color: $pr--button-color;
+ border-color: $pr--button-color;
+
+ &:hover,
+ &:active,
+ &:focus,
+ &:active:hover,
+ &:active:focus,
+ &:active.focus,
+ &.active:hover,
+ &.active:focus,
+ &.active.focus {
+ background-color: lighten($pr--button-color, 20%);
+ border-color: lighten($pr--button-color, 20%);
+ }
+ }
+
+ .ascribe-property {
+ > p > span:not(> .span),
+ > textarea,
+ > input {
+ color: $pr--nav-fg-prim-color;
+ }
+ }
+
+ .ascribe-property-wrapper:hover {
+ border-left-color: lighten($pr--nav-fg-prim-color, 60%);
+ }
+
+ .is-focused {
+ border-left-color: $pr--nav-fg-prim-color !important;
+ background-color: lighten($pr--nav-fg-prim-color, 95%);
+ }
+
+ .register-piece--info {
+ text-align: center;
+
+ h1, h2 {
+ font-variant: small-caps;
+ }
+
+ h1 {
+ font-size: 5em;
+ color: #757575;
+ }
+
+ h2 {
+ font-size: 1.25em;
+ }
+
+ p {
+ margin-bottom: 0;
+ }
+
+ p + p {
+ margin-top: 0;
+ }
+
+ p:last-child {
+ margin-bottom: 1.5em;
+ }
+ }
+
+ .register-piece--form {
+ margin-top: 2em;
+ margin-bottom: 3em;
+
+ form {
+ border-top: none;
+ border-bottom: none;
+ }
+ }
+
+ .piece--hero {
+ text-align: center;
+ padding: 1em 0 1em 0;
+ margin-bottom: 3em;
+ border-bottom: 1px solid rgba(0, 0, 0, .1);
+
+ background-color: white;
+
+ h2 {
+ margin-top: 0;
+ }
+ }
+
+ .ascribe-property {
+ > p > span:not(> .span) {
+ text-transform: capitalize;
+ }
+ }
+}
\ No newline at end of file
diff --git a/sass/whitelabel/prize/sluice/sluice_custom_style.scss b/sass/whitelabel/prize/simple_prize/simple_prize_custom_style.scss
similarity index 100%
rename from sass/whitelabel/prize/sluice/sluice_custom_style.scss
rename to sass/whitelabel/prize/simple_prize/simple_prize_custom_style.scss
diff --git a/sass/whitelabel/wallet/ikonotv/ikonotv_custom_style.scss b/sass/whitelabel/wallet/ikonotv/ikonotv_custom_style.scss
index 52affdaf..70a5cd18 100644
--- a/sass/whitelabel/wallet/ikonotv/ikonotv_custom_style.scss
+++ b/sass/whitelabel/wallet/ikonotv/ikonotv_custom_style.scss
@@ -178,7 +178,7 @@ $ikono--font: 'Helvetica Neue', 'Helvetica', sans-serif !important;
border: none;
}
- .ascribe-property > span {
+ .ascribe-property > p > span {
color: white;
}