mirror of
https://github.com/ascribe/onion.git
synced 2024-11-15 01:25:17 +01:00
loan request up till accept
This commit is contained in:
parent
5fcee39ed3
commit
b2fed6426f
39
js/actions/ownership_actions.js
Normal file
39
js/actions/ownership_actions.js
Normal file
@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
import alt from '../alt';
|
||||
import OwnershipFetcher from '../fetchers/ownership_fetcher';
|
||||
|
||||
|
||||
class OwnershipActions {
|
||||
constructor() {
|
||||
this.generateActions(
|
||||
'updateLoanPieceRequestList',
|
||||
'updateLoanPieceRequest'
|
||||
);
|
||||
}
|
||||
|
||||
fetchLoanRequestList() {
|
||||
OwnershipFetcher.fetchLoanPieceRequestList()
|
||||
.then((data) => {
|
||||
this.actions.updateLoanPieceRequestList(data.loan_requests);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
this.actions.updateLoanPieceRequestList(null);
|
||||
});
|
||||
}
|
||||
|
||||
fetchLoanRequest(pieceId) {
|
||||
OwnershipFetcher.fetchLoanPieceRequestList()
|
||||
.then((data) => {
|
||||
let loanRequests = data.loan_requests;
|
||||
this.actions.updateLoanPieceRequest({loanRequests, pieceId});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.logGlobal(err);
|
||||
this.actions.flushLoanPieceRequest();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default alt.createActions(OwnershipActions);
|
@ -6,6 +6,7 @@ import ConsignForm from '../ascribe_forms/form_consign';
|
||||
import UnConsignForm from '../ascribe_forms/form_unconsign';
|
||||
import TransferForm from '../ascribe_forms/form_transfer';
|
||||
import LoanForm from '../ascribe_forms/form_loan';
|
||||
import LoanRequestAnswerForm from '../ascribe_forms/form_loan_request_answer';
|
||||
import ShareForm from '../ascribe_forms/form_share_email';
|
||||
import ModalWrapper from '../ascribe_modal/modal_wrapper';
|
||||
import AppConstants from '../../constants/application_constants';
|
||||
@ -27,6 +28,8 @@ let AclButton = React.createClass({
|
||||
React.PropTypes.array
|
||||
]).isRequired,
|
||||
currentUser: React.PropTypes.object,
|
||||
buttonAcceptName: React.PropTypes.string,
|
||||
buttonAcceptClassName: React.PropTypes.string,
|
||||
handleSuccess: React.PropTypes.func.isRequired,
|
||||
className: React.PropTypes.string
|
||||
},
|
||||
@ -89,6 +92,18 @@ let AclButton = React.createClass({
|
||||
handleSuccess: this.showNotification
|
||||
};
|
||||
}
|
||||
else if (this.props.action === 'acl_loan_request'){
|
||||
return {
|
||||
title: getLangText('Loan artwork'),
|
||||
tooltip: getLangText('Loan your artwork for a limited period of time'),
|
||||
form: (<LoanRequestAnswerForm
|
||||
message={message}
|
||||
id={this.getFormDataId()}
|
||||
url={this.isPiece() ? ApiUrls.ownership_loans_pieces : ApiUrls.ownership_loans_editions}/>
|
||||
),
|
||||
handleSuccess: this.showNotification
|
||||
};
|
||||
}
|
||||
else if (this.props.action === 'acl_share'){
|
||||
return {
|
||||
title: getLangText('Share artwork'),
|
||||
@ -140,17 +155,20 @@ let AclButton = React.createClass({
|
||||
|
||||
// Removes the acl_ prefix and converts to upper case
|
||||
sanitizeAction() {
|
||||
if (this.props.buttonAcceptName) {
|
||||
return this.props.buttonAcceptName;
|
||||
}
|
||||
return this.props.action.split('acl_')[1].toUpperCase();
|
||||
},
|
||||
|
||||
render() {
|
||||
let shouldDisplay = this.props.availableAcls[this.props.action];
|
||||
let aclProps = this.actionProperties();
|
||||
|
||||
let buttonClassName = this.props.buttonAcceptClassName ? this.props.buttonAcceptClassName : '';
|
||||
return (
|
||||
<ModalWrapper
|
||||
trigger={
|
||||
<button className={shouldDisplay ? 'btn btn-default btn-sm ' : 'hidden'}>
|
||||
<button className={shouldDisplay ? 'btn btn-default btn-sm ' + buttonClassName : 'hidden'}>
|
||||
{this.sanitizeAction()}
|
||||
</button>
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ let LoanForm = React.createClass({
|
||||
startdate: React.PropTypes.object,
|
||||
enddate: React.PropTypes.object,
|
||||
showPersonalMessage: React.PropTypes.bool,
|
||||
showEndDate: React.PropTypes.bool,
|
||||
showStartDate: React.PropTypes.bool,
|
||||
showPassword: React.PropTypes.bool,
|
||||
url: React.PropTypes.string,
|
||||
id: React.PropTypes.object,
|
||||
message: React.PropTypes.string,
|
||||
@ -37,7 +40,10 @@ let LoanForm = React.createClass({
|
||||
getDefaultProps() {
|
||||
return {
|
||||
loanHeading: '',
|
||||
showPersonalMessage: true
|
||||
showPersonalMessage: true,
|
||||
showEndDate: false,
|
||||
showStartDate: false,
|
||||
showPassword: true
|
||||
};
|
||||
},
|
||||
|
||||
@ -155,7 +161,7 @@ let LoanForm = React.createClass({
|
||||
required/>
|
||||
</Property>
|
||||
<Property
|
||||
name='gallery_name'
|
||||
name='gallery'
|
||||
label={getLangText('Gallery/exhibition (optional)')}
|
||||
editable={!this.props.gallery}
|
||||
overrideForm={!!this.props.gallery}>
|
||||
@ -167,7 +173,7 @@ let LoanForm = React.createClass({
|
||||
<Property
|
||||
name='startdate'
|
||||
label={getLangText('Start date')}
|
||||
hidden={this.props.startdate}>
|
||||
hidden={!this.props.showStartDate}>
|
||||
<InputDate
|
||||
defaultValue={this.props.startdate}
|
||||
placeholderText={getLangText('Loan start date')} />
|
||||
@ -175,7 +181,7 @@ let LoanForm = React.createClass({
|
||||
<Property
|
||||
name='enddate'
|
||||
label={getLangText('End date')}
|
||||
hidden={this.props.enddate}>
|
||||
hidden={!this.props.showEndDate}>
|
||||
<InputDate
|
||||
defaultValue={this.props.enddate}
|
||||
placeholderText={getLangText('Loan end date')} />
|
||||
@ -194,11 +200,12 @@ let LoanForm = React.createClass({
|
||||
</Property>
|
||||
<Property
|
||||
name='password'
|
||||
label={getLangText('Password')}>
|
||||
label={getLangText('Password')}
|
||||
hidden={!this.props.showPassword}>
|
||||
<input
|
||||
type="password"
|
||||
placeholder={getLangText('Enter your password')}
|
||||
required/>
|
||||
required={this.props.showPassword ? 'required' : ''}/>
|
||||
</Property>
|
||||
{this.getContractCheckbox()}
|
||||
{this.props.children}
|
||||
|
88
js/components/ascribe_forms/form_loan_request_answer.js
Normal file
88
js/components/ascribe_forms/form_loan_request_answer.js
Normal file
@ -0,0 +1,88 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classnames from 'classnames';
|
||||
|
||||
import Button from 'react-bootstrap/lib/Button';
|
||||
|
||||
import LoanForm from './form_loan';
|
||||
import Property from './property';
|
||||
import InputTextAreaToggable from './input_textarea_toggable';
|
||||
import InputDate from './input_date';
|
||||
import InputCheckbox from './input_checkbox';
|
||||
|
||||
import OwnershipActions from '../../actions/ownership_actions';
|
||||
import OwnershipStore from '../../stores/ownership_store';
|
||||
|
||||
import AppConstants from '../../constants/application_constants';
|
||||
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
|
||||
|
||||
let LoanRequestAnswerForm = React.createClass({
|
||||
propTypes: {
|
||||
loanHeading: React.PropTypes.string,
|
||||
email: React.PropTypes.string,
|
||||
gallery: React.PropTypes.string,
|
||||
startdate: React.PropTypes.object,
|
||||
enddate: React.PropTypes.object,
|
||||
showPersonalMessage: React.PropTypes.bool,
|
||||
showEndDate: React.PropTypes.bool,
|
||||
showStartDate: React.PropTypes.bool,
|
||||
showPassword: React.PropTypes.bool,
|
||||
url: React.PropTypes.string,
|
||||
id: React.PropTypes.object,
|
||||
message: React.PropTypes.string,
|
||||
handleSuccess: React.PropTypes.func
|
||||
},
|
||||
|
||||
getDefaultProps() {
|
||||
return {
|
||||
loanHeading: '',
|
||||
showPersonalMessage: true,
|
||||
showEndDate: false,
|
||||
showStartDate: false,
|
||||
showPassword: true
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return OwnershipStore.getState();
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
OwnershipStore.listen(this.onChange);
|
||||
OwnershipActions.fetchLoanRequest(this.props.id.piece_id);
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
OwnershipStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
|
||||
render() {
|
||||
console.log(this.state.loanRequest)
|
||||
if (this.state.loanRequest) {
|
||||
return (
|
||||
<LoanForm
|
||||
loanHeading={null}
|
||||
message={''}
|
||||
id={this.props.id}
|
||||
url={this.props.url}
|
||||
email={""}
|
||||
gallery={this.state.loanRequest.gallery}
|
||||
showPassword={true}
|
||||
showPersonalMessage={false}
|
||||
handleSuccess={this.handleLoanSuccess}/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
export default LoanRequestAnswerForm;
|
@ -90,6 +90,18 @@ let RequestActionForm = React.createClass({
|
||||
<AclButton
|
||||
availableAcls={{'acl_unconsign': true}}
|
||||
action="acl_unconsign"
|
||||
buttonAcceptClassName='inline pull-right'
|
||||
pieceOrEditions={this.props.pieceOrEditions}
|
||||
currentUser={this.props.currentUser}
|
||||
handleSuccess={this.props.handleSuccess} />
|
||||
);
|
||||
} else if(this.props.requestAction === 'loan_request') {
|
||||
return (
|
||||
<AclButton
|
||||
availableAcls={{'acl_loan_request': true}}
|
||||
action="acl_loan_request"
|
||||
buttonAcceptName="LOAN"
|
||||
buttonAcceptClassName='inline pull-right'
|
||||
pieceOrEditions={this.props.pieceOrEditions}
|
||||
currentUser={this.props.currentUser}
|
||||
handleSuccess={this.props.handleSuccess} />
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import Router from 'react-router';
|
||||
import Moment from 'moment';
|
||||
|
||||
import StarRating from 'react-star-rating';
|
||||
|
||||
@ -15,6 +16,7 @@ import PrizeRatingActions from '../../actions/prize_rating_actions';
|
||||
import PrizeRatingStore from '../../stores/prize_rating_store';
|
||||
|
||||
import UserStore from '../../../../../stores/user_store';
|
||||
import WhitelabelStore from '../../../../../stores/whitelabel_store';
|
||||
|
||||
import Piece from '../../../../../components/ascribe_detail/piece';
|
||||
import Note from '../../../../../components/ascribe_detail/note';
|
||||
@ -27,6 +29,9 @@ import InputTextAreaToggable from '../../../../../components/ascribe_forms/input
|
||||
import CollapsibleParagraph from '../../../../../components/ascribe_collapsible/collapsible_paragraph';
|
||||
|
||||
import InputCheckbox from '../../../../ascribe_forms/input_checkbox';
|
||||
import LoanForm from '../../../../ascribe_forms/form_loan';
|
||||
import RequestActionForm from '../../../../ascribe_forms/form_request_action';
|
||||
import ModalWrapper from '../../../../ascribe_modal/modal_wrapper';
|
||||
|
||||
import GlobalNotificationModel from '../../../../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
|
||||
@ -61,7 +66,6 @@ let PieceContainer = React.createClass({
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if(this.props.params.pieceId !== nextProps.params.pieceId) {
|
||||
PieceActions.updatePiece({});
|
||||
console.log('update')
|
||||
PieceActions.fetchOne(nextProps.params.pieceId);
|
||||
}
|
||||
},
|
||||
@ -86,6 +90,21 @@ let PieceContainer = React.createClass({
|
||||
this.setState(this.state);
|
||||
},
|
||||
|
||||
getActions(){
|
||||
if (this.state.piece &&
|
||||
this.state.piece.request_action &&
|
||||
this.state.piece.request_action.length > 0) {
|
||||
return (
|
||||
<RequestActionForm
|
||||
currentUser={this.state.currentUser}
|
||||
pieceOrEditions={ this.state.piece }
|
||||
requestAction={this.state.piece.request_action}
|
||||
requestUser={this.state.piece.user_registered}
|
||||
handleSuccess={this.loadPiece}/>);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
render() {
|
||||
if('title' in this.state.piece) {
|
||||
let artistName = ((this.state.currentUser.is_jury && !this.state.currentUser.is_judge) ||
|
||||
@ -104,6 +123,7 @@ let PieceContainer = React.createClass({
|
||||
<h1 className="ascribe-detail-title">{this.state.piece.title}</h1>
|
||||
<DetailProperty label="BY" value={artistName} />
|
||||
<DetailProperty label="DATE" value={ this.state.piece.date_created.slice(0, 4) } />
|
||||
{this.getActions()}
|
||||
<hr/>
|
||||
</div>
|
||||
}
|
||||
@ -169,7 +189,8 @@ let PrizePieceRatings = React.createClass({
|
||||
getInitialState() {
|
||||
return mergeOptions(
|
||||
PieceListStore.getState(),
|
||||
PrizeRatingStore.getState()
|
||||
PrizeRatingStore.getState(),
|
||||
WhitelabelStore.getState()
|
||||
);
|
||||
},
|
||||
|
||||
@ -178,6 +199,7 @@ let PrizePieceRatings = React.createClass({
|
||||
PrizeRatingActions.fetchOne(this.props.piece.id);
|
||||
PrizeRatingActions.fetchAverage(this.props.piece.id);
|
||||
PieceListStore.listen(this.onChange);
|
||||
WhitelabelStore.listen(this.onChange);
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
@ -188,6 +210,7 @@ let PrizePieceRatings = React.createClass({
|
||||
PrizeRatingActions.updateRating({});
|
||||
PrizeRatingStore.unlisten(this.onChange);
|
||||
PieceListStore.unlisten(this.onChange);
|
||||
WhitelabelStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
// The StarRating component does not have a property that lets us set
|
||||
@ -213,6 +236,39 @@ let PrizePieceRatings = React.createClass({
|
||||
);
|
||||
},
|
||||
|
||||
getLoanButton(){
|
||||
let today = new Moment();
|
||||
let endDate = new Moment();
|
||||
endDate.add(6, 'months');
|
||||
return (
|
||||
<ModalWrapper
|
||||
trigger={
|
||||
<button className='btn btn-default btn-sm'>
|
||||
SEND LOAN REQUEST
|
||||
</button>
|
||||
}
|
||||
handleSuccess={this.handleLoanRequestSuccess}
|
||||
title='REQUEST LOAN'>
|
||||
<LoanForm
|
||||
loanHeading={null}
|
||||
message={'Congratulations,\nYou have been selected for the sluice screens.\n' +
|
||||
'Please accept the loan request to proceed\n\nBest regards,\n\nSluice.'}
|
||||
id={{piece_id: this.props.piece.id}}
|
||||
url={ApiUrls.ownership_loans_pieces_request}
|
||||
email={this.state.whitelabel.user}
|
||||
gallery={this.props.piece.prize.name}
|
||||
startdate={today}
|
||||
enddate={endDate}
|
||||
showPersonalMessage={true}
|
||||
showStartDate={true}
|
||||
showEndDate={true}
|
||||
showPassword={false}
|
||||
handleSuccess={this.handleLoanSuccess} />
|
||||
</ModalWrapper>);
|
||||
},
|
||||
|
||||
handleLoanRequestSuccess(){},
|
||||
|
||||
refreshPieceData() {
|
||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||
@ -241,10 +297,7 @@ let PrizePieceRatings = React.createClass({
|
||||
</InputCheckbox>
|
||||
</span>
|
||||
<span className="pull-right">
|
||||
{this.props.piece.selected ?
|
||||
<button className={'btn btn-default btn-sm '}>
|
||||
SEND LOAN REQUEST
|
||||
</button> : null}
|
||||
{this.props.piece.selected ? this.getLoanButton() : null}
|
||||
</span>
|
||||
</div>
|
||||
<hr />
|
||||
|
@ -32,6 +32,7 @@ let ApiUrls = {
|
||||
'ownership_loans_pieces': AppConstants.apiEndpoint + 'ownership/loans/pieces/',
|
||||
'ownership_loans_pieces_confirm': AppConstants.apiEndpoint + 'ownership/loans/pieces/confirm/',
|
||||
'ownership_loans_pieces_deny': AppConstants.apiEndpoint + 'ownership/loans/pieces/deny/',
|
||||
'ownership_loans_pieces_request': AppConstants.apiEndpoint + 'ownership/loans/pieces/request/',
|
||||
'ownership_loans_editions': AppConstants.apiEndpoint + 'ownership/loans/editions/',
|
||||
'ownership_loans_confirm': AppConstants.apiEndpoint + 'ownership/loans/editions/confirm/',
|
||||
'ownership_loans_deny': AppConstants.apiEndpoint + 'ownership/loans/editions/deny/',
|
||||
|
@ -17,8 +17,11 @@ let OwnershipFetcher = {
|
||||
*/
|
||||
fetchLoanContractList(){
|
||||
return requests.get(ApiUrls.ownership_loans_contract);
|
||||
}
|
||||
},
|
||||
|
||||
fetchLoanPieceRequestList(){
|
||||
return requests.get(ApiUrls.ownership_loans_pieces_request);
|
||||
}
|
||||
};
|
||||
|
||||
export default OwnershipFetcher;
|
||||
|
35
js/stores/ownership_store.js
Normal file
35
js/stores/ownership_store.js
Normal file
@ -0,0 +1,35 @@
|
||||
'use strict';
|
||||
|
||||
import alt from '../alt';
|
||||
import OwnershipActions from '../actions/ownership_actions';
|
||||
|
||||
|
||||
class OwnershipStore {
|
||||
constructor() {
|
||||
this.loanRequestList = [];
|
||||
this.loanRequest = null;
|
||||
this.bindActions(OwnershipActions);
|
||||
}
|
||||
|
||||
onUpdateLoanPieceRequestList(loanRequests) {
|
||||
this.loanRequestList = loanRequests;
|
||||
}
|
||||
|
||||
onUpdateLoanPieceRequest({loanRequests, pieceId}) {
|
||||
this.loanRequestList = loanRequests;
|
||||
this.loanRequest = loanRequests.filter((item) => item.piece_id === pieceId.toString());
|
||||
if (this.loanRequest.length > 0){
|
||||
this.loanRequest = this.loanRequest[0];
|
||||
}
|
||||
else {
|
||||
this.loanRequest = null;
|
||||
}
|
||||
}
|
||||
|
||||
flushLoanPieceRequest(){
|
||||
this.loanRequestList = [];
|
||||
this.loanRequest = null;
|
||||
}
|
||||
}
|
||||
|
||||
export default alt.createStore(OwnershipStore, 'OwnershipStore');
|
@ -23,6 +23,8 @@ export function getAclFormMessage(aclName, entities, senderName) {
|
||||
message += getLangText('I un-consign');
|
||||
} else if(aclName === 'acl_loan') {
|
||||
message += getLangText('I loan');
|
||||
} else if(aclName === 'acl_loan_request') {
|
||||
message += getLangText('I request to loan');
|
||||
} else if(aclName === 'acl_share') {
|
||||
message += getLangText('I share');
|
||||
} else {
|
||||
@ -34,7 +36,7 @@ export function getAclFormMessage(aclName, entities, senderName) {
|
||||
|
||||
if(aclName === 'acl_transfer' || aclName === 'acl_loan' || aclName === 'acl_consign') {
|
||||
message += getLangText('to you');
|
||||
} else if(aclName === 'acl_unconsign') {
|
||||
} else if(aclName === 'acl_unconsign' || aclName === 'acl_loan_request') {
|
||||
message += getLangText('from you');
|
||||
} else if(aclName === 'acl_share') {
|
||||
message += getLangText('with you');
|
||||
|
Loading…
Reference in New Issue
Block a user