1
0
mirror of https://github.com/ascribe/onion.git synced 2024-11-15 01:25:17 +01:00

errors for non-fields, 500

removed retry
consign_form
This commit is contained in:
ddejongh 2015-05-29 15:16:42 +02:00
parent 7a18c150c7
commit 961b8ee58d
11 changed files with 151 additions and 23 deletions

View 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;

View File

@ -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) {

View File

@ -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) {

View 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;

View File

@ -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">

View File

@ -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">

View File

@ -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/>

View File

@ -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;

View File

@ -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});

View File

@ -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
View File

@ -0,0 +1,11 @@
import React from 'react';
let ModalMixin = {
onRequestHide(e){
if (e)
e.preventDefault();
this.props.onRequestHide();
}
};
export default ModalMixin;