UNPKG

bnbservice-checkout-embed

Version:

Embeddable app to facilitate the request of a service instance

728 lines (631 loc) 30.1 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _regenerator = require('babel-runtime/regenerator'); var _regenerator2 = _interopRequireDefault(_regenerator); var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reduxForm = require('redux-form'); var _reactRedux = require('react-redux'); var _widgets = require('../utilities/widgets'); var _bnbserviceBaseForm = require('bnbservice-base-form'); var _billingSettingsForm = require('./billing-settings-form.js'); var _currencySymbolMap = require('currency-symbol-map'); var _currencySymbolMap2 = _interopRequireDefault(_currencySymbolMap); var _price = require('../utilities/price.js'); var _reduxFormValidators = require('redux-form-validators'); var _reactStripeElements = require('react-stripe-elements'); var _client = require('../core-input-types/client'); var _client2 = _interopRequireDefault(_client); var _handleInputs = require('../widget-inputs/handleInputs'); var _object = require('object.values'); var _object2 = _interopRequireDefault(_object); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // import 'react-tagsinput/react-tagsinput.css'; // import '../css/template-create.css'; var _ = require("lodash"); if (!Object.values) { _object2.default.shim(); } var selector = (0, _reduxForm.formValueSelector)('serviceInstanceRequestForm'); // <-- same as form name //Custom property var renderCustomProperty = function renderCustomProperty(props) { var fields = props.fields, formJSON = props.formJSON, _props$meta = props.meta, touched = _props$meta.touched, error = _props$meta.error; var widgets = (0, _client2.default)().reduce(function (acc, widget) { acc[widget.type] = widget; return acc; }, {}); return _react2.default.createElement( 'div', null, fields.map(function (customProperty, index) { var property = widgets[formJSON[index].type]; var validate = []; if (formJSON[index].type === "metric") { return _react2.default.createElement('div', null); } if (formJSON[index].required) { validate.push((0, _reduxFormValidators.required)()); } if (formJSON[index].prompt_user) { return _react2.default.createElement(_reduxForm.Field, { key: index, name: customProperty + '.data.value', type: formJSON[index].type, widget: property.widget, component: _bnbserviceBaseForm.widgetField, label: formJSON[index].prop_label // value={formJSON[index].data.value} , formJSON: formJSON[index], configValue: formJSON[index].config, validate: validate }); } else { if (formJSON[index].data && formJSON[index].data.value && !formJSON[index].private) { return _react2.default.createElement( 'div', { className: 'form-group form-group-flex' }, formJSON[index].prop_label && formJSON[index].type !== 'hidden' && _react2.default.createElement( 'label', { className: 'control-label form-label-flex-md' }, formJSON[index].prop_label ), _react2.default.createElement( 'div', { className: 'form-input-flex' }, _react2.default.createElement( 'p', null, formJSON[index].data.value ) ) ); } else { return _react2.default.createElement('span', null); } } }) ); }; //The full form var ServiceRequestForm = function (_React$Component) { (0, _inherits3.default)(ServiceRequestForm, _React$Component); function ServiceRequestForm(props) { (0, _classCallCheck3.default)(this, ServiceRequestForm); var _this = (0, _possibleConstructorReturn3.default)(this, (ServiceRequestForm.__proto__ || Object.getPrototypeOf(ServiceRequestForm)).call(this, props)); _this.state = { price: props.plan.amount }; return _this; } (0, _createClass3.default)(ServiceRequestForm, [{ key: 'componentDidUpdate', value: function componentDidUpdate(prevProps, prevState) { var _props = this.props, handleSubmit = _props.handleSubmit, formJSON = _props.formJSON, helpers = _props.helpers, error = _props.error, step = _props.step, plan = _props.plan; var self = this; if (prevState.price === this.state.price) { var handlers = (0, _client2.default)().reduce(function (acc, widget) { acc[widget.type] = widget.handler; return acc; }, {}); var newPrice = plan.amount; try { newPrice = (0, _handleInputs.getPrice)(formJSON.references.service_template_properties, handlers, plan.amount); if (newPrice !== self.state.price) { helpers.updatePrice(newPrice); self.setState({ price: newPrice }); } } catch (e) { console.error(e); } } } }, { key: 'render', value: function render() { var _props2 = this.props, handleSubmit = _props2.handleSubmit, formJSON = _props2.formJSON, helpers = _props2.helpers, error = _props2.error, step = _props2.step, plan = _props2.plan, needsCard = _props2.needsCard; var price = this.state.price; var getRequestText = function getRequestText() { var serType = plan.type; var trial = plan.trial_period_days > 0; var prefix = (0, _currencySymbolMap2.default)(plan.currency); if (trial) { return "Sign Up"; } else { if (serType === "subscription") { return _react2.default.createElement( 'span', null, 'Subscribe Now' ); } else if (serType === "one_time") { return _react2.default.createElement( 'span', null, 'Pay Now' ); } else if (serType === "custom") { return _react2.default.createElement( 'span', null, 'Request' ); } else if (serType === "split") { return _react2.default.createElement( 'span', null, 'Pay Now' ); } else { return _react2.default.createElement( 'span', null, 'Pay Now' ); } } }; var buttonText = plan && plan.type !== "custom" ? "Next" : "Contact"; var checkoutText = plan && plan.trial_period_days > 0 ? "Sign Up" : "Pay Now"; //Sort users and if user does not have name set, set it to the email value which will always be there return _react2.default.createElement( 'div', { className: 'rf--body' }, _react2.default.createElement( 'form', { onSubmit: handleSubmit }, step === 0 && _react2.default.createElement( 'div', null, !helpers.uid && _react2.default.createElement( 'div', { className: 'rf--form-inner _step-0' }, _react2.default.createElement( 'div', { className: '_heading-wrapper' }, _react2.default.createElement( 'h2', null, 'Create Account' ) ), _react2.default.createElement( 'div', { className: '_content_wrapper' }, _react2.default.createElement(_reduxForm.Field, { name: 'email', type: 'text', component: _bnbserviceBaseForm.inputField, label: 'Email Address', validate: [(0, _reduxFormValidators.required)(), (0, _reduxFormValidators.email)()] }), helpers.emailExists && "That email is in use", helpers.setPassword && plan.type !== "custom" && _react2.default.createElement( 'div', null, _react2.default.createElement(_reduxForm.Field, { name: 'password', type: 'password', component: _bnbserviceBaseForm.inputField, label: 'Password', validate: [(0, _reduxFormValidators.length)({ min: 8 }), (0, _reduxFormValidators.required)()] }), _react2.default.createElement(_reduxForm.Field, { name: 'password_confirmation', type: 'password', label: 'Password confirmation', component: _bnbserviceBaseForm.inputField, validate: [(0, _reduxFormValidators.confirmation)({ field: 'password', fieldLabel: 'Password' })] }) ), _react2.default.createElement( _reduxForm.FormSection, { name: 'references' }, _react2.default.createElement(_reduxForm.FieldArray, { name: 'service_template_properties', component: renderCustomProperty, formJSON: formJSON.references.service_template_properties }) ), _react2.default.createElement( 'div', { className: 'button-wrapper _center' }, _react2.default.createElement( 'button', { className: 'buttons _primary _next' }, buttonText ) ) ) ) ) //end step 0 , step === 1 && _react2.default.createElement( 'div', { className: 'rf--form-inner _step-1' }, _react2.default.createElement( 'div', { className: '_heading-wrapper' }, _react2.default.createElement( 'h2', null, 'Checkout' ) ), this.props.summary, _react2.default.createElement( 'div', { className: '_content_wrapper' }, needsCard && _react2.default.createElement(_billingSettingsForm.CardSection, null), _react2.default.createElement( 'div', { className: 'button-wrapper _center _space-between' }, _react2.default.createElement( 'button', { onClick: helpers.stepBack, className: 'buttons _primary _text submit-request' }, 'Back' ), _react2.default.createElement( 'button', { className: 'buttons _primary submit-request', type: 'submit', value: 'submit' }, getRequestText() ) ) ) ), error && _react2.default.createElement( 'strong', null, error ) ) ); } }]); return ServiceRequestForm; }(_react2.default.Component); ServiceRequestForm = (0, _reactRedux.connect)(function (state, ownProps) { return { "serviceTypeValue": selector(state, 'type'), formJSON: (0, _reduxForm.getFormValues)('serviceInstanceRequestForm')(state) }; })(ServiceRequestForm); var ServiceInstanceForm = function (_React$Component2) { (0, _inherits3.default)(ServiceInstanceForm, _React$Component2); function ServiceInstanceForm(props) { (0, _classCallCheck3.default)(this, ServiceInstanceForm); var _this2 = (0, _possibleConstructorReturn3.default)(this, (ServiceInstanceForm.__proto__ || Object.getPrototypeOf(ServiceInstanceForm)).call(this, props)); var templateId = _this2.props.templateId || 1; _this2.state = { uid: _this2.props.uid, stripToken: null, templateId: templateId, templateData: _this2.props.service, formData: _this2.props.service, formURL: _this2.props.url + "/api/v1/service-templates/" + templateId + "/request", formResponseData: null, formResponseError: null, serviceCreated: false, servicePrice: _this2.props.plan.amount, usersData: {}, usersURL: "/api/v1/users", hasCard: null, loading: true, hasFund: false, step: 0 }; _this2.closeUserLoginModal = _this2.closeUserLoginModal.bind(_this2); _this2.updatePrice = _this2.updatePrice.bind(_this2); _this2.submissionPrep = _this2.submissionPrep.bind(_this2); _this2.handleResponse = _this2.handleResponse.bind(_this2); _this2.handleFailure = _this2.handleFailure.bind(_this2); return _this2; } (0, _createClass3.default)(ServiceInstanceForm, [{ key: 'componentDidMount', value: function () { var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee() { var self; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: self = this; this.setState({ loading: false }); // let headers = new Headers({ // "Content-Type": "application/json" // }); // // Fetcher(self.state.formURL,).then(function (response) { // if (!response.error) { // self.setState({loading: false, templateData: response, formData: response}); // } else { // console.error("Error", response.error); // self.setState({loading: false}); // } // }).catch(function (err) { // console.error("ERROR!", err); // }); case 2: case 'end': return _context.stop(); } } }, _callee, this); })); function componentDidMount() { return _ref.apply(this, arguments); } return componentDidMount; }() }, { key: 'componentDidUpdate', value: function componentDidUpdate(nextProps, nextState) { if (nextState.serviceCreated) { // browserHistory.push(`/service-instance/${nextState.serviceCreated.id}`); } } }, { key: 'updatePrice', value: function updatePrice(newPrice) { var self = this; console.log("UP RIC", newPrice); self.setState({ servicePrice: newPrice }); } }, { key: 'handleFailure', value: function handleFailure(event) { this.props.setLoading(false); } }, { key: 'closeUserLoginModal', value: function closeUserLoginModal() { this.setState({ emailExists: false }); } }, { key: 'submissionPrep', value: function () { var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(values) { var needsCard, token; return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: if (!(this.state.step === 0 && this.props.plan.type !== "custom")) { _context2.next = 3; break; } this.props.stepForward(); throw ""; case 3: this.props.setLoading(true); needsCard = this.state.servicePrice > 0 && this.props.plan.type !== "custom" && !this.state.hasCard && this.props.plan.trial_period_days <= 0 || this.props.forceCard || this.props.plan.type === "split"; if (!needsCard) { _context2.next = 15; break; } _context2.next = 8; return this.props.stripe.createToken(); case 8: token = _context2.sent; if (!token.error) { _context2.next = 12; break; } this.props.setLoading(false); throw token.error.message; case 12: return _context2.abrupt('return', (0, _extends3.default)({}, values, { token_id: token.token.id })); case 15: return _context2.abrupt('return', values); case 16: case 'end': return _context2.stop(); } } }, _callee2, this); })); function submissionPrep(_x) { return _ref2.apply(this, arguments); } return submissionPrep; }() }, { key: 'handleResponse', value: function () { var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(response) { return _regenerator2.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: this.setState({ serviceCreated: true }); _context3.prev = 1; if (!this.props.handleResponse) { _context3.next = 5; break; } _context3.next = 5; return this.props.handleResponse(response); case 5: _context3.next = 10; break; case 7: _context3.prev = 7; _context3.t0 = _context3['catch'](1); console.error(_context3.t0); case 10: this.props.setLoading(false); if (this.props.redirect) { window.location = this.props.redirect; } case 12: case 'end': return _context3.stop(); } } }, _callee3, this, [[1, 7]]); })); function handleResponse(_x2) { return _ref3.apply(this, arguments); } return handleResponse; }() }, { key: 'formValidation', value: function formValidation(values) { var props = values.references && values.references.service_template_properties ? values.references.service_template_properties : []; var re = props.reduce(function (acc, prop, index) { if (prop.required && (!prop.data || !prop.data.value)) { acc[index] = { data: { value: "is required" } }; } return acc; }, {}); var validation = { references: { service_template_properties: re } }; if (Object.keys(re).length === 0) { delete validation.references; } return validation; } }, { key: 'render', value: function render() { var self = this; var initialValues = this.props.service; var initialRequests = []; // let submissionPrep = (values) => {self.props.setLoading(true); return values;} var submissionRequest = { 'method': 'POST', 'url': this.props.url + '/api/v1/service-templates/' + this.props.templateId + '/request' }; var successMessage = "Service Requested"; var successRoute = "/my-services"; //If admin requested, redirect to the manage subscription page console.log(this.state.servicePrice, this.props.plan); var needsCard = this.state.servicePrice > 0 && this.props.plan.type !== "custom" && !this.state.hasCard && this.props.plan.trial_period_days <= 0 || this.props.forceCard || this.props.plan.type === "split"; var helpers = Object.assign(this.state, this.props); helpers.updatePrice = self.updatePrice; helpers.stepForward = this.props.stepForward; helpers.stepBack = this.props.stepBack; // consoe.log("HELLO!!!!"); // } // self.setState({step : step + 1})}; // helpers.stepBack = () => {console.log("HELLO")}; // self.setState({step : step - 1})}; helpers.step = this.props.step; //Gets a token to populate token_id for instance request return _react2.default.createElement( 'div', { className: 'rf--form-elements' }, _react2.default.createElement(_bnbserviceBaseForm.BnbServiceBaseForm, { form: ServiceRequestForm, initialValues: initialValues, initialRequests: initialRequests, submissionPrep: this.submissionPrep, submissionRequest: submissionRequest, successMessage: successMessage // successRoute={successRoute} , handleResponse: this.handleResponse, handleFailure: this.handleFailure, formName: 'serviceInstanceRequestForm', helpers: helpers, formProps: { needsCard: needsCard, summary: this.props.summary, plan: this.props.plan, step: this.props.step }, validations: this.formValidation, loaderTimeout: false, external: this.props.external }) ); } }]); return ServiceInstanceForm; }(_react2.default.Component); var mapDispatchToProps = function mapDispatchToProps(dispatch) { return { setLoading: function setLoading(is_loading) { dispatch({ type: "SET_LOADING", is_loading: is_loading }); }, setOverrides: function setOverrides(propName, prop) { if (!event.currentTarget.value || event.currentTarget.value == 'false') { dispatch(change(TEMPLATE_FORM_NAME, 'references.' + ownProps.member + '.private', false)); } } }; }; ServiceInstanceForm = (0, _reactStripeElements.injectStripe)(ServiceInstanceForm); ServiceInstanceForm = (0, _reactRedux.connect)(null, mapDispatchToProps)(ServiceInstanceForm); var BnbServiceRequestForm = function (_React$Component3) { (0, _inherits3.default)(BnbServiceRequestForm, _React$Component3); function BnbServiceRequestForm(props) { (0, _classCallCheck3.default)(this, BnbServiceRequestForm); var _this3 = (0, _possibleConstructorReturn3.default)(this, (BnbServiceRequestForm.__proto__ || Object.getPrototypeOf(BnbServiceRequestForm)).call(this, props)); _this3.state = { loading: true }; _this3.getSPK = _this3.getSPK.bind(_this3); return _this3; } (0, _createClass3.default)(BnbServiceRequestForm, [{ key: 'componentDidMount', value: function componentDidMount() { this.getSPK(); } }, { key: 'getSPK', value: function getSPK() { var self = this; fetch(this.props.url + '/api/v1/stripe/spk').then(function (response) { return response.json(); }).then(function (json) { self.setState({ loading: false, spk: json.spk }); }).catch(function (e) { return console.error(e); }); } }, { key: 'render', value: function render() { console.log(this.props); var spk = this.state.spk; if (this.state.loading) { return _react2.default.createElement( 'div', { className: 'loader' }, _react2.default.createElement( 'div', { className: 'lds-ellipsis' }, _react2.default.createElement('div', null), _react2.default.createElement('div', null), _react2.default.createElement('div', null), _react2.default.createElement('div', null) ) ); } var form = _react2.default.createElement( _reactStripeElements.StripeProvider, { apiKey: spk || "no_public_token" }, _react2.default.createElement( _reactStripeElements.Elements, null, _react2.default.createElement(ServiceInstanceForm, this.props) ) ); if (this.props.hasStore) { return form; } else { return form; } } }]); return BnbServiceRequestForm; }(_react2.default.Component); exports.default = BnbServiceRequestForm;