From 05811e529b562dec53c0cd6ed76fd1ce01cf14d9 Mon Sep 17 00:00:00 2001 From: Keksike Date: Sun, 2 Jul 2017 12:40:37 +0300 Subject: [PATCH] progress with stripe-payment --- src/index.jade | 1 + src/js/components/inviteForm.js | 3 +- src/js/components/membershipForm.js | 121 ++++++++++++++++------------ src/js/components/stripeCheckout.js | 117 +++++++++++++++++++++++++++ src/styles/style.styl | 16 +++- src/yhdistys.jade | 11 ++- 6 files changed, 211 insertions(+), 58 deletions(-) create mode 100644 src/js/components/stripeCheckout.js diff --git a/src/index.jade b/src/index.jade index f8c9589..f0bacbe 100644 --- a/src/index.jade +++ b/src/index.jade @@ -33,6 +33,7 @@ html meta(name='msapplication-TileColor', content='#10558c') meta(name='msapplication-TileImage', content='icons/mstile-144x144.png') meta(property='og:image', content='images/logo.png') + script(src='https://js.stripe.com/v3/') script(src='//use.typekit.net/scb5xny.js') script. try{Typekit.load();}catch(e){}; diff --git a/src/js/components/inviteForm.js b/src/js/components/inviteForm.js index 357419c..768b235 100644 --- a/src/js/components/inviteForm.js +++ b/src/js/components/inviteForm.js @@ -48,6 +48,7 @@ module.exports = React.createClass({ }, render() { var formClasses = classSet({ + 'form': true, 'invite-form': true, 'has-success': this.state.submitted, 'has-error': this.state.error, @@ -76,7 +77,7 @@ module.exports = React.createClass({ } feedbackMessage = ( -
+
{messageText}
); diff --git a/src/js/components/membershipForm.js b/src/js/components/membershipForm.js index 66178b6..c9182e8 100644 --- a/src/js/components/membershipForm.js +++ b/src/js/components/membershipForm.js @@ -6,6 +6,8 @@ var classSet = require('classnames'); var api = require('../api'); +var StripeCheckout = require('./stripeCheckout.js'); + module.exports = React.createClass({ getInitialState() { return { @@ -15,7 +17,9 @@ module.exports = React.createClass({ residence: '', submitted: false, sending: false, - error: null + error: null, + infoFormSuccess: false, + paymentSuccess: false }; }, onSubmit(e) { @@ -27,14 +31,10 @@ module.exports = React.createClass({ error: null }); - request.post(api('invites'), { - email: this.state.email.trim() - }) - .then(this.handleSuccess) - .catch(this.handleError); + this.handleInfoFormSuccess(); }, - handleSuccess() { - this.setState({submitted: true, sending: false}); + handleInfoFormSuccess() { + this.setState({submitted: true, sending: false, infoFormSuccess: true}); }, handleError(err) { this.setState({error: err, sending: false}); @@ -50,8 +50,12 @@ module.exports = React.createClass({ submitted: false }); }, + handlePaymentSuccess() { + this.setState({paymentSuccess: true}) + }, render() { var formClasses = classSet({ + 'form': true, 'membership-form': true, 'has-success': this.state.submitted, 'has-error': this.state.error, @@ -80,54 +84,69 @@ module.exports = React.createClass({ } feedbackMessage = ( -
+
{messageText}
); } - return ( -
- - - - - - - - {feedbackMessage} -
+ if(!this.state.infoFormSuccess) { + return ( +
+
+ {feedbackMessage} + + + + + + + +
+
) + } else if (this.state.infoFormSuccess && !this.state.paymentSuccess) { + return ( +
+ +
+ ) + } else { + return ( +

Onnee! +

+ ) + } } }); diff --git a/src/js/components/stripeCheckout.js b/src/js/components/stripeCheckout.js new file mode 100644 index 0000000..1ff75fe --- /dev/null +++ b/src/js/components/stripeCheckout.js @@ -0,0 +1,117 @@ +'use strict'; + +var request = require('axios'); +var React = require('react'); +var classSet = require('classnames'); +var api = require('../api'); + +var stripe = Stripe('pk_test_6pRNASCoBOKtIshFeQd4XMUh'); +var elements = stripe.elements(); +var card = elements.create('card', { + style: { + base: { + iconColor: '#666EE8', + color: '#31325F', + lineHeight: '40px', + fontWeight: 300, + fontFamily: '"Helvetica Neue", Helvetica, sans-serif', + fontSize: '15px', + + '::placeholder': { + color: '#CFD7E0', + }, + }, + } +}); + +var stripeErrMessages = { + incomplete_number: "incomplete number", + incorrect_number: "Kortin numero on virheellinen.", + invalid_number: "Kortin numero on virheellinen.", + invalid_expiry_month: "Kortin vanhenemiskuu on virheellinen.", + invalid_expiry_year: "Kortin vanhenemisvuosi on virheellinen.", + invalid_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.", + 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." +}; + + +module.exports = React.createClass({ + getInitialState() { + return { + sending: false, + error: null + }; + }, + + setOutcome(result) { + if (result.token) { + this.setState({ + error: null + }) + + // tää siirretään .theniin + this.setState({ + sending: false, + }) + + this.props.onPaymentSuccess(); + } else if (result.error) { + this.setState({ + error: stripeErrMessages[result.error.code] || result.error.message + }); + } + }, + + componentDidMount: function() { + card.mount('#card-element'); + }, + + onSubmit(e) { + e.preventDefault(); + + this.setState({ + error: null, + sending: true + }); + + var form = document.querySelector('form'); + var extraDetails = { + name: "My Name", + }; + stripe.createToken(card, extraDetails).then(this.setOutcome); + }, + + render() { + var formClasses = classSet({ + 'form': true, + 'stripe-form': true, + 'has-error': this.state.error, + }); + + var feedbackMessage; + + if(this.state.error) { + console.log(this.state.error); + feedbackMessage = ( +
+ {this.state.error} +
+ ); + } + + return ( +
+ {feedbackMessage} + {this.props.payerName} +
+ +
+ ) + } +}); diff --git a/src/styles/style.styl b/src/styles/style.styl index 8228f2d..d2670f7 100644 --- a/src/styles/style.styl +++ b/src/styles/style.styl @@ -112,6 +112,7 @@ section:first-child .btn background linkColor border-bottom 2px solid #117280 + color rgba(255, 255, 255, 0.9) .loader background transparent url('../images/ajax-loader.gif') no-repeat center center display block @@ -152,7 +153,14 @@ section:first-child margin 8px 0px .btn margin-top 12px - color rgba(255, 255, 255, 0.9) + +.stripe-form + margin 20px 0px + .name + margin-top 20px + text-align left + display block + color rgba(0, 0, 0, 0.4) @keyframes drop 0% @@ -166,7 +174,7 @@ section:first-child 100% transform rotateX(0deg) -.invite-form--message +.form--message background linkColor color #fff line-height 40px @@ -176,8 +184,8 @@ section:first-child transform-origin 100% 0 animation drop 0.6s linear -.invite-form.has-error - .invite-form--message +.form.has-error + .form--message background rgb(226, 33, 112) .members diff --git a/src/yhdistys.jade b/src/yhdistys.jade index 79d1096..aa4d857 100644 --- a/src/yhdistys.jade +++ b/src/yhdistys.jade @@ -33,6 +33,7 @@ html meta(name='msapplication-TileColor', content='#10558c') meta(name='msapplication-TileImage', content='icons/mstile-144x144.png') meta(property='og:image', content='images/logo.png') + script(src='https://js.stripe.com/v3/') script(src='//use.typekit.net/scb5xny.js') script. try{Typekit.load();}catch(e){}; @@ -55,7 +56,9 @@ html .column.column1-2 h3 Rekisteröity yhdistys p. - Koodiklinikka on nyt myös ry! Tähän vois kirjottaa jotain kivoja juttuja + Koodiklinikka on nyt myös ry! + p. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec semper euismod ex. Morbi vel feugiat turpis. Nunc feugiat enim id elementum dapibus. Nullam rhoncus sem ut sem mattis vulputate id at leo. Phasellus vitae semper libero, ut interdum libero. .column.column1-2 a(href='images/slack.png', target='_blank') img(src='images/slack.png') @@ -64,9 +67,13 @@ html .column.column1-2 h3 Liity jäseneksi #membership-form.form + .column.column1-2 p. - Jäseneksi liittymällä saat jotain hienoja juttuja eli kannattaa liittyä + Tähän vois kirjottaa juttuja siitä miks kandee liittyy jäseneks yms. + p. + Mauris imperdiet rutrum turpis ac scelerisque. Nulla ullamcorper mi eget maximus rutrum. Ut malesuada lectus quis dolor vehicula, sed finibus ante ullamcorper. Nullam vitae suscipit arcu. Vestibulum semper tortor in commodo molestie. Ut id enim faucibus, pharetra lectus vel, euismod neque. Cras massa erat, eleifend sit amet ligula et, volutpat blandit erat. Mauris eget lacinia dui. Nullam laoreet fringilla lorem, non tristique arcu aliquam at. + footer .sponsors