From 5c2ec3ffb0f2b558ca8f6a9d55303908e6d7e116 Mon Sep 17 00:00:00 2001 From: diminator Date: Wed, 16 Sep 2015 23:27:38 +0200 Subject: [PATCH] bug fix signup query landing page redirect ikono: user acl proxy on submit button ikono: further details + slides --- js/components/ascribe_forms/form_loan.js | 6 +- js/components/ascribe_forms/form_signup.js | 1 - .../slides_container.js | 4 +- js/components/signup_container.js | 9 + .../ikonotv_accordion_list_item.js | 14 +- .../ascribe_detail/ikonotv_piece_container.js | 137 +++++++-------- ...form.js => ikonotv_artist_details_form.js} | 44 +++-- .../ikonotv_artwork_details_form.js | 164 ++++++++++++++++++ .../ikonotv/ikonotv_contract_notifications.js | 4 +- .../components/ikonotv/ikonotv_landing.js | 31 ++-- .../ikonotv/ikonotv_register_piece.js | 128 ++++++++++---- js/components/whitelabel/wallet/wallet_app.js | 2 +- 12 files changed, 395 insertions(+), 149 deletions(-) rename js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/{ikonotv_additional_data_form.js => ikonotv_artist_details_form.js} (64%) create mode 100644 js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artwork_details_form.js diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js index a1c31330..0c60fd7b 100644 --- a/js/components/ascribe_forms/form_loan.js +++ b/js/components/ascribe_forms/form_loan.js @@ -35,6 +35,7 @@ let LoanForm = React.createClass({ url: React.PropTypes.string, id: React.PropTypes.object, message: React.PropTypes.string, + createPublicContractAgreement: React.PropTypes.bool, handleSuccess: React.PropTypes.func }, @@ -44,7 +45,8 @@ let LoanForm = React.createClass({ showPersonalMessage: true, showEndDate: true, showStartDate: true, - showPassword: true + showPassword: true, + createPublicContractAgreement: true }; }, @@ -82,7 +84,7 @@ let LoanForm = React.createClass({ if (email) { ContractAgreementListActions.fetchAvailableContractAgreementList(email).then( (contractAgreementList) => { - if (!contractAgreementList) { + if (!contractAgreementList && this.props.createPublicContractAgreement) { ContractAgreementListActions.createContractAgreementFromPublicContract(email); } } diff --git a/js/components/ascribe_forms/form_signup.js b/js/components/ascribe_forms/form_signup.js index 8b4e4cf7..928afe38 100644 --- a/js/components/ascribe_forms/form_signup.js +++ b/js/components/ascribe_forms/form_signup.js @@ -67,7 +67,6 @@ let SignupForm = React.createClass({ }, getFormData() { - console.log(this.getQuery()); if (this.getQuery().token){ return {token: this.getQuery().token}; } diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js index 84dff61c..53092a38 100644 --- a/js/components/ascribe_slides_container/slides_container.js +++ b/js/components/ascribe_slides_container/slides_container.js @@ -178,7 +178,7 @@ let SlidesContainer = React.createClass({ let breadcrumbs = []; ReactAddons.Children.map(this.props.children, (child, i) => { - if(i >= this.state.startFrom && child.props['data-slide-title']) { + if(child && i >= this.state.startFrom && child.props['data-slide-title']) { breadcrumbs.push(child.props['data-slide-title']); } }); @@ -229,7 +229,7 @@ let SlidesContainer = React.createClass({ // since the default parameter of startFrom is -1, we do not need to check // if its actually present in the url bar, as it will just not match - if(i >= this.state.startFrom) { + if(child && i >= this.state.startFrom) { return ReactAddons.addons.cloneWithProps(child, { className: 'ascribe-slide', style: { diff --git a/js/components/signup_container.js b/js/components/signup_container.js index 46813b59..856e4af2 100644 --- a/js/components/signup_container.js +++ b/js/components/signup_container.js @@ -1,8 +1,12 @@ 'use strict'; import React from 'react'; +import Router from 'react-router'; import SignupForm from './ascribe_forms/form_signup'; +import { getLangText } from '../utils/lang_utils'; + +let Link = Router.Link; let SignupContainer = React.createClass({ getInitialState() { @@ -33,7 +37,12 @@ let SignupContainer = React.createClass({ return (
+
+ {getLangText('Already an ascribe user')}? {getLangText('Log in')}...
+ {getLangText('Forgot my password')}? {getLangText('Rescue me')}... +
+ ); } }); diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js index b716914a..2dd3cc2f 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js @@ -63,12 +63,16 @@ let IkonotvAccordionListItem = React.createClass({ return (
- + + + 0) { - return ( - ); - } - else { - - //We need to disable the normal acl_loan because we're inserting a custom acl_loan button - let availableAcls; - - if(this.state.piece && this.state.piece.acl && typeof this.state.piece.acl.acl_loan !== 'undefined') { - // make a copy to not have side effects - availableAcls = mergeOptions({}, this.state.piece.acl); - availableAcls.acl_loan = false; - } - - return ( - - - - - - - ); - } - }, - render() { if(this.state.piece && this.state.piece.title) { return ( @@ -152,14 +87,29 @@ let IkonotvPieceContainer = React.createClass({
- } - buttons={this.getActions()}> + }> + 0}> + + {return {'id': this.state.piece.id}; }} + label={getLangText('Personal note (private)')} + defaultValue={this.state.piece.private_note ? this.state.piece.private_note : null} + placeholder={getLangText('Enter your comments ...')} + editable={true} + successMessage={getLangText('Private note saved')} + url={ApiUrls.note_private_piece} + currentUser={this.state.currentUser}/> + + ); } else { @@ -172,4 +122,43 @@ let IkonotvPieceContainer = React.createClass({ } }); + +let IkonotvPieceDetails = React.createClass({ + propTypes: { + piece: React.PropTypes.object + }, + + render() { + if (this.props.piece && Object.keys(this.props.piece.extra_data).length !== 0){ + return ( + +
+ {Object.keys(this.props.piece.extra_data).map((data, i) => { + let label = data.replace('_', ' '); + return ( + ); + } + )} +
+
+
+ ); + } + return null; + } +}); + export default IkonotvPieceContainer; diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js similarity index 64% rename from js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js rename to js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js index 6f249c7b..cd98a94c 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js @@ -15,10 +15,9 @@ import AppConstants from '../../../../../../constants/application_constants'; import requests from '../../../../../../utils/requests'; import { getLangText } from '../../../../../../utils/lang_utils'; -//import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils'; -let IkonotvAdditionalDataForm = React.createClass({ +let IkonotvArtistDetailsForm = React.createClass({ propTypes: { handleSuccess: React.PropTypes.func.isRequired, piece: React.PropTypes.object.isRequired, @@ -77,7 +76,7 @@ let IkonotvAdditionalDataForm = React.createClass({ type="submit" className="btn ascribe-btn ascribe-btn-login" disabled={!this.state.isUploadReady || this.props.disabled}> - {getLangText('Proceed to loan')} + {getLangText('Proceed to artwork details')} } spinner={ @@ -87,28 +86,49 @@ let IkonotvAdditionalDataForm = React.createClass({ }>

- {getLangText('Provide supporting materials')} + {getLangText('Artist Details')}

+ defaultValue={this.props.piece.extra_data.artist_website} + placeholder={getLangText('The artist\'s website if present...')}/> + + + + + + + defaultValue={this.props.piece.extra_data.conceptual_overview} + placeholder={getLangText('Enter a short bio about the Artist')} + /> ); @@ -122,4 +142,4 @@ let IkonotvAdditionalDataForm = React.createClass({ } }); -export default IkonotvAdditionalDataForm; \ No newline at end of file +export default IkonotvArtistDetailsForm; \ No newline at end of file diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artwork_details_form.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artwork_details_form.js new file mode 100644 index 00000000..ffaa8fa5 --- /dev/null +++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artwork_details_form.js @@ -0,0 +1,164 @@ +'use strict'; + +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 FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader'; + +import ApiUrls from '../../../../../../constants/api_urls'; +import AppConstants from '../../../../../../constants/application_constants'; + +import requests from '../../../../../../utils/requests'; + +import { getLangText } from '../../../../../../utils/lang_utils'; + + +let IkonotvArtworkDetailsForm = React.createClass({ + propTypes: { + handleSuccess: React.PropTypes.func.isRequired, + piece: React.PropTypes.object.isRequired, + + disabled: React.PropTypes.bool + }, + + getInitialState() { + return { + isUploadReady: true + }; + }, + + getFormData() { + let extradata = {}; + let formRefs = this.refs.form.refs; + + // Put additional fields in extra data object + Object + .keys(formRefs) + .forEach((fieldName) => { + extradata[fieldName] = formRefs[fieldName].state.value; + }); + + return { + extradata: extradata, + piece_id: this.props.piece.id + }; + + }, + + uploadStarted() { + this.setState({ + isUploadReady: false + }); + }, + + setIsUploadReady(isReady) { + this.setState({ + isUploadReady: isReady + }); + }, + + render() { + if(this.props.piece && this.props.piece.id) { + return ( +
+ {getLangText('Proceed to loan')} + + } + spinner={ +
+ +
+ }> +
+

+ {getLangText('Artwork Details')} +

+
+ + + + + + + + + + + + + + + + + + +
+ ); + } else { + return ( +
+ +
+ ); + } + } +}); + +export default IkonotvArtworkDetailsForm; \ No newline at end of file diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js index beffe23a..60ec2208 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js @@ -12,6 +12,7 @@ import NotificationStore from '../../../../../stores/notification_store'; import UserStore from '../../../../../stores/user_store'; import WhitelabelStore from '../../../../../stores/whitelabel_store'; +import WhitelabelActions from '../../../../../actions/whitelabel_actions'; import GlobalNotificationModel from '../../../../../models/global_notification_model'; import GlobalNotificationActions from '../../../../../actions/global_notification_actions'; @@ -42,6 +43,7 @@ let IkonotvContractNotifications = React.createClass({ NotificationStore.listen(this.onChange); UserStore.listen(this.onChange); WhitelabelStore.listen(this.onChange); + WhitelabelActions.fetchWhitelabel(); if (this.state.contractAgreementListNotifications === null){ NotificationActions.fetchContractAgreementListNotifications(); } @@ -90,7 +92,7 @@ let IkonotvContractNotifications = React.createClass({ getAppendix() { let notifications = this.state.contractAgreementListNotifications[0]; let appendix = notifications.contract_agreement.appendix; - if (appendix) { + if (appendix && appendix.default) { return (

{getLangText('Appendix')}

diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js index 1e2d3803..7abfd62c 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js @@ -1,10 +1,10 @@ 'use strict'; import React from 'react'; +import Router from 'react-router'; import ButtonLink from 'react-router-bootstrap/lib/ButtonLink'; -import UserActions from '../../../../../actions/user_actions'; import UserStore from '../../../../../stores/user_store'; import { getLangText } from '../../../../../utils/lang_utils'; @@ -12,6 +12,8 @@ import { getLangText } from '../../../../../utils/lang_utils'; let IkonotvLanding = React.createClass({ + mixins: [Router.Navigation, Router.State], + getInitialState() { return UserStore.getState(); }, @@ -29,19 +31,20 @@ let IkonotvLanding = React.createClass({ }, getEnterButton() { + let redirect = 'signup'; + if(this.state.currentUser && this.state.currentUser.email) { - return ( - - {getLangText('ENTER')} - - ); - } else { - return ( - - {getLangText('ENTER')} - - ); + redirect = 'pieces'; } + else if (this.getQuery() && this.getQuery().redirect) { + redirect = this.getQuery().redirect; + } + console.log(redirect); + return ( + + {getLangText('ENTER')} + + ); }, render() { @@ -52,7 +55,7 @@ let IkonotvLanding = React.createClass({

PROTECT

-

& SHARE

+

& SHARE

Welcome to the ikonoTV

Registration Page

@@ -93,7 +96,7 @@ let IkonotvLanding = React.createClass({

Elizabeth Markevitch

-

Founder & CEO Markevitch Media GmbH

+

Founder & CEO Markevitch Media GmbH

{this.getEnterButton()}
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js index 6be9f9f6..ecb594c5 100644 --- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js +++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js @@ -21,7 +21,9 @@ import GlobalNotificationActions from '../../../../../actions/global_notificatio import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece'; import LoanForm from '../../../../ascribe_forms/form_loan'; -import IkonotvAdditionalDataForm from './ascribe_forms/ikonotv_additional_data_form'; + +import IkonotvArtistDetailsForm from './ascribe_forms/ikonotv_artist_details_form'; +import IkonotvArtworkDetailsForm from './ascribe_forms/ikonotv_artwork_details_form'; import SlidesContainer from '../../../../ascribe_slides_container/slides_container'; @@ -95,10 +97,14 @@ let IkonotvRegisterPiece = React.createClass({ if(response && response.piece) { PieceActions.updatePiece(response.piece); } + if (!this.canSubmit()) { + this.transitionTo('pieces'); + } + else { + this.incrementStep(); + this.refs.slidesContainer.nextSlide(); + } - this.incrementStep(); - - this.refs.slidesContainer.nextSlide(); }, handleAdditionalDataSuccess() { @@ -158,12 +164,83 @@ let IkonotvRegisterPiece = React.createClass({ this.transitionTo('login'); }, + canSubmit() { + if (this.state.currentUser && this.state.currentUser.acl) { + return ( + this.state.currentUser + && this.state.currentUser.acl + && !!this.state.currentUser.acl.acl_submit + ); + } + return false; + }, + + getSlideArtistDetails() { + if (this.canSubmit()) { + return ( +
+ + + 1} + handleSuccess={this.handleAdditionalDataSuccess} + piece={this.state.piece}/> + + +
+ ); + } + return null; + }, + + getSlideArtworkDetails() { + if (this.canSubmit()) { + return ( +
+ + + 1} + handleSuccess={this.handleAdditionalDataSuccess} + piece={this.state.piece}/> + + +
+ ); + } + return null; + }, + + getSlideLoan() { + if (this.canSubmit()) { + + let today = new Moment(); + let enddate = new Moment(); + enddate.add(1, 'years'); + return ( +
+ + + + + +
+ ); + } + return null; + }, + render() { - - let today = new Moment(); - let enddate = new Moment(); - enddate.add(1, 'years'); - return ( 0} enableLocalHashing={false} - headerMessage={getLangText('Submit to IkonoTV')} - submitMessage={getLangText('Submit')} + headerMessage={getLangText('Register work')} + submitMessage={getLangText('Register')} isFineUploaderActive={this.state.isFineUploaderActive} handleSuccess={this.handleRegisterSuccess} onLoggedOut={this.onLoggedOut} />
-
- - - 1} - handleSuccess={this.handleAdditionalDataSuccess} - piece={this.state.piece}/> - - -
-
- - - - - -
+ {this.getSlideArtistDetails()} + {this.getSlideArtworkDetails()} + {this.getSlideLoan()} ); } diff --git a/js/components/whitelabel/wallet/wallet_app.js b/js/components/whitelabel/wallet/wallet_app.js index 06bac15f..9a742f8b 100644 --- a/js/components/whitelabel/wallet/wallet_app.js +++ b/js/components/whitelabel/wallet/wallet_app.js @@ -19,7 +19,7 @@ let WalletApp = React.createClass({ let ROUTES = getRoutes(null, subdomain); let header = null; - if ((this.isActive('landing') || this.isActive('login') || this.isActive('signup')) + if ((this.isActive('landing') || this.isActive('login') || this.isActive('signup') || this.isActive('contract_notifications')) && (['ikonotv', 'cyland']).indexOf(subdomain) > -1) { header = (
);