mirror of
https://github.com/ascribe/onion.git
synced 2024-11-15 09:35:10 +01:00
errors for non-fields, 500
removed retry consign_form
This commit is contained in:
parent
7a18c150c7
commit
961b8ee58d
66
js/components/ascribe_forms/form_consign.js
Normal file
66
js/components/ascribe_forms/form_consign.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import fetch from 'isomorphic-fetch';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import ApiUrls from '../../constants/api_urls';
|
||||||
|
import FormMixin from '../../mixins/form_mixin';
|
||||||
|
import InputText from './input_text';
|
||||||
|
import InputTextArea from './input_textarea';
|
||||||
|
import ButtonSubmitOrClose from './button_submit_close';
|
||||||
|
|
||||||
|
let ConsignForm = React.createClass({
|
||||||
|
mixins: [FormMixin],
|
||||||
|
|
||||||
|
url() {
|
||||||
|
return ApiUrls.ownership_consigns
|
||||||
|
},
|
||||||
|
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
|
||||||
|
}
|
||||||
|
},
|
||||||
|
renderForm() {
|
||||||
|
let title = this.props.edition.title;
|
||||||
|
let username = this.props.currentUser.username;
|
||||||
|
let message =
|
||||||
|
`Hi,
|
||||||
|
|
||||||
|
I consign \" ${title} \" to you.
|
||||||
|
|
||||||
|
Truly yours,
|
||||||
|
${username}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form id="transfer_modal_content" role="form" onSubmit={this.submit}>
|
||||||
|
<input className="invisible" type="email" name="fake_consignee"/>
|
||||||
|
<input className="invisible" type="password" name="fake_password"/>
|
||||||
|
<InputText
|
||||||
|
ref="consignee"
|
||||||
|
placeHolder="Consignee email"
|
||||||
|
required="required"
|
||||||
|
type="email"
|
||||||
|
submitted={this.state.submitted}/>
|
||||||
|
<InputTextArea
|
||||||
|
ref="consign_message"
|
||||||
|
defaultValue={message}
|
||||||
|
required=""
|
||||||
|
/>
|
||||||
|
<InputText
|
||||||
|
ref="password"
|
||||||
|
placeHolder="Password"
|
||||||
|
required="required"
|
||||||
|
type="password"
|
||||||
|
submitted={this.state.submitted}/>
|
||||||
|
<ButtonSubmitOrClose
|
||||||
|
text="CONSIGN"
|
||||||
|
onClose={this.props.onRequestHide}
|
||||||
|
submitted={this.state.submitted} />
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ConsignForm;
|
@ -8,8 +8,7 @@ let InputText = React.createClass({
|
|||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {value: null,
|
return {value: null,
|
||||||
alerts: null, // needed in AlertMixin
|
alerts: null
|
||||||
retry: 0 // needed in AlertMixin for generating unique alerts
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleChange(event) {
|
handleChange(event) {
|
||||||
|
@ -8,8 +8,7 @@ let InputTextArea = React.createClass({
|
|||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {value: this.props.defaultValue,
|
return {value: this.props.defaultValue,
|
||||||
alerts: null, // needed in AlertMixin
|
alerts: null // needed in AlertMixin
|
||||||
retry: 0 // needed in AlertMixin for generating unique alerts
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
handleChange(event) {
|
handleChange(event) {
|
||||||
|
43
js/components/ascribe_modal/modal_consign.js
Normal file
43
js/components/ascribe_modal/modal_consign.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Modal from 'react-bootstrap/lib/Modal';
|
||||||
|
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 ModalMixin from '../../mixins/modal_mixin'
|
||||||
|
|
||||||
|
let ConsignModalButton = React.createClass({
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<OverlayTrigger delay={500} placement="left"
|
||||||
|
overlay={<Tooltip>Have someone else sell the artwork</Tooltip>}>
|
||||||
|
<ModalTrigger modal={<ConsignModal edition={this.props.edition}
|
||||||
|
currentUser={this.props.currentUser}/>}>
|
||||||
|
<div className="btn btn-ascribe-inv">
|
||||||
|
CONSIGN
|
||||||
|
</div>
|
||||||
|
</ModalTrigger>
|
||||||
|
</OverlayTrigger>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let ConsignModal = React.createClass({
|
||||||
|
mixins : [ModalMixin],
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Modal {...this.props} title="Consign artwork">
|
||||||
|
<div className="modal-body">
|
||||||
|
<ConsignForm edition={this.props.edition}
|
||||||
|
currentUser={this.props.currentUser}
|
||||||
|
onRequestHide={this.onRequestHide}/>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default ConsignModalButton;
|
@ -4,6 +4,7 @@ import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
|
|||||||
import ModalTrigger from 'react-bootstrap/lib/ModalTrigger';
|
import ModalTrigger from 'react-bootstrap/lib/ModalTrigger';
|
||||||
import Tooltip from 'react-bootstrap/lib/Tooltip';
|
import Tooltip from 'react-bootstrap/lib/Tooltip';
|
||||||
|
|
||||||
|
import ModalMixin from '../../mixins/modal_mixin'
|
||||||
|
|
||||||
|
|
||||||
import ShareForm from '../ascribe_forms/form_share_email'
|
import ShareForm from '../ascribe_forms/form_share_email'
|
||||||
@ -24,11 +25,8 @@ let ShareModalButton = React.createClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
let ShareModal = React.createClass({
|
let ShareModal = React.createClass({
|
||||||
onRequestHide(e){
|
mixins : [ModalMixin],
|
||||||
if (e)
|
|
||||||
e.preventDefault();
|
|
||||||
this.props.onRequestHide();
|
|
||||||
},
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Modal {...this.props} title="Share artwork">
|
<Modal {...this.props} title="Share artwork">
|
||||||
|
@ -5,7 +5,7 @@ import ModalTrigger from 'react-bootstrap/lib/ModalTrigger';
|
|||||||
import Tooltip from 'react-bootstrap/lib/Tooltip';
|
import Tooltip from 'react-bootstrap/lib/Tooltip';
|
||||||
|
|
||||||
import TransferForm from '../ascribe_forms/form_transfer'
|
import TransferForm from '../ascribe_forms/form_transfer'
|
||||||
|
import ModalMixin from '../../mixins/modal_mixin'
|
||||||
|
|
||||||
let TransferModalButton = React.createClass({
|
let TransferModalButton = React.createClass({
|
||||||
render() {
|
render() {
|
||||||
@ -24,10 +24,8 @@ let TransferModalButton = React.createClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
let TransferModal = React.createClass({
|
let TransferModal = React.createClass({
|
||||||
onRequestHide(e){
|
mixins : [ModalMixin],
|
||||||
e.preventDefault();
|
|
||||||
this.props.onRequestHide();
|
|
||||||
},
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Modal {...this.props} title="Transfer artwork">
|
<Modal {...this.props} title="Transfer artwork">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import ImageViewer from './ascribe_media/image_viewer';
|
import ImageViewer from './ascribe_media/image_viewer';
|
||||||
|
import ConsignModalButton from './ascribe_modal/modal_consign';
|
||||||
import TransferModalButton from './ascribe_modal/modal_transfer';
|
import TransferModalButton from './ascribe_modal/modal_transfer';
|
||||||
import ShareModalButton from './ascribe_modal/modal_share';
|
import ShareModalButton from './ascribe_modal/modal_share';
|
||||||
|
|
||||||
@ -47,6 +48,7 @@ let EditionDetails = React.createClass({
|
|||||||
<EditionDetailProperty label="id" value={ this.props.edition.bitcoin_id } />
|
<EditionDetailProperty label="id" value={ this.props.edition.bitcoin_id } />
|
||||||
<EditionDetailProperty label="owner" value={ this.props.edition.owner } />
|
<EditionDetailProperty label="owner" value={ this.props.edition.owner } />
|
||||||
<br/>
|
<br/>
|
||||||
|
<ConsignModalButton edition={ this.props.edition } currentUser={ this.props.currentUser }/>
|
||||||
<TransferModalButton edition={ this.props.edition } currentUser={ this.props.currentUser }/>
|
<TransferModalButton edition={ this.props.edition } currentUser={ this.props.currentUser }/>
|
||||||
<ShareModalButton edition={ this.props.edition } currentUser={ this.props.currentUser }/>
|
<ShareModalButton edition={ this.props.edition } currentUser={ this.props.currentUser }/>
|
||||||
<hr/>
|
<hr/>
|
||||||
|
@ -2,7 +2,8 @@ import AppConstants from './application_constants';
|
|||||||
|
|
||||||
let apiUrls = {
|
let apiUrls = {
|
||||||
'ownership_shares_mail' : AppConstants.baseUrl + 'ownership/shares/mail/',
|
'ownership_shares_mail' : AppConstants.baseUrl + 'ownership/shares/mail/',
|
||||||
'ownership_transfers' : AppConstants.baseUrl + 'ownership/transfers/'
|
'ownership_transfers' : AppConstants.baseUrl + 'ownership/transfers/',
|
||||||
|
'ownership_consigns' : AppConstants.baseUrl + 'ownership/consigns/'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default apiUrls;
|
export default apiUrls;
|
@ -5,11 +5,10 @@ let AlertMixin = {
|
|||||||
setAlerts(errors){
|
setAlerts(errors){
|
||||||
let alerts = errors.map(
|
let alerts = errors.map(
|
||||||
function(error) {
|
function(error) {
|
||||||
let key = error + this.state.retry;
|
return <AlertDismissable error={error} key={error}/>;
|
||||||
return <AlertDismissable error={error} key={key}/>;
|
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
);
|
);
|
||||||
this.setState({alerts: alerts, retry: this.state.retry + 1});
|
this.setState({alerts: alerts});
|
||||||
},
|
},
|
||||||
clearAlerts(){
|
clearAlerts(){
|
||||||
this.setState({alerts: null});
|
this.setState({alerts: null});
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import EditionActions from '../actions/edition_actions'
|
||||||
import AppConstants from '../constants/application_constants'
|
import AppConstants from '../constants/application_constants'
|
||||||
import AlertDismissable from '../components/ascribe_forms/alert'
|
import AlertDismissable from '../components/ascribe_forms/alert'
|
||||||
|
|
||||||
@ -8,6 +9,7 @@ export const FormMixin = {
|
|||||||
return {
|
return {
|
||||||
submitted: false
|
submitted: false
|
||||||
, status: null
|
, status: null
|
||||||
|
, errors: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
submit(e) {
|
submit(e) {
|
||||||
@ -15,7 +17,7 @@ export const FormMixin = {
|
|||||||
for (var ref in this.refs){
|
for (var ref in this.refs){
|
||||||
this.refs[ref].clearAlerts();
|
this.refs[ref].clearAlerts();
|
||||||
}
|
}
|
||||||
this.setState({submitted: true});
|
this.setState({submitted: true, errors: []});
|
||||||
fetch(this.url(), {
|
fetch(this.url(), {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: {
|
headers: {
|
||||||
@ -30,15 +32,16 @@ export const FormMixin = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
handleResponse(response){
|
handleResponse(response){
|
||||||
|
let submitted = false;
|
||||||
if (response.status >= 200 && response.status < 300){
|
if (response.status >= 200 && response.status < 300){
|
||||||
|
EditionActions.fetchOne(this.props.edition.id);
|
||||||
this.props.onRequestHide();
|
this.props.onRequestHide();
|
||||||
|
submitted = true;
|
||||||
}
|
}
|
||||||
else if (response.status >= 400 && response.status < 500) {
|
else if (response.status >= 400 && response.status < 500) {
|
||||||
this.handleError(response);
|
this.handleError(response);
|
||||||
}
|
}
|
||||||
else {
|
this.setState({submitted: submitted, status: response.status});
|
||||||
this.setState({submitted: false, status: response.status});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
handleError(response){
|
handleError(response){
|
||||||
response.json().then((response) => this.dispatchErrors(response.errors));
|
response.json().then((response) => this.dispatchErrors(response.errors));
|
||||||
@ -49,14 +52,23 @@ export const FormMixin = {
|
|||||||
if (this.refs && this.refs[input] && this.refs[input].state){
|
if (this.refs && this.refs[input] && this.refs[input].state){
|
||||||
this.refs[input].setAlerts(errors[input]);
|
this.refs[input].setAlerts(errors[input]);
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
this.setState({errors: this.state.errors.concat(errors[input])});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.setState({submitted: false});
|
|
||||||
},
|
},
|
||||||
render(){
|
render(){
|
||||||
let alert = null;
|
let alert = null;
|
||||||
if (this.state.status >= 500){
|
if (this.state.status >= 500){
|
||||||
alert = <AlertDismissable error="Something went wrong, please try again later"/>;
|
alert = <AlertDismissable error="Something went wrong, please try again later"/>;
|
||||||
}
|
}
|
||||||
|
if (this.state.errors.length > 0){
|
||||||
|
alert = this.state.errors.map(
|
||||||
|
function(error) {
|
||||||
|
return <AlertDismissable error={error} key={error}/>;
|
||||||
|
}.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{alert}
|
{alert}
|
||||||
|
11
js/mixins/modal_mixin.js
Normal file
11
js/mixins/modal_mixin.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
let ModalMixin = {
|
||||||
|
onRequestHide(e){
|
||||||
|
if (e)
|
||||||
|
e.preventDefault();
|
||||||
|
this.props.onRequestHide();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalMixin;
|
Loading…
Reference in New Issue
Block a user