From d90a4f97dbc55eb11b841faa41998a2cfcd7b538 Mon Sep 17 00:00:00 2001 From: ddejongh Date: Mon, 1 Jun 2015 13:02:53 +0200 Subject: [PATCH] loan --- index.html | 1 + js/components/ascribe_forms/form_loan.js | 107 +++++++++++++++--- js/components/ascribe_forms/input_checkbox.js | 40 +++++++ js/components/ascribe_forms/input_date.js | 53 +++++++++ js/components/ascribe_forms/input_hidden.js | 33 ++++++ js/components/ascribe_forms/input_text.js | 3 +- js/components/ascribe_modal/modal_loan.js | 24 ++-- js/components/edition.js | 2 + js/constants/api_urls.js | 1 + js/fetchers/ownership_fetcher.js | 24 ++++ package.json | 3 +- sass/main.scss | 8 ++ 12 files changed, 270 insertions(+), 29 deletions(-) create mode 100644 js/components/ascribe_forms/input_checkbox.js create mode 100644 js/components/ascribe_forms/input_date.js create mode 100644 js/components/ascribe_forms/input_hidden.js create mode 100644 js/fetchers/ownership_fetcher.js diff --git a/index.html b/index.html index 4c875443..dec0a732 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,7 @@ +
diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js index 708ab70e..1822b8ce 100644 --- a/js/components/ascribe_forms/form_loan.js +++ b/js/components/ascribe_forms/form_loan.js @@ -5,46 +5,122 @@ import React from 'react'; import ApiUrls from '../../constants/api_urls'; import FormMixin from '../../mixins/form_mixin'; import InputText from './input_text'; +import InputHidden from './input_hidden'; +import InputCheckbox from './input_checkbox'; +//import InputDate from './input_date'; import InputTextArea from './input_textarea'; +import OwnershipFetcher from '../../fetchers/ownership_fetcher' import ButtonSubmitOrClose from './button_submit_close'; -let ConsignForm = React.createClass({ +let LoanForm = React.createClass({ mixins: [FormMixin], url() { - return ApiUrls.ownership_consigns + return ApiUrls.ownership_loans + }, + componentDidMount(){ + this.setState({contract_key: null, + contract_url: null, + loaneeHasContract: false}); }, getFormData() { return { bitcoin_id: this.props.edition.bitcoin_id, - consignee: this.refs.consignee.state.value, - consign_message: this.refs.consign_message.state.value, - password: this.refs.password.state.value + loanee: this.refs.loanee.state.value, + gallery_name: this.refs.gallery_name.state.value, + startdate: this.refs.startdate.state.value, + enddate: this.refs.enddate.state.value, + loan_message: this.refs.loan_message.state.value, + password: this.refs.password.state.value, + terms: this.refs.terms.state.value } }, + handleLoanEmailBlur(e){ + OwnershipFetcher.fetchLoanContract(this.refs.loanee.state.value) + .then((res) => { + if (res && res.length > 0) { + this.setState({contract_key: res[0].s3Key, + contract_url: res[0].s3Url, + loaneeHasContract: true}); + } + else{ + this.resetLoanContract(); + } + }) + .catch((err) => { + console.log(err); + this.resetLoanContract(); + }); + }, + resetLoanContract(){ + this.setState({contract_key: null, + contract_url: null, + loaneeHasContract: false + }); + }, renderForm() { let title = this.props.edition.title; let username = this.props.currentUser.username; let message = `Hi, -I consign \" ${title} \" to you. +I loan \" ${title} \" to you. Truly yours, ${username}`; - + let contract = ; + if (this.state.loaneeHasContract){ + let label =
+ I agree to the  + + terms of {this.refs.loanee.state.value} + +
; + contract = + } return ( -
- + + + +
+
+ +
+
+ +
+
@@ -54,8 +130,9 @@ ${username}`; required="required" type="password" submitted={this.state.submitted}/> - @@ -63,4 +140,4 @@ ${username}`; } }); -export default ConsignForm; \ No newline at end of file +export default LoanForm; \ No newline at end of file diff --git a/js/components/ascribe_forms/input_checkbox.js b/js/components/ascribe_forms/input_checkbox.js new file mode 100644 index 00000000..c1ecda1a --- /dev/null +++ b/js/components/ascribe_forms/input_checkbox.js @@ -0,0 +1,40 @@ +import React from 'react'; + +import AlertMixin from '../../mixins/alert_mixin' + +let InputCheckbox = React.createClass({ + + mixins : [AlertMixin], + + getInitialState() { + return {value: null, + alerts: null // needed in AlertMixin + }; + }, + handleChange(event) { + this.setState({value: event.target.value}); + }, + render() { + let alerts = (this.props.submitted) ? null : this.state.alerts; + return ( +
+ {alerts} +
+
+ +
+
+
+ ); + + } +}); + +export default InputCheckbox; \ No newline at end of file diff --git a/js/components/ascribe_forms/input_date.js b/js/components/ascribe_forms/input_date.js new file mode 100644 index 00000000..aa3e9e94 --- /dev/null +++ b/js/components/ascribe_forms/input_date.js @@ -0,0 +1,53 @@ +import React from 'react'; + +import AlertMixin from '../../mixins/alert_mixin' +import DatePicker from 'react-datepicker/dist/react-datepicker' + +let InputDate = React.createClass({ + + mixins : [AlertMixin], + + getInitialState() { + return {value: '2015-01-01', + alerts: null // needed in AlertMixin + }; + }, + handleChange(moment_date) { + this.setState({value: moment_date.format("YYYY-MM-DD")}); + }, + isValidDate: function (str) { + return ( + /^[0-9]{4}$/.test(str) && + moment(str, 'YYYY-MM-DD').isValid() + ); + }, + render: function () { + let className = "form-control input-text-ascribe"; + let alerts = (this.props.submitted) ? null : this.state.alerts; + return ( + + ); + //return ( + //
+ // + // + // + // + //
+ //) + + + } +}); + +export default InputDate; \ No newline at end of file diff --git a/js/components/ascribe_forms/input_hidden.js b/js/components/ascribe_forms/input_hidden.js new file mode 100644 index 00000000..96ff95ce --- /dev/null +++ b/js/components/ascribe_forms/input_hidden.js @@ -0,0 +1,33 @@ +import React from 'react'; + +import AlertMixin from '../../mixins/alert_mixin' + +let InputHidden = React.createClass({ + + mixins : [AlertMixin], + + getInitialState() { + return {value: this.props.value, + alerts: null // needed in AlertMixin + }; + }, + handleChange(event) { + this.setState({value: event.target.value}); + }, + render() { + let alerts = (this.props.submitted) ? null : this.state.alerts; + return ( +
+ {alerts} + +
+ ); + + } +}); + +export default InputHidden; \ No newline at end of file diff --git a/js/components/ascribe_forms/input_text.js b/js/components/ascribe_forms/input_text.js index d242de86..b9e7287a 100644 --- a/js/components/ascribe_forms/input_text.js +++ b/js/components/ascribe_forms/input_text.js @@ -24,7 +24,8 @@ let InputText = React.createClass({ placeholder={this.props.placeHolder} required={this.props.required} type={this.props.type} - onChange={this.handleChange}/> + onChange={this.handleChange} + onBlur={this.props.onBlur}/> ); diff --git a/js/components/ascribe_modal/modal_loan.js b/js/components/ascribe_modal/modal_loan.js index bcd47973..aed475b1 100644 --- a/js/components/ascribe_modal/modal_loan.js +++ b/js/components/ascribe_modal/modal_loan.js @@ -4,18 +4,18 @@ import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger'; import ModalTrigger from 'react-bootstrap/lib/ModalTrigger'; import Tooltip from 'react-bootstrap/lib/Tooltip'; -import ConsignForm from '../ascribe_forms/form_consign' +import LoanForm from '../ascribe_forms/form_loan' import ModalMixin from '../../mixins/modal_mixin' -let ConsignModalButton = React.createClass({ +let LoanModalButton = React.createClass({ render() { return ( Have someone else sell the artwork}> - }> + overlay={Loan your artwork for a limited period of time}> + }>
- CONSIGN + LOAN
@@ -23,16 +23,16 @@ let ConsignModalButton = React.createClass({ } }); -let ConsignModal = React.createClass({ +let LoanModal = React.createClass({ mixins : [ModalMixin], render() { return ( - +
- +
) @@ -40,4 +40,4 @@ let ConsignModal = React.createClass({ }); -export default ConsignModalButton; +export default LoanModalButton; diff --git a/js/components/edition.js b/js/components/edition.js index 2c5279c1..18c09675 100644 --- a/js/components/edition.js +++ b/js/components/edition.js @@ -1,6 +1,7 @@ import React from 'react'; import ImageViewer from './ascribe_media/image_viewer'; +import LoanModalButton from './ascribe_modal/modal_loan'; import ConsignModalButton from './ascribe_modal/modal_consign'; import UnConsignModalButton from './ascribe_modal/modal_unconsign'; import UnConsignRequestModalButton from './ascribe_modal/modal_unconsign_request'; @@ -50,6 +51,7 @@ let EditionDetails = React.createClass({
+ diff --git a/js/constants/api_urls.js b/js/constants/api_urls.js index 6099710b..c1288fcd 100644 --- a/js/constants/api_urls.js +++ b/js/constants/api_urls.js @@ -3,6 +3,7 @@ import AppConstants from './application_constants'; let apiUrls = { 'ownership_shares_mail' : AppConstants.baseUrl + 'ownership/shares/mail/', 'ownership_transfers' : AppConstants.baseUrl + 'ownership/transfers/', + 'ownership_loans' : AppConstants.baseUrl + 'ownership/loans/', 'ownership_consigns' : AppConstants.baseUrl + 'ownership/consigns/', 'ownership_unconsigns' : AppConstants.baseUrl + 'ownership/unconsigns/', 'ownership_unconsigns_request' : AppConstants.baseUrl + 'ownership/unconsigns/request/' diff --git a/js/fetchers/ownership_fetcher.js b/js/fetchers/ownership_fetcher.js new file mode 100644 index 00000000..94050860 --- /dev/null +++ b/js/fetchers/ownership_fetcher.js @@ -0,0 +1,24 @@ +import fetch from 'isomorphic-fetch'; + +import AppConstants from '../constants/application_constants'; +import FetchApiUtils from '../utils/fetch_api_utils'; + + +let OwnershipFetcher = { + /** + * Fetch one user from the API. + * If no arg is supplied, load the current user + * + */ + fetchLoanContract(email) { + return fetch(AppConstants.baseUrl + 'ownership/loans/contract/?loanee=' + email, { + headers: { + 'Authorization': 'Basic ' + AppConstants.debugCredentialBase64 + } + }).then( + (res) => res.json() + ); + } +}; + +export default OwnershipFetcher; diff --git a/package.json b/package.json index 38710b47..adc61664 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "react": "^0.13.2", "react-router": "^0.13.3", "uglifyjs": "^2.4.10", - "react-bootstrap": "~0.22.6" + "react-bootstrap": "~0.22.6", + "react-datepicker": "~0.8.0" }, "jest": { "scriptPreprocessor": "node_modules/babel-jest", diff --git a/sass/main.scss b/sass/main.scss index cd0edf3a..d1a54ee8 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -163,6 +163,14 @@ height: 13em !important; } +.input-checkbox-ascribe { + text-align: left; + line-height: 1.6; + width: 90%; + margin-left: auto; + margin-right: auto; +} + /* columns of same height styles */ /* http://www.minimit.com/articles/solutions-tutorials/bootstrap-3-responsive-columns-of-same-height */ .row-full-height {