mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 17:33:14 +01:00
boilerplate for loan process
This commit is contained in:
parent
9630d043db
commit
d5dc164810
@ -5,21 +5,15 @@ import React from 'react';
|
||||
import Row from 'react-bootstrap/lib/Row';
|
||||
import Col from 'react-bootstrap/lib/Col';
|
||||
|
||||
|
||||
import Form from './../ascribe_forms/form';
|
||||
import Property from './../ascribe_forms/property';
|
||||
|
||||
import PieceExtraDataForm from './../ascribe_forms/form_piece_extradata';
|
||||
|
||||
import ReactS3FineUploader from './../ascribe_uploader/react_s3_fine_uploader';
|
||||
|
||||
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 { getCookie } from '../../utils/fetch_api_utils';
|
||||
import FurtherDetailsFileuploader from './further_details_fileuploader';
|
||||
|
||||
let FurtherDetails = React.createClass({
|
||||
propTypes: {
|
||||
@ -90,93 +84,21 @@ let FurtherDetails = React.createClass({
|
||||
editable={this.props.editable}
|
||||
pieceId={this.props.pieceId}
|
||||
extraData={this.props.extraData} />
|
||||
<FileUploader
|
||||
submitKey={this.submitKey}
|
||||
setIsUploadReady={this.setIsUploadReady}
|
||||
isReadyForFormSubmission={this.isReadyForFormSubmission}
|
||||
editable={this.props.editable}
|
||||
pieceId={this.props.pieceId}
|
||||
otherData={this.props.otherData}/>
|
||||
<Form>
|
||||
<FurtherDetailsFileuploader
|
||||
submitKey={this.submitKey}
|
||||
setIsUploadReady={this.setIsUploadReady}
|
||||
isReadyForFormSubmission={this.isReadyForFormSubmission}
|
||||
editable={this.props.editable}
|
||||
pieceId={this.props.pieceId}
|
||||
otherData={this.props.otherData}/>
|
||||
</Form>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
let FileUploader = React.createClass({
|
||||
propTypes: {
|
||||
pieceId: React.PropTypes.number,
|
||||
otherData: React.PropTypes.object,
|
||||
setIsUploadReady: React.PropTypes.func,
|
||||
submitKey: React.PropTypes.func,
|
||||
isReadyForFormSubmission: React.PropTypes.func,
|
||||
editable: React.PropTypes.bool
|
||||
},
|
||||
|
||||
render() {
|
||||
// Essentially there a three cases important to the fileuploader
|
||||
//
|
||||
// 1. there is no other_data => do not show the fileuploader at all
|
||||
// 2. there is other_data, but user has no edit rights => show fileuploader but without action buttons
|
||||
// 3. both other_data and editable are defined or true => show fileuploade with all action buttons
|
||||
if (!this.props.editable && !this.props.otherData){
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Form>
|
||||
<Property
|
||||
label="Additional files (max. 10MB)">
|
||||
<ReactS3FineUploader
|
||||
keyRoutine={{
|
||||
url: AppConstants.serverUrl + 's3/key/',
|
||||
fileClass: 'otherdata',
|
||||
pieceId: this.props.pieceId
|
||||
}}
|
||||
createBlobRoutine={{
|
||||
url: ApiUrls.blob_otherdatas,
|
||||
pieceId: this.props.pieceId
|
||||
}}
|
||||
validation={{
|
||||
itemLimit: 100000,
|
||||
sizeLimit: '10000000'
|
||||
}}
|
||||
submitKey={this.props.submitKey}
|
||||
setIsUploadReady={this.props.setIsUploadReady}
|
||||
isReadyForFormSubmission={this.props.isReadyForFormSubmission}
|
||||
session={{
|
||||
endpoint: AppConstants.serverUrl + 'api/blob/otherdatas/fineuploader_session/',
|
||||
customHeaders: {
|
||||
'X-CSRFToken': getCookie(AppConstants.csrftoken)
|
||||
},
|
||||
params: {
|
||||
'pk': this.props.otherData ? this.props.otherData.id : null
|
||||
},
|
||||
cors: {
|
||||
expected: true,
|
||||
sendCredentials: true
|
||||
}
|
||||
}}
|
||||
signature={{
|
||||
endpoint: AppConstants.serverUrl + 's3/signature/',
|
||||
customHeaders: {
|
||||
'X-CSRFToken': getCookie(AppConstants.csrftoken)
|
||||
}
|
||||
}}
|
||||
deleteFile={{
|
||||
enabled: true,
|
||||
method: 'DELETE',
|
||||
endpoint: AppConstants.serverUrl + 's3/delete',
|
||||
customHeaders: {
|
||||
'X-CSRFToken': getCookie(AppConstants.csrftoken)
|
||||
}
|
||||
}}
|
||||
areAssetsDownloadable={true}
|
||||
areAssetsEditable={this.props.editable}/>
|
||||
</Property>
|
||||
<hr />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default FurtherDetails;
|
||||
|
95
js/components/ascribe_detail/further_details_fileuploader.js
Normal file
95
js/components/ascribe_detail/further_details_fileuploader.js
Normal file
@ -0,0 +1,95 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Property from './../ascribe_forms/property';
|
||||
|
||||
import ReactS3FineUploader from './../ascribe_uploader/react_s3_fine_uploader';
|
||||
|
||||
import ApiUrls from '../../constants/api_urls';
|
||||
import AppConstants from '../../constants/application_constants';
|
||||
|
||||
import { getCookie } from '../../utils/fetch_api_utils';
|
||||
|
||||
let FurtherDetailsFileuploader = React.createClass({
|
||||
propTypes: {
|
||||
pieceId: React.PropTypes.number,
|
||||
otherData: React.PropTypes.object,
|
||||
setIsUploadReady: React.PropTypes.func,
|
||||
submitKey: React.PropTypes.func,
|
||||
isReadyForFormSubmission: React.PropTypes.func,
|
||||
editable: React.PropTypes.bool,
|
||||
multiple: React.PropTypes.bool
|
||||
},
|
||||
|
||||
getDefaultProps() {
|
||||
return {
|
||||
multiple: false
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
// Essentially there a three cases important to the fileuploader
|
||||
//
|
||||
// 1. there is no other_data => do not show the fileuploader at all
|
||||
// 2. there is other_data, but user has no edit rights => show fileuploader but without action buttons
|
||||
// 3. both other_data and editable are defined or true => show fileuploade with all action buttons
|
||||
if (!this.props.editable && !this.props.otherData){
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Property
|
||||
label="Additional files (max. 10MB)">
|
||||
<ReactS3FineUploader
|
||||
keyRoutine={{
|
||||
url: AppConstants.serverUrl + 's3/key/',
|
||||
fileClass: 'otherdata',
|
||||
pieceId: this.props.pieceId
|
||||
}}
|
||||
createBlobRoutine={{
|
||||
url: ApiUrls.blob_otherdatas,
|
||||
pieceId: this.props.pieceId
|
||||
}}
|
||||
validation={{
|
||||
itemLimit: 100000,
|
||||
sizeLimit: '10000000'
|
||||
}}
|
||||
submitKey={this.props.submitKey}
|
||||
setIsUploadReady={this.props.setIsUploadReady}
|
||||
isReadyForFormSubmission={this.props.isReadyForFormSubmission}
|
||||
session={{
|
||||
endpoint: AppConstants.serverUrl + 'api/blob/otherdatas/fineuploader_session/',
|
||||
customHeaders: {
|
||||
'X-CSRFToken': getCookie(AppConstants.csrftoken)
|
||||
},
|
||||
params: {
|
||||
'pk': this.props.otherData ? this.props.otherData.id : null
|
||||
},
|
||||
cors: {
|
||||
expected: true,
|
||||
sendCredentials: true
|
||||
}
|
||||
}}
|
||||
signature={{
|
||||
endpoint: AppConstants.serverUrl + 's3/signature/',
|
||||
customHeaders: {
|
||||
'X-CSRFToken': getCookie(AppConstants.csrftoken)
|
||||
}
|
||||
}}
|
||||
deleteFile={{
|
||||
enabled: true,
|
||||
method: 'DELETE',
|
||||
endpoint: AppConstants.serverUrl + 's3/delete',
|
||||
customHeaders: {
|
||||
'X-CSRFToken': getCookie(AppConstants.csrftoken)
|
||||
}
|
||||
}}
|
||||
areAssetsDownloadable={true}
|
||||
areAssetsEditable={this.props.editable}
|
||||
multiple={this.props.multiple}/>
|
||||
</Property>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default FurtherDetailsFileuploader;
|
@ -2,6 +2,8 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classnames from 'classnames';
|
||||
|
||||
import Button from 'react-bootstrap/lib/Button';
|
||||
|
||||
import Form from './form';
|
||||
@ -20,12 +22,25 @@ import { getLangText } from '../../utils/lang_utils';
|
||||
|
||||
let LoanForm = React.createClass({
|
||||
propTypes: {
|
||||
fullform: React.PropTypes.bool,
|
||||
email: React.PropTypes.string,
|
||||
gallery: React.PropTypes.string,
|
||||
startdate: React.PropTypes.string,
|
||||
enddate: React.PropTypes.string,
|
||||
showPersonalMessage: React.PropTypes.bool,
|
||||
|
||||
url: React.PropTypes.string,
|
||||
id: React.PropTypes.object,
|
||||
message: React.PropTypes.string,
|
||||
handleSuccess: React.PropTypes.func
|
||||
},
|
||||
|
||||
getDefaultProps() {
|
||||
return {
|
||||
fullform: false
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return LoanContractStore.getState();
|
||||
},
|
||||
@ -87,60 +102,87 @@ let LoanForm = React.createClass({
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
getButtons() {
|
||||
if(this.props.fullform) {
|
||||
return (
|
||||
<button
|
||||
type="submit"
|
||||
className="btn ascribe-btn ascribe-btn-login">
|
||||
{getLangText('Finish process')}
|
||||
</button>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="modal-footer">
|
||||
<p className="pull-right">
|
||||
<Button
|
||||
className="btn btn-default btn-sm ascribe-margin-1px"
|
||||
type="submit">
|
||||
{getLangText('LOAN')}
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Form
|
||||
className={classnames({'ascribe-form-bordered': this.props.fullform})}
|
||||
ref='form'
|
||||
url={this.props.url}
|
||||
getFormData={this.getFormData}
|
||||
handleSuccess={this.props.handleSuccess}
|
||||
buttons={
|
||||
<div className="modal-footer">
|
||||
<p className="pull-right">
|
||||
<Button
|
||||
className="btn btn-default btn-sm ascribe-margin-1px"
|
||||
type="submit">
|
||||
{getLangText('LOAN')}
|
||||
</Button>
|
||||
</p>
|
||||
</div>}
|
||||
buttons={this.getButtons()}
|
||||
spinner={
|
||||
<div className="modal-footer">
|
||||
<img src={AppConstants.baseUrl + 'static/img/ascribe_animated_small.gif'} />
|
||||
</div>}>
|
||||
<div className={classnames({'ascribe-form-header': true, 'hidden': !this.props.fullform})}>
|
||||
<h3>Loan</h3>
|
||||
</div>
|
||||
<Property
|
||||
name='loanee'
|
||||
label={getLangText('Loanee Email')}
|
||||
onBlur={this.handleOnBlur}>
|
||||
onBlur={this.handleOnBlur}
|
||||
editable={!this.props.email}>
|
||||
<input
|
||||
value={this.props.email}
|
||||
type="email"
|
||||
placeholder={getLangText('Email of the loanee')}
|
||||
required/>
|
||||
</Property>
|
||||
<Property
|
||||
name='gallery_name'
|
||||
label={getLangText('Gallery/exhibition (optional)')}>
|
||||
label={getLangText('Gallery/exhibition (optional)')}
|
||||
editable={!this.props.gallery}>
|
||||
<input
|
||||
value={this.props.gallery}
|
||||
type="text"
|
||||
placeholder={getLangText('Gallery/exhibition (optional)')}/>
|
||||
</Property>
|
||||
<Property
|
||||
name='startdate'
|
||||
label={getLangText('Start date')}>
|
||||
label={getLangText('Start date')}
|
||||
hidden={!this.props.startdate}>
|
||||
<InputDate
|
||||
value={this.props.startdate}
|
||||
placeholderText={getLangText('Loan start date')} />
|
||||
</Property>
|
||||
<Property
|
||||
name='enddate'
|
||||
label={getLangText('End date')}>
|
||||
label={getLangText('End date')}
|
||||
hidden={!this.props.enddate}>
|
||||
<InputDate
|
||||
value={this.props.enddate}
|
||||
placeholderText={getLangText('Loan end date')} />
|
||||
</Property>
|
||||
<Property
|
||||
name='loan_message'
|
||||
label={getLangText('Personal Message')}
|
||||
editable={true}>
|
||||
editable={true}
|
||||
hidden={this.props.showPersonalMessage}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
editable={true}
|
||||
|
@ -0,0 +1,116 @@
|
||||
'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 CylandAdditionalDataForm = React.createClass({
|
||||
propTypes: {
|
||||
handleSuccess: React.PropTypes.func.isRequired,
|
||||
piece: React.PropTypes.object.isRequired
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
isUploadReady: false
|
||||
};
|
||||
},
|
||||
|
||||
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
|
||||
};
|
||||
},
|
||||
|
||||
setIsUploadReady(isReady) {
|
||||
this.setState({
|
||||
isUploadReady: isReady
|
||||
});
|
||||
},
|
||||
|
||||
isReadyForFormSubmission() {
|
||||
return true;
|
||||
},
|
||||
|
||||
render() {
|
||||
if(this.props.piece && this.props.piece.id) {
|
||||
return (
|
||||
<Form
|
||||
className="ascribe-form-bordered"
|
||||
ref='form'
|
||||
url={requests.prepareUrl(ApiUrls.piece_extradata, {piece_id: this.props.piece.id})}
|
||||
handleSuccess={this.props.handleSuccess}
|
||||
getFormData={this.getFormData}
|
||||
buttons={
|
||||
<button
|
||||
type="submit"
|
||||
className="btn ascribe-btn ascribe-btn-login"
|
||||
disabled={!this.state.isUploadReady}>
|
||||
{getLangText('Proceed to loan')}
|
||||
</button>
|
||||
}
|
||||
spinner={
|
||||
<div className="modal-footer">
|
||||
<img src={AppConstants.baseUrl + 'static/img/ascribe_animated_small.gif'} />
|
||||
</div>
|
||||
}>
|
||||
<FurtherDetailsFileuploader
|
||||
submitKey={this.submitKey}
|
||||
setIsUploadReady={this.setIsUploadReady}
|
||||
isReadyForFormSubmission={this.isReadyForFormSubmission}
|
||||
editable={true}
|
||||
pieceId={this.props.piece.id}
|
||||
otherData={this.props.piece.other_data}
|
||||
multiple={false}/>
|
||||
<Property
|
||||
name='artist_bio'
|
||||
label={getLangText('Artist Biography')}
|
||||
editable={true}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
editable={true}
|
||||
placeholder={getLangText('Enter the artist\'s biography...')}
|
||||
required="required"/>
|
||||
</Property>
|
||||
<Property
|
||||
name='conceptual_overview'
|
||||
label={getLangText('Conceptual Overview')}
|
||||
editable={true}>
|
||||
<InputTextAreaToggable
|
||||
rows={1}
|
||||
editable={true}
|
||||
placeholder={getLangText('Enter a conceptual overview...')}
|
||||
required="required"/>
|
||||
</Property>
|
||||
</Form>
|
||||
);
|
||||
} else {
|
||||
return <span>First register the piece.</span>;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default CylandAdditionalDataForm;
|
@ -9,7 +9,6 @@ import Row from 'react-bootstrap/lib/Row';
|
||||
import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece';
|
||||
|
||||
import Property from '../../../../ascribe_forms/property';
|
||||
import InputTextAreaToggable from '../../../../ascribe_forms/input_textarea_toggable';
|
||||
import InputCheckbox from '../../../../ascribe_forms/input_checkbox';
|
||||
|
||||
import PieceListStore from '../../../../../stores/piece_list_store';
|
||||
@ -18,36 +17,51 @@ 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 GlobalNotificationModel from '../../../../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
|
||||
|
||||
import CylandAdditionalDataForm from '../ascribe_forms/cyland_additional_data_form';
|
||||
|
||||
import LoanForm from '../../../../ascribe_forms/form_loan';
|
||||
|
||||
import SlidesContainer from '../../../../ascribe_slides_container/slides_container';
|
||||
|
||||
import ApiUrls from '../../../../../constants/api_urls';
|
||||
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
||||
import { mergeOptions, dateToString } from '../../../../../utils/general_utils';
|
||||
import { getAclFormMessage } from '../../../../../utils/form_utils';
|
||||
|
||||
let CylandRegisterPiece = React.createClass({
|
||||
|
||||
mixins: [Router.Navigation],
|
||||
|
||||
getInitialState(){
|
||||
return mergeOptions(
|
||||
UserStore.getState(),
|
||||
PieceListStore.getState(),
|
||||
PieceStore.getState(),
|
||||
{
|
||||
selectedLicense: 0,
|
||||
isFineUploaderActive: false
|
||||
});
|
||||
},
|
||||
|
||||
mixins: [Router.Navigation],
|
||||
|
||||
componentDidMount() {
|
||||
PieceListStore.listen(this.onChange);
|
||||
UserStore.listen(this.onChange);
|
||||
PieceStore.listen(this.onChange);
|
||||
|
||||
UserActions.fetchCurrentUser();
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PieceListStore.unlisten(this.onChange);
|
||||
UserStore.unlisten(this.onChange);
|
||||
PieceStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
@ -61,9 +75,7 @@ let CylandRegisterPiece = React.createClass({
|
||||
}
|
||||
},
|
||||
|
||||
handleSuccess(response){
|
||||
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
handleRegisterSuccess(response){
|
||||
|
||||
// once the user was able to register a piece successfully, we need to make sure to keep
|
||||
// the piece list up to date
|
||||
@ -76,7 +88,16 @@ let CylandRegisterPiece = React.createClass({
|
||||
this.state.filterBy
|
||||
);
|
||||
|
||||
this.transitionTo('piece', {pieceId: response.piece.id});
|
||||
// also start loading the piece for the next step
|
||||
if(response && response.piece) {
|
||||
PieceActions.updatePiece(response.piece);
|
||||
}
|
||||
|
||||
this.refs.slidesContainer.setSlideNum(1);
|
||||
},
|
||||
|
||||
handleAdditionalDataSuccess() {
|
||||
this.refs.slidesContainer.setSlideNum(2);
|
||||
},
|
||||
|
||||
changeSlide() {
|
||||
@ -93,11 +114,14 @@ let CylandRegisterPiece = React.createClass({
|
||||
},
|
||||
|
||||
render() {
|
||||
|
||||
let today = new Date();
|
||||
let datetimeWhenWeAllWillBeFlyingCoolHoverboardsAndDinosaursWillLiveAgain = new Date();
|
||||
datetimeWhenWeAllWillBeFlyingCoolHoverboardsAndDinosaursWillLiveAgain.setFullYear(3000);
|
||||
|
||||
return (
|
||||
<SlidesContainer ref="slidesContainer">
|
||||
<div
|
||||
onClick={this.changeSlide}
|
||||
onFocus={this.changeSlide}>
|
||||
<div>
|
||||
<Row className="no-margin">
|
||||
<Col xs={12} sm={10} md={8} smOffset={1} mdOffset={2}>
|
||||
<RegisterPieceForm
|
||||
@ -105,7 +129,7 @@ let CylandRegisterPiece = React.createClass({
|
||||
headerMessage={getLangText('Submit to Cyland Archive')}
|
||||
submitMessage={getLangText('Submit')}
|
||||
isFineUploaderActive={this.state.isFineUploaderActive}
|
||||
handleSuccess={this.handleSuccess}
|
||||
handleSuccess={this.handleRegisterSuccess}
|
||||
onLoggedOut={this.onLoggedOut}>
|
||||
<Property
|
||||
name="terms"
|
||||
@ -114,7 +138,7 @@ let CylandRegisterPiece = React.createClass({
|
||||
<InputCheckbox>
|
||||
<span>
|
||||
{' ' + getLangText('I agree to the Terms of Service the art price') + ' '}
|
||||
(<a href="https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/sluice/terms.pdf" target="_blank" style={{fontSize: '0.9em', color: 'rgba(0,0,0,0.7)'}}>
|
||||
(<a href="https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/cyland/terms_and_contract.pdf" target="_blank" style={{fontSize: '0.9em', color: 'rgba(0,0,0,0.7)'}}>
|
||||
{getLangText('read')}
|
||||
</a>)
|
||||
</span>
|
||||
@ -125,7 +149,28 @@ let CylandRegisterPiece = React.createClass({
|
||||
</Row>
|
||||
</div>
|
||||
<div>
|
||||
{/* next slide */}
|
||||
<Row className="no-margin">
|
||||
<Col xs={12} sm={10} md={8} smOffset={1} mdOffset={2}>
|
||||
<CylandAdditionalDataForm
|
||||
handleSuccess={this.handleAdditionalDataSuccess}
|
||||
piece={this.state.piece}/>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
<div>
|
||||
<Row className="no-margin">
|
||||
<Col xs={12} sm={10} md={8} smOffset={1} mdOffset={2}>
|
||||
<LoanForm
|
||||
fullform={true}
|
||||
message={getAclFormMessage('acl_loan', '\"' + this.state.piece.title + '\"', this.state.currentUser.username)}
|
||||
id={{piece_id: this.state.piece.id}}
|
||||
url={ApiUrls.ownership_loans_pieces}
|
||||
email="videoarchive@cyland.org"
|
||||
gallery="Cyland Archive"
|
||||
startdate={dateToString(today)}
|
||||
enddate={dateToString(datetimeWhenWeAllWillBeFlyingCoolHoverboardsAndDinosaursWillLiveAgain)}/>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</SlidesContainer>
|
||||
);
|
||||
|
@ -178,3 +178,25 @@ function _mergeOptions(obj1, obj2) {
|
||||
export function escapeHTML(s) {
|
||||
return document.createElement('div').appendChild(document.createTextNode(s)).parentNode.innerHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a date object to a string.
|
||||
* Taken from: http://stackoverflow.com/a/4929629/1263876
|
||||
* @param {date} date a javascript date
|
||||
* @return {string} a string, in format: DD-MM-YYY
|
||||
*/
|
||||
export function dateToString(date) {
|
||||
var dd = date.getDate();
|
||||
var mm = date.getMonth() + 1; //January is 0!
|
||||
var yyyy = date.getFullYear();
|
||||
|
||||
if(dd < 10) {
|
||||
dd = '0' + dd;
|
||||
}
|
||||
|
||||
if(mm < 10) {
|
||||
mm = '0' + mm;
|
||||
}
|
||||
|
||||
return dd + '-' + mm + '-' + yyyy;
|
||||
}
|
Loading…
Reference in New Issue
Block a user