From 225e9a797440f9cbaceda347e5db065964ab475e Mon Sep 17 00:00:00 2001 From: Cihan Bebek Date: Tue, 4 Jul 2017 15:24:35 +0300 Subject: [PATCH] major reform on membership registration form, also more error-handling for membership info form --- src/js/components/membershipForm.js | 147 +++----------------- src/js/components/membershipInfoForm.js | 173 ++++++++++++++++++++++++ src/js/components/stripeCheckout.js | 14 +- 3 files changed, 202 insertions(+), 132 deletions(-) create mode 100644 src/js/components/membershipInfoForm.js diff --git a/src/js/components/membershipForm.js b/src/js/components/membershipForm.js index e48b302..cf31414 100644 --- a/src/js/components/membershipForm.js +++ b/src/js/components/membershipForm.js @@ -4,149 +4,46 @@ var request = require('axios'); var React = require('react'); var classSet = require('classnames'); -var api = require('../api'); - var StripeCheckout = require('./stripeCheckout.js'); +var MembershipInfoForm = require('./membershipInfoForm.js'); module.exports = React.createClass({ getInitialState() { return { - email: '', - name: '', - handle: '', - residence: '', - submitted: false, - sending: false, - error: null, + userInfo: null, infoFormSuccess: false, paymentSuccess: false }; }, - onSubmit(e) { - e.preventDefault(); - this.setState({ - submitted: false, - sending: true, - error: null - }); - - this.handleInfoFormSuccess(); - //TODO handleError - }, - handleInfoFormSuccess() { - this.setState({submitted: true, sending: false, infoFormSuccess: true}); - }, - handleError(err) { - this.setState({error: err, sending: false}); - }, - onChange(e) { - if(e.target.value === this.state[e.target.name]) { - return; - } - - this.setState({ - [e.target.name]: e.target.value, - error: null, - submitted: false - }); - }, handlePaymentSuccess() { this.setState({paymentSuccess: true}); }, + + handleInfoFormSuccess(userInfo) { + this.setState({ + userInfo: userInfo, + infoFormSuccess: true, + }); + }, + render() { - var formClasses = classSet({ - 'form': true, - 'membership-form': true, - 'has-success': this.state.submitted, - 'has-error': this.state.error, - 'sending': this.state.sending - }); - - var inputClasses = classSet({ - 'input': true, - 'has-success': this.state.submitted, - 'has-error': this.state.error - }); - - var feedbackMessage; - - if(this.state.error || this.state.submitted) { - let messageText; - - if(this.state.submitted) { - messageText = 'Kutsu lähetetty antamaasi sähköpostiosoitteeseen.'; - } else if(this.state.error.status === 400 && this.state.error.data === 'invalid_email') { - messageText = 'Tarkasta syöttämäsi sähköpostiosoite'; - } else if(this.state.error.status === 400 && this.state.error.data === 'already_invited') { - messageText = 'Sähköpostiosoitteeseen on jo lähetetty kutsu'; - } else { - messageText = 'Jotain meni pieleen. Yritä hetken päästä uudelleen.'; - } - - feedbackMessage = ( -
- {messageText} -
- ); - } - if(!this.state.infoFormSuccess) { + return + + } else if (!this.state.paymentSuccess) { return ( -
-
- {feedbackMessage} - - - - - - - -
-
- ) - } else if (this.state.infoFormSuccess && !this.state.paymentSuccess) { - return ( -
- -
- ) + + ) + } else { return ( -

Tervetuloa jäseneksi! -

+
+

Maksu ja rekisteröityminen onnistui.

+

Tervetuloa Koodiklinikka ry:n jäseneksi!

+
) } } diff --git a/src/js/components/membershipInfoForm.js b/src/js/components/membershipInfoForm.js new file mode 100644 index 0000000..8a74c8c --- /dev/null +++ b/src/js/components/membershipInfoForm.js @@ -0,0 +1,173 @@ +'use strict'; + +var request = require('axios'); +var React = require('react'); +var classSet = require('classnames'); + +var api = require('../api'); + +var StripeCheckout = require('./stripeCheckout.js'); + +var fieldNameTranslations = { + email: {fi: "Sähköpostiosoite"}, + name: {fi: "Koko nimi"}, + handle: {fi: "Slack-käyttäjätunnus"}, + residence: {fi: "Paikkakunta"} +} + +function validateEmail(email) { + var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return re.test(email); +} + +module.exports = React.createClass({ + + getInitialState() { + return { + email: '', + name: '', + handle: '', + residence: '', + sending: false, + errors: [] + }; + }, + onSubmit(e) { + e.preventDefault(); + + this.setState({ + sending: true, + errors: [] + }); + + + var userInfo = { + email: this.state.email, + name: this.state.name, + handle: this.state.handle, + residence: this.state.residence, + } + + var userInfoErrors = this.getDataErrors(); + + console.log(userInfoErrors); + + if(userInfoErrors.length){ + this.setState({ + sending: false, + errors: userInfoErrors + }); + console.log("errorei"); + } else { + this.props.onSuccess(userInfo); + } + }, + handleError(err) { + this.setState({error: err, sending: false}); + }, + onChange(e) { + if(e.target.value === this.state[e.target.name]) { + return; + } + + this.setState({ + [e.target.name]: e.target.value, + errors: [] + }); + }, + + getDataErrors() { + var foundErrors = []; + + if (!this.state.name) + foundErrors.push({field: 'name', type: 'missing'}); + + if (!this.state.email) + foundErrors.push({field: 'email', type: 'missing'}); + else if(!validateEmail(this.state.email)) + foundErrors.push({field: 'email', type: 'invalid'}); + + if (!this.state.handle) + foundErrors.push({field: 'handle', type: 'missing'}); + + if (!this.state.residence) + foundErrors.push({field: 'residence', type: 'missing'}); + + + return foundErrors; + }, + + render() { + var formClasses = classSet({ + 'form': true, + 'membership-form': true, + 'has-error': this.state.errors.length, + 'sending': this.state.sending + }); + + var inputClasses = classSet({ + 'input': true, + 'has-error': this.state.errors.length + }); + + var feedbackMessages = []; + + this.state.errors.forEach((err, i) => { + var feedbackText; + + if(err.type == 'missing') { + feedbackText = `${fieldNameTranslations[err.field].fi} on pakollinen.` + } else if (err.type == 'invalid') { + feedbackText = `${fieldNameTranslations[err.field].fi} on virheellinen.` + } + + feedbackMessages.push((
{feedbackText}
)) + }); + + return ( +
+
+ {feedbackMessages} + + + + + + + +
+
+ ) + } +}); diff --git a/src/js/components/stripeCheckout.js b/src/js/components/stripeCheckout.js index 687887c..3e0aaa0 100644 --- a/src/js/components/stripeCheckout.js +++ b/src/js/components/stripeCheckout.js @@ -25,22 +25,24 @@ var card = elements.create('card', { }); var stripeErrMessages = { - incomplete_number: "incomplete number", + incomplete_number: "Kortin numero on virheellinen.", incorrect_number: "Kortin numero on virheellinen.", invalid_number: "Kortin numero on virheellinen.", + incomplete_expiry: "Kortin vanhenemisaika on virheellinen.", invalid_expiry_month: "Kortin vanhenemiskuu on virheellinen.", invalid_expiry_year: "Kortin vanhenemisvuosi on virheellinen.", invalid_cvc: "Kortin CVC koodi on virheellinen.", + incomplete_cvc: "Kortin CVC koodi on virheellinen.", expired_card: "Kortti on vanhentunut.", incorrect_cvc: "Kortin CVC koodi on virheellinen..", - incorrect_zip: "The card's zip code failed validation.", + incomplete_zip: "Virheellinen postinumero.", + incorrect_zip: "Virheellinen postinumero.", card_declined: "Kortti hylättiin.", missing: "There is no card on a customer that is being charged.", processing_error: "Virhe kortin prosessoinnissa.", - rate_limit: "An error occurred due to requests hitting the API too quickly. Please let us know if you're consistently running into this error." + rate_limit: "Rajapintaan tehty liian monta kutsua. Odota hetki." }; - module.exports = React.createClass({ getInitialState() { return { @@ -55,8 +57,6 @@ module.exports = React.createClass({ error: null }) - console.log(result.token); - request.post(api('membership'), { stripeToken: result.token.id, email: this.props.payerEmail @@ -72,6 +72,7 @@ module.exports = React.createClass({ }); } else if (result.error) { + console.log(result.error); this.setState({ error: stripeErrMessages[result.error.code] || result.error.message, sending: false @@ -109,7 +110,6 @@ module.exports = React.createClass({ var feedbackMessage; if(this.state.error) { - console.log(this.state.error); feedbackMessage = (
{this.state.error}