UNPKG

rycard

Version:

Is a react component that implements an input card form to receipt the Number cards, Dates expired and CVV code. To help to the user the form shows some errors when the card is incomplete or when the date expired is not in range of valid dates.

600 lines (523 loc) 17.3 kB
import React, { Component } from 'react'; import qs from 'qs'; import payment from 'payment'; import axios from 'axios'; function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } var styles = {"test":"_3ybTi","ulala-loading-check":"_2eLh7","loaderSpin":"_3xobC","red":"_3nWpX","small":"_1YEqb","big":"_2KwTh","huge":"_NNwjx","load-complete":"_3nAaU","checkmark":"_1UIFl","checkmarkSmall":"_JwoZ-","checkmarkBig":"_3SDln","checkmarkHuge":"_3mn94"}; var Rycircle = /*#__PURE__*/function (_Component) { _inheritsLoose(Rycircle, _Component); function Rycircle() { return _Component.apply(this, arguments) || this; } var _proto = Rycircle.prototype; _proto.getClass = function getClass() { var _str = styles['ulala-loading-check'] + " "; if (this.props.done) { _str += " " + styles['load-complete'] + " "; } if (this.props.size) { _str += " " + styles[this.props.size] + " "; } if (this.props.error) { _str += " " + styles['red'] + " "; } return _str; }; _proto.getSnapshotBeforeUpdate = function getSnapshotBeforeUpdate(prevProps) { return { notifyRequired: prevProps.done !== this.props.done || prevProps.error !== this.props.error }; }; _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState, snapshot) { if (snapshot.notifyRequired) { this.updateAndNotify(); } }; _proto.updateAndNotify = function updateAndNotify() { setTimeout(function (argument) { if (this.props.done) { this.props.onDoneChange(false); } if (this.props.error) { this.props.onErrorChange(false); } }.bind(this), 1000); }; _proto.showComponent = function showComponent() { return /*#__PURE__*/React.createElement("div", { className: this.getClass() }, /*#__PURE__*/React.createElement("div", { className: styles['checkmark'] + " draw" })); }; _proto.render = function render() { return /*#__PURE__*/React.createElement("div", null, this.showComponent()); }; return Rycircle; }(Component); var Ryloading = /*#__PURE__*/function (_Component2) { _inheritsLoose(Ryloading, _Component2); function Ryloading(props) { var _this; _this = _Component2.call(this, props) || this; _this.state = { 'done': false, 'error': false }; _this.reset = _this.reset.bind(_assertThisInitialized(_this)); return _this; } var _proto2 = Ryloading.prototype; _proto2.getSnapshotBeforeUpdate = function getSnapshotBeforeUpdate(prevProps) { return { notifyRequired: prevProps.status !== this.props.status }; }; _proto2.componentDidUpdate = function componentDidUpdate(prevProps, prevState, snapshot) { if (snapshot.notifyRequired) { this.updateAndNotify(); } }; _proto2.updateAndNotify = function updateAndNotify() { if (this.props.status === 'done') { this.setState({ 'done': true, 'error': false }); } else if (this.props.status === 'error') { this.setState({ 'error': true, 'done': false }); } }; _proto2.getAlertClass = function getAlertClass() { if (this.props.alert === 'done') { return 'alert-success'; } else if (this.props.alert === 'error') { return 'alert-danger'; } }; _proto2.showAlert = function showAlert() { if (this.props.text) { if (this.props.text.length > 0) { return /*#__PURE__*/React.createElement("div", { className: "alert" + " " + this.getAlertClass(), role: "alert" }, this.props.text); } } return /*#__PURE__*/React.createElement("div", null); }; _proto2.reset = function reset() { this.setState({ 'done': false, 'error': false }); this.props.onRyLoadingReset(); }; _proto2.showComponent = function showComponent() { if (this.props.status === 'running' || this.props.status === 'done' || this.props.status === 'error') { return /*#__PURE__*/React.createElement("div", { className: "mt-2" }, /*#__PURE__*/React.createElement("div", { className: "text-center" }, /*#__PURE__*/React.createElement(Rycircle, { done: this.state.done, error: this.state.error, size: this.props.size, onDoneChange: this.reset, onErrorChange: this.reset }))); } else { return /*#__PURE__*/React.createElement("div", null); } }; _proto2.render = function render() { return /*#__PURE__*/React.createElement("div", null, this.showComponent(), /*#__PURE__*/React.createElement("div", { className: "mt-2" }, this.showAlert())); }; return Ryloading; }(Component); Ryloading.defaultProps = { text: undefined, size: 'small', status: 'hold' }; var Rycard = /*#__PURE__*/function (_Component) { _inheritsLoose(Rycard, _Component); function Rycard(props) { var _this2; _this2 = _Component.call(this, props) || this; _this2.state = { card: { 'card': { 'valid': undefined }, 'cvv': { 'valid': undefined }, 'expiry': { 'valid': undefined } }, resp: { text: undefined }, loading: { 'status': 'hold', 'alert': 'hold' } }; _this2.handleSubmit = _this2.handleSubmit.bind(_assertThisInitialized(_this2)); _this2.onRyLoadingReset = _this2.onRyLoadingReset.bind(_assertThisInitialized(_this2)); _this2.handleCardNumberBlur = _this2.handleCardNumberBlur.bind(_assertThisInitialized(_this2)); _this2.handleCardCVCCBlur = _this2.handleCardCVCCBlur.bind(_assertThisInitialized(_this2)); _this2.handleCardExpiryBlur = _this2.handleCardExpiryBlur.bind(_assertThisInitialized(_this2)); _this2.handleCardNumberChange = _this2.handleCardNumberChange.bind(_assertThisInitialized(_this2)); _this2.handleCardExpiryChange = _this2.handleCardExpiryChange.bind(_assertThisInitialized(_this2)); _this2.handleCardCVCChange = _this2.handleCardCVCChange.bind(_assertThisInitialized(_this2)); return _this2; } var _proto = Rycard.prototype; _proto.handleFormChange = function handleFormChange() { this.setState({ 'loading': _extends({}, this.state.loading, { 'alert': undefined }), 'resp': { 'text': undefined } }); }; _proto.handleCardNumberChange = function handleCardNumberChange(e) { var value = e.target.value; this.setValuesOnCard('card', value); payment.formatCardNumber(e.target); this.handleFormChange(); }; _proto.handleCardExpiryChange = function handleCardExpiryChange(e) { var value = e.target.value; this.setValuesOnCard('expiry', value); payment.formatCardExpiry(e.target); this.handleFormChange(); }; _proto.handleCardCVCChange = function handleCardCVCChange(e) { var value = e.target.value; this.setValuesOnCard('cvv', value); payment.formatCardCVC(e.target); this.handleFormChange(); }; _proto.handleCardExpiryBlur = function handleCardExpiryBlur(e) { var value = e.target.value; var v = payment.fns.validateCardExpiry(value); this.setState({ 'card': _extends({}, this.state.card, { 'expiry': _extends({}, this.state.card.expiry, { 'valid': v }) }) }, function () { this.setValuesOnCard('expiry', value); }); }; _proto.handleCardCVCCBlur = function handleCardCVCCBlur(e) { var value = e.target.value; var v = payment.fns.validateCardCVC(value); this.setState({ 'card': _extends({}, this.state.card, { 'cvv': _extends({}, this.state.card.cvv, { 'valid': v }) }) }, function () { this.setValuesOnCard('cvv', value); }); }; _proto.handleCardNumberBlur = function handleCardNumberBlur(e) { var value = e.target.value; var v = payment.fns.validateCardNumber(value); this.setState({ 'card': _extends({}, this.state.card, { 'card': _extends({}, this.state.card.card, { 'valid': v }) }) }, function () { this.setValuesOnCard('card', value); }); }; _proto.setValuesOnCard = function setValuesOnCard(field, value) { value = value.split(' ').join(''); if (field === 'expiry') { value = value.split('/'); this.setState({ 'card': _extends({}, this.state.card, { 'expiry': _extends({}, this.state.card.expiry, { 'year': value[1], 'month': value[0] }) }) }); } else if (field === 'card') { this.setState({ 'card': _extends({}, this.state.card, { 'card': _extends({}, this.state.card.card, { 'value': value }) }) }); } else if (field === 'cvv') { this.setState({ 'card': _extends({}, this.state.card, { 'cvv': _extends({}, this.state.card.cvv, { 'value': value }) }) }); } else if (field === 'email') { this.setState({ 'card': _extends({}, this.state.card, { 'email': _extends({}, this.state.card.email, { 'value': value }) }) }); } }; _proto.onRyLoadingReset = function onRyLoadingReset() { this.setState({ loading: _extends({}, this.state.loading, { 'status': 'hold' }) }); }; _proto.animateLoading = function animateLoading(status, t) { this.setState({ 'loading': { 'status': status, 'alert': status } }, function () {}); this.setState({ 'resp': { 'text': t } }); }; _proto.getWarningClassOnFields = function getWarningClassOnFields(field) { if (field === 'number') { if (this.state.card.card.valid === false) { return 'is-invalid'; } } else if (field === 'expiry') { if (this.state.card.expiry.valid === false) { return 'is-invalid'; } } else if (field === 'cvv') { if (this.state.card.cvv.valid === false) { return 'is-invalid'; } } return ''; }; _proto.getWarningOnFields = function getWarningOnFields(field) { if (field === 'number') { if (this.state.card.card.valid === false) { return /*#__PURE__*/React.createElement("div", { className: "invalid-feedback" }, "Please enter a valid card number."); } } else if (field === 'expiry') { if (this.state.card.expiry.valid === false) { return /*#__PURE__*/React.createElement("div", { className: "invalid-feedback" }, "Expiry invalid."); } } else if (field === 'cvv') { if (this.state.card.cvv.valid === false) { return /*#__PURE__*/React.createElement("div", { className: "invalid-feedback" }, "CVV invalid."); } } }; _proto.getIsSubmitIsOk = function getIsSubmitIsOk() { return this.state.card.cvv.valid && this.state.card.expiry.valid && this.state.card.card.valid; }; _proto.handleSubmit = function handleSubmit(event) { var endpoint = this.props.endpoint; if (endpoint === undefined) { console.log("You must define an endpoint."); event.preventDefault(); return; } var _this = this; if (_this.state.loading.status !== 'hold') { return; } _this.animateLoading('running'); var data = { 'email': _this.props.email, 'price': _this.props.price, 'card': _this.state.card.card.value, 'year': _this.state.card.expiry.year, 'month': _this.state.card.expiry.month, 'cvv': _this.state.card.cvv.value }; var options = { method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' }, data: qs.stringify(data), url: endpoint }; var t = undefined; axios(options).then(function (response) { var res = response.data; if (res['status']) { t = "Success"; if (res && res['meta'] && res['meta']['msg']) { t = res['meta']['msg']; } _this.animateLoading('done', t); } else { t = "Oops, something has gone bad. Please reload the browser and try again."; if (res && res['meta'] && res['meta']['msg']) { t = res['meta']['msg']; } _this.animateLoading('error', t); } _this.props.onResponse(res); _this.props.onNativeResponse(response); }).catch(function (error) { t = "Oops, something has gone bad. Please reload the browser and try again."; _this.animateLoading('error', t); if (typeof _this.props.onError === 'function') { _this.props.onError(error); } }); event.preventDefault(); }; _proto.render = function render() { return /*#__PURE__*/React.createElement("div", { className: "rycard" }, /*#__PURE__*/React.createElement("div", { className: "card" }, /*#__PURE__*/React.createElement("div", { className: "card-header" }, /*#__PURE__*/React.createElement("div", { className: "row" }, /*#__PURE__*/React.createElement("div", { className: "col-12 col-sm-6" }, /*#__PURE__*/React.createElement("span", { className: "h5 mb-0" }, this.props.email)), /*#__PURE__*/React.createElement("div", { className: "col-12 col-sm-6 text-right" }, /*#__PURE__*/React.createElement("span", { className: "h5 text-success mb-0" }, "$ ", this.props.price)))), /*#__PURE__*/React.createElement("div", { className: "card-body" }, /*#__PURE__*/React.createElement("form", { onSubmit: this.handleSubmit }, /*#__PURE__*/React.createElement("div", { className: "row" }, /*#__PURE__*/React.createElement("div", { className: "col-12" }, /*#__PURE__*/React.createElement("div", { className: "form-group" }, /*#__PURE__*/React.createElement("label", { htmlFor: "cc-number", className: "control-label" }, "Card Number"), /*#__PURE__*/React.createElement("input", { id: "cc-number", type: "text", className: 'form-control ' + this.getWarningClassOnFields('number'), onBlur: this.handleCardNumberBlur, onChange: this.handleCardNumberChange }), this.getWarningOnFields('number')))), /*#__PURE__*/React.createElement("div", { className: "row" }, /*#__PURE__*/React.createElement("div", { className: "col-12" }, /*#__PURE__*/React.createElement("label", { htmlFor: "cc-exp", className: "control-label" }, "Expiry (Month/Year)"), /*#__PURE__*/React.createElement("input", { id: "cc-exp", type: "text", placeholder: "12/2025", className: 'form-control ' + this.getWarningClassOnFields('expiry'), onBlur: this.handleCardExpiryBlur, onChange: this.handleCardExpiryChange }), this.getWarningOnFields('expiry'))), /*#__PURE__*/React.createElement("div", { className: "row" }, /*#__PURE__*/React.createElement("div", { className: "col-12" }, /*#__PURE__*/React.createElement("div", { className: "form-group mt-3" }, /*#__PURE__*/React.createElement("label", { htmlFor: "cc-cvv", className: "control-label" }, "CVV"), /*#__PURE__*/React.createElement("input", { id: "cc-cvv", type: "text", className: 'form-control ' + this.getWarningClassOnFields('cvv'), onBlur: this.handleCardCVCCBlur, onChange: this.handleCardCVCChange }), this.getWarningOnFields('cvv')))), /*#__PURE__*/React.createElement("div", { className: "row" }, /*#__PURE__*/React.createElement("div", { className: "col-12" }, /*#__PURE__*/React.createElement(Ryloading, { text: this.state.resp.text, status: this.state.loading.status, alert: this.state.loading.alert, size: this.props.size, onRyLoadingReset: this.onRyLoadingReset }), /*#__PURE__*/React.createElement("div", { className: "form-group mt-3 mb-1 text-right" }, /*#__PURE__*/React.createElement("button", { className: "btn btn-primary", disabled: !this.getIsSubmitIsOk(), type: "submit" }, "Make Payment")))))))); }; return Rycard; }(Component); Rycard.defaultProps = { email: "unknown@unknown.com", price: 0, endpoint: undefined, size: 'small', onResponse: function onResponse() {}, onError: function onError() {}, onNativeResponse: function onNativeResponse() {} }; export default Rycard; //# sourceMappingURL=index.modern.js.map