bnbservice-checkout-embed
Version:
Embeddable app to facilitate the request of a service instance
728 lines (631 loc) • 30.1 kB
JavaScript
'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;