diff --git a/js/components/whitelabel/wallet/components/lumenus/lumenus_forms/lumenus_additional_data_form.js b/js/components/whitelabel/wallet/components/lumenus/lumenus_forms/lumenus_additional_data_form.js new file mode 100644 index 00000000..c0493ddd --- /dev/null +++ b/js/components/whitelabel/wallet/components/lumenus/lumenus_forms/lumenus_additional_data_form.js @@ -0,0 +1,129 @@ +'use strict'; + +import React from 'react'; + +import Form from '../../../../../ascribe_forms/form'; +import Property from '../../../../../ascribe_forms/property'; + +import GlobalNotificationModel from '../../../../../../models/global_notification_model'; +import GlobalNotificationActions from '../../../../../../actions/global_notification_actions'; + +import ApiUrls from '../../../../../../constants/api_urls'; +import AppConstants from '../../../../../../constants/application_constants'; + +import requests from '../../../../../../utils/requests'; + +import { getLangText } from '../../../../../../utils/lang_utils'; + + +let LumenusAdditionalDataForm = React.createClass({ + propTypes: { + handleSuccess: React.PropTypes.func, + piece: React.PropTypes.object.isRequired, + isInline: React.PropTypes.bool, + location: React.PropTypes.object + }, + + getDefaultProps() { + return { + isInline: false + }; + }, + + getInitialState() { + return { + isUploadReady: true + }; + }, + + handleSuccess() { + let notification = new GlobalNotificationModel(getLangText('Further details successfully updated'), 'success', 10000); + GlobalNotificationActions.appendGlobalNotification(notification); + }, + + 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 + }; + + }, + + render() { + let { piece, isInline, handleSuccess } = this.props; + let buttons, spinner, heading; + + if(!isInline) { + buttons = ( + + ); + + spinner = ( +
+ +
+ ); + + heading = ( +
+

+ {getLangText('Provide additional details')} +

+
+ ); + } + + if(piece && piece.id) { + return ( +
+ {heading} + + + + + + +
+ ); + } else { + return ( +
+ +
+ ); + } + } +}); + +export default LumenusAdditionalDataForm; diff --git a/js/components/whitelabel/wallet/components/lumenus/lumenus_register_piece.js b/js/components/whitelabel/wallet/components/lumenus/lumenus_register_piece.js new file mode 100644 index 00000000..9d671ee0 --- /dev/null +++ b/js/components/whitelabel/wallet/components/lumenus/lumenus_register_piece.js @@ -0,0 +1,195 @@ +'use strict'; + +import React from 'react'; +import { History } from 'react-router'; + +import Col from 'react-bootstrap/lib/Col'; +import Row from 'react-bootstrap/lib/Row'; + +import Property from '../../../../ascribe_forms/property'; +import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece'; + +import WhitelabelActions from '../../../../../actions/whitelabel_actions'; +import WhitelabelStore from '../../../../../stores/whitelabel_store'; + +import PieceListStore from '../../../../../stores/piece_list_store'; +import PieceListActions from '../../../../../actions/piece_list_actions'; + +import UserStore from '../../../../../stores/user_store'; +import UserActions from '../../../../../actions/user_actions'; + +import PieceStore from '../../../../../stores/piece_store'; +import PieceActions from '../../../../../actions/piece_actions'; + +import LumenusAdditionalDataForm from './lumenus_forms/lumenus_additional_data_form'; + +import SlidesContainer from '../../../../ascribe_slides_container/slides_container'; + +import { getLangText } from '../../../../../utils/lang_utils'; +import { setDocumentTitle } from '../../../../../utils/dom_utils'; +import { mergeOptions } from '../../../../../utils/general_utils'; + + +let LumenusRegisterPiece = React.createClass({ + propTypes: { + location: React.PropTypes.object + }, + + mixins: [History], + + getInitialState(){ + return mergeOptions( + UserStore.getState(), + PieceListStore.getState(), + PieceStore.getState(), + WhitelabelStore.getState(), + { + selectedLicense: 0, + isFineUploaderActive: false, + step: 0 + }); + }, + + componentDidMount() { + PieceListStore.listen(this.onChange); + UserStore.listen(this.onChange); + PieceStore.listen(this.onChange); + WhitelabelStore.listen(this.onChange); + UserActions.fetchCurrentUser(); + WhitelabelActions.fetchWhitelabel(); + + let queryParams = this.props.location.query; + + // Since every step of this register process is atomic, + // we may need to enter the process at step 1 or 2. + // If this is the case, we'll need the piece number to complete submission. + // It is encoded in the URL as a queryParam and we're checking for it here. + // + // We're using 'in' here as we want to know if 'piece_id' is present in the url, + // we don't care about the value. + if(queryParams && 'piece_id' in queryParams) { + PieceActions.fetchOne(queryParams.piece_id); + } + }, + + componentWillUnmount() { + PieceListStore.unlisten(this.onChange); + UserStore.unlisten(this.onChange); + PieceStore.unlisten(this.onChange); + WhitelabelStore.unlisten(this.onChange); + }, + + onChange(state) { + this.setState(state); + + if(this.state.currentUser && this.state.currentUser.email) { + // we should also make the fineuploader component editable again + this.setState({ + isFineUploaderActive: true + }); + } + }, + + handleRegisterSuccess(response){ + this.refreshPieceList(); + + // also start loading the piece for the next step + if(response && response.piece) { + PieceActions.updatePiece({}); + PieceActions.updatePiece(response.piece); + } + + this.incrementStep(); + + this.refs.slidesContainer.nextSlide({ piece_id: response.piece.id }); + }, + + handleAdditionalDataSuccess() { + // We need to refetch the piece again after submitting the additional data + // since we want it's otherData to be displayed when the user choses to click + // on the browsers back button. + PieceActions.fetchOne(this.state.piece.id); + + this.refreshPieceList(); + + this.history.pushState(null, `/collection`); + }, + + // We need to increase the step to lock the forms that are already filled out + incrementStep() { + // also increase step + let newStep = this.state.step + 1; + this.setState({ + step: newStep + }); + }, + + refreshPieceList() { + PieceListActions.fetchPieceList( + this.state.page, + this.state.pageSize, + this.state.searchTerm, + this.state.orderBy, + this.state.orderAsc, + this.state.filterBy + ); + }, + + // basically redirects to the second slide (index: 1), when the user is not logged in + onLoggedOut() { + this.history.pushState(null, '/login'); + }, + + render() { + setDocumentTitle(getLangText('Register a new piece')); + + return ( + +
+ + + 0} + enableLocalHashing={false} + headerMessage={getLangText('Consign to Lumenus')} + submitMessage={getLangText('Proceed to additional details')} + isFineUploaderActive={this.state.isFineUploaderActive} + handleSuccess={this.handleRegisterSuccess} + onLoggedOut={this.onLoggedOut} + location={this.props.location}> + + + + + + +
+
+ + + + + +
+
+ ); + } +}); + +export default LumenusRegisterPiece; diff --git a/js/components/whitelabel/wallet/wallet_routes.js b/js/components/whitelabel/wallet/wallet_routes.js index e258dfa7..e170d671 100644 --- a/js/components/whitelabel/wallet/wallet_routes.js +++ b/js/components/whitelabel/wallet/wallet_routes.js @@ -30,6 +30,7 @@ import IkonotvPieceContainer from './components/ikonotv/ikonotv_detail/ikonotv_p import IkonotvContractNotifications from './components/ikonotv/ikonotv_contract_notifications'; import LumenusPieceList from './components/lumenus/lumenus_piece_list'; +import LumenusRegisterPiece from './components/lumenus/lumenus_register_piece'; import CCRegisterPiece from './components/cc/cc_register_piece'; @@ -174,7 +175,7 @@ let ROUTES = { component={AuthProxyHandler({to: '/login', when: 'loggedOut'})(ContractSettings)}/>