From 4899bfedc21b23fdd9bc36be2b50cc3548ae9a42 Mon Sep 17 00:00:00 2001 From: sovanna Date: Tue, 14 Apr 2020 18:54:59 +0900 Subject: [PATCH] feat(issue19-22/UI): Updates shop build --- static/js/shop.min.js | 771 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 621 insertions(+), 150 deletions(-) diff --git a/static/js/shop.min.js b/static/js/shop.min.js index 5cef328..f2fb648 100644 --- a/static/js/shop.min.js +++ b/static/js/shop.min.js @@ -6,15 +6,15 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } @@ -39,6 +39,7 @@ var _window$ReactBeautifu = window.ReactBeautifulDnd, Draggable = _window$ReactBeautifu.Draggable, Droppable = _window$ReactBeautifu.Droppable; var data = window.shop_data; +var axios = window.axios; var productStyle = function productStyle(style, snapshot, removeAnim, hovered, selected) { var custom = { @@ -160,13 +161,138 @@ var Layout = function (_React$PureComponent) { _inherits(Layout, _React$PureComponent); - function Layout() { + _createClass(Layout, null, [{ + key: "propTypes", + get: function get() { + return { + aside: PropTypes.any, + main: PropTypes.any, + mobileSideMenuShouldOpen: PropTypes.bool, + isMobile: PropTypes.bool, + newCardJustAdded: PropTypes.bool, + onClickToggleMobileSideMenu: PropTypes.func, + onClickCloseRFQFeedback: PropTypes.func, + RFQBodyType: PropTypes.string, + RFQBodyOrder: PropTypes.string, + onClickLoadCustomConf: PropTypes.func + }; + } + }, { + key: "defaultProps", + get: function get() { + return { + mobileSideMenuShouldOpen: false + }; + } + }]); + + function Layout(props) { + var _this; + _classCallCheck(this, Layout); - return _possibleConstructorReturn(this, _getPrototypeOf(Layout).apply(this, arguments)); + _this = _possibleConstructorReturn(this, _getPrototypeOf(Layout).call(this, props)); + _this.state = { + customconf: '', + error: null + }; + _this.handleCustomConfig = _this.handleCustomConfig.bind(_assertThisInitialized(_this)); + _this.handleClickLoad = _this.handleClickLoad.bind(_assertThisInitialized(_this)); + _this.checkValidation = _this.checkValidation.bind(_assertThisInitialized(_this)); + return _this; } _createClass(Layout, [{ + key: "handleCustomConfig", + value: function handleCustomConfig(e) { + var value = e.target.value; + this.checkValidation(value); + } + }, { + key: "checkValidation", + value: function checkValidation(conf) { + var conf_obj; + + if (!conf) { + conf = this.state.customconf; + } + + try { + conf_obj = JSON.parse(conf); + } catch (e) { + return this.setState(_objectSpread({}, this.state, { + customconf: conf, + customconf_ready: null, + error: 'invalid format' + })); + } + + if (!conf_obj) { + return this.setState(_objectSpread({}, this.state, { + customconf: conf, + customconf_ready: null, + error: 'invalid format' + })); + } + + if ((!conf_obj.items || !conf_obj.type) && (Object.prototype.toString.call(conf_obj.items) !== '[object Array]' || Object.prototype.toString.call(conf_obj.type) !== '[object String]')) { + return this.setState(_objectSpread({}, this.state, { + customconf: conf, + customconf_ready: null, + error: 'invalid format' + })); + } + + if (conf_obj.type !== "desktop" && conf_obj.type !== "rack") { + return this.setState(_objectSpread({}, this.state, { + customconf: conf, + customconf_ready: null, + error: 'invalid format' + })); + } + + conf_obj.items.map(function (item) { + try { + return JSON.parse(item); + } catch (e) { + return null; + } + }); + conf_obj.items = conf_obj.items.filter(function (item) { + return item; + }); + + if (conf_obj.items.filter(function (item) { + return Object.prototype.toString.call(item) !== '[object Object]' || !item.pn || Object.prototype.toString.call(item.pn) !== '[object String]'; + }).length > 0) { + return this.setState(_objectSpread({}, this.state, { + customconf: conf, + customconf_ready: null, + error: 'invalid format' + })); + } + + conf_obj.items = conf_obj.items.map(function (item) { + return { + pn: item.pn + }; + }); + this.setState(_objectSpread({}, this.state, { + customconf: conf, + error: null, + customconf_ready: conf_obj + })); + } + }, { + key: "handleClickLoad", + value: function handleClickLoad() { + this.checkValidation(); + + if (this.props.onClickLoadCustomConf) { + this.props.onClickLoadCustomConf(this.state.customconf_ready); + } + } + }, { key: "render", value: function render() { var _this$props = this.props, @@ -175,7 +301,11 @@ function (_React$PureComponent) { mobileSideMenuShouldOpen = _this$props.mobileSideMenuShouldOpen, isMobile = _this$props.isMobile, newCardJustAdded = _this$props.newCardJustAdded, - onClickToggleMobileSideMenu = _this$props.onClickToggleMobileSideMenu; + onClickToggleMobileSideMenu = _this$props.onClickToggleMobileSideMenu, + onClickCloseRFQFeedback = _this$props.onClickCloseRFQFeedback, + showRFQFeedback = _this$props.showRFQFeedback, + RFQBodyType = _this$props.RFQBodyType, + RFQBodyOrder = _this$props.RFQBodyOrder; return React.createElement("div", { className: "layout" }, React.createElement("aside", { @@ -187,26 +317,88 @@ function (_React$PureComponent) { className: "main" }, main), isMobile && newCardJustAdded ? React.createElement("div", { className: "feedback-add-success" - }, "\u2713 added") : null); - } - }], [{ - key: "propTypes", - get: function get() { - return { - aside: PropTypes.any, - main: PropTypes.any, - mobileSideMenuShouldOpen: PropTypes.bool, - isMobile: PropTypes.bool, - newCardJustAdded: PropTypes.bool, - onClickToggleMobileSideMenu: PropTypes.func - }; - } - }, { - key: "defaultProps", - get: function get() { - return { - mobileSideMenuShouldOpen: false - }; + }, "\u2713 added") : null, React.createElement("div", { + "class": "modal fade ".concat(showRFQFeedback ? 'show' : ''), + style: { + 'display': showRFQFeedback ? 'block' : 'none' + }, + id: "exampleModal", + tabindex: "-1", + role: "dialog", + "aria-labelledby": "exampleModalLabel", + "aria-hidden": "true" + }, React.createElement("div", { + "class": "modal-dialog", + role: "document" + }, React.createElement("div", { + "class": "modal-content" + }, React.createElement("div", { + "class": "modal-body rfqFeedback" + }, React.createElement("div", { + className: "d-flex w-100" + }, RFQBodyType === 'email' ? React.createElement("div", { + className: "d-flex" + }, React.createElement("div", null, React.createElement("img", { + width: "30px", + src: "/images/shop/icon-done.svg", + alt: "close" + })), React.createElement("div", { + style: { + 'padding': '0 .5em' + } + }, "We've received your request and will be in contact soon.")) : null, RFQBodyType === 'show' ? React.createElement("p", null, RFQBodyOrder) : null, RFQBodyType === 'import' ? React.createElement("div", { + className: "w-100" + }, React.createElement("form", { + className: "form w-100" + }, React.createElement("div", { + className: "form-group" + }, React.createElement("p", { + className: "small" + }, "Add your own configuration below. Should be something like:", React.createElement("br", null), JSON.stringify({ + "items": [{ + "pn": "1123" + }, { + "pn": "2118" + }, { + "pn": "2118" + }, { + "pn": "2128" + }], + "type": "desktop" + }))), React.createElement("div", { + className: "form-group w-100" + }, React.createElement("textarea", { + onChange: this.handleCustomConfig, + value: this.state.customconf, + className: "form-control w-100", + rows: "5", + placeholder: "Add your custom configuration here. e.g " + })), this.state.error ? React.createElement("div", { + className: "form-group" + }, React.createElement("p", { + className: "text-danger" + }, this.state.error)) : null), React.createElement("div", { + className: "d-flex flex-column flex-sm-row justify-content-end" + }, React.createElement("a", { + type: "button", + onClick: onClickCloseRFQFeedback, + "class": "btn btn-sm btn-outline-primary m-0 mb-2 mb-sm-0 mr-sm-2" + }, "Close"), React.createElement("a", { + type: "button", + onClick: this.handleClickLoad, + "class": "btn btn-sm btn-primary m-0 ml-sm-2 ".concat(this.state.error ? 'disabled' : '') + }, "Load configuration"))) : null, React.createElement("div", null, React.createElement("button", { + onClick: onClickCloseRFQFeedback + }, React.createElement("img", { + src: "/images/shop/icon-close.svg", + alt: "close" + })))))))), React.createElement("div", { + onClick: onClickCloseRFQFeedback, + className: "modal-backdrop fade ".concat(showRFQFeedback ? 'show' : ''), + style: { + 'display': showRFQFeedback ? 'initial' : 'none' + } + })); } }]); @@ -241,13 +433,13 @@ function (_React$PureComponent2) { }]); function ProductItem(props) { - var _this; + var _this2; _classCallCheck(this, ProductItem); - _this = _possibleConstructorReturn(this, _getPrototypeOf(ProductItem).call(this, props)); - _this.handleOnClickAddItem = _this.handleOnClickAddItem.bind(_assertThisInitialized(_this)); - return _this; + _this2 = _possibleConstructorReturn(this, _getPrototypeOf(ProductItem).call(this, props)); + _this2.handleOnClickAddItem = _this2.handleOnClickAddItem.bind(_assertThisInitialized(_this2)); + return _this2; } _createClass(ProductItem, [{ @@ -349,19 +541,19 @@ function (_React$PureComponent3) { }]); function ProductCartItem(props) { - var _this2; + var _this3; _classCallCheck(this, ProductCartItem); - _this2 = _possibleConstructorReturn(this, _getPrototypeOf(ProductCartItem).call(this, props)); - _this2.handleOnMouseEnterItem = _this2.handleOnMouseEnterItem.bind(_assertThisInitialized(_this2)); - _this2.handleOnMouseLeaveItem = _this2.handleOnMouseLeaveItem.bind(_assertThisInitialized(_this2)); - _this2.handleOnMouseEnterWarningItem = _this2.handleOnMouseEnterWarningItem.bind(_assertThisInitialized(_this2)); - _this2.handleOnMouseLeaveWarningItem = _this2.handleOnMouseLeaveWarningItem.bind(_assertThisInitialized(_this2)); - _this2.handleOnMouseEnterRemoveItem = _this2.handleOnMouseEnterRemoveItem.bind(_assertThisInitialized(_this2)); - _this2.handleOnMouseLeaveRemoveItem = _this2.handleOnMouseLeaveRemoveItem.bind(_assertThisInitialized(_this2)); - _this2.handleOnClickRemoveItem = _this2.handleOnClickRemoveItem.bind(_assertThisInitialized(_this2)); - return _this2; + _this3 = _possibleConstructorReturn(this, _getPrototypeOf(ProductCartItem).call(this, props)); + _this3.handleOnMouseEnterItem = _this3.handleOnMouseEnterItem.bind(_assertThisInitialized(_this3)); + _this3.handleOnMouseLeaveItem = _this3.handleOnMouseLeaveItem.bind(_assertThisInitialized(_this3)); + _this3.handleOnMouseEnterWarningItem = _this3.handleOnMouseEnterWarningItem.bind(_assertThisInitialized(_this3)); + _this3.handleOnMouseLeaveWarningItem = _this3.handleOnMouseLeaveWarningItem.bind(_assertThisInitialized(_this3)); + _this3.handleOnMouseEnterRemoveItem = _this3.handleOnMouseEnterRemoveItem.bind(_assertThisInitialized(_this3)); + _this3.handleOnMouseLeaveRemoveItem = _this3.handleOnMouseLeaveRemoveItem.bind(_assertThisInitialized(_this3)); + _this3.handleOnClickRemoveItem = _this3.handleOnClickRemoveItem.bind(_assertThisInitialized(_this3)); + return _this3; } _createClass(ProductCartItem, [{ @@ -436,7 +628,7 @@ function (_React$PureComponent3) { }, { key: "render", value: function render() { - var _this3 = this; + var _this4 = this; var _this$props3 = this.props, hovered = _this$props3.hovered, @@ -491,15 +683,15 @@ function (_React$PureComponent3) { ref: provided.innerRef }, provided.draggableProps, provided.dragHandleProps, { style: _objectSpread({}, productStyle(provided.draggableProps.style, snapshot, true, hovered ? true : false, model.selected ? true : false)), - onMouseEnter: _this3.handleOnMouseEnterRemoveItem.bind(_this3, index), - onMouseLeave: _this3.handleOnMouseLeaveRemoveItem.bind(_this3, index) + onMouseEnter: _this4.handleOnMouseEnterRemoveItem.bind(_this4, index), + onMouseLeave: _this4.handleOnMouseLeaveRemoveItem.bind(_this4, index) }), React.createElement("div", { style: { 'height': '24px' }, className: "progress-container warning", - onMouseEnter: _this3.handleOnMouseEnterWarningItem.bind(_this3, index, warning), - onMouseLeave: _this3.handleOnMouseLeaveWarningItem.bind(_this3, index, warning) + onMouseEnter: _this4.handleOnMouseEnterWarningItem.bind(_this4, index, warning), + onMouseLeave: _this4.handleOnMouseLeaveWarningItem.bind(_this4, index, warning) }, warning && React.createElement("img", { className: "alert-warning", src: warning ? "/images".concat(warning.icon) : null @@ -511,7 +703,7 @@ function (_React$PureComponent3) { style: { 'height': '350px' }, - onMouseEnter: _this3.handleOnMouseEnterRemoveItem.bind(_this3, index) + onMouseEnter: _this4.handleOnMouseEnterRemoveItem.bind(_this4, index) }, React.createElement("img", { className: "item-cart", src: "/images".concat(model.image) @@ -520,7 +712,7 @@ function (_React$PureComponent3) { 'display': model.showOverlayRemove ? 'flex' : 'none' }, className: "overlayRemove", - onClick: _this3.handleOnClickRemoveItem.bind(_this3, index) + onClick: _this4.handleOnClickRemoveItem.bind(_this4, index) }, React.createElement("img", { src: "/images/shop/icon-remove.svg", alt: "rm" @@ -529,8 +721,8 @@ function (_React$PureComponent3) { 'height': '22px' }, className: "progress-container", - onMouseEnter: _this3.handleOnMouseEnterItem.bind(_this3, index), - onMouseLeave: _this3.handleOnMouseLeaveItem.bind(_this3, index) + onMouseEnter: _this4.handleOnMouseEnterItem.bind(_this4, index), + onMouseLeave: _this4.handleOnMouseLeaveItem.bind(_this4, index) }, model.nbrSlotMax > 0 && React.createElement("div", { className: "nbr-connectors" }, React.createElement("div", { @@ -708,13 +900,13 @@ function (_React$PureComponent6) { }]); function CrateMode(props) { - var _this4; + var _this5; _classCallCheck(this, CrateMode); - _this4 = _possibleConstructorReturn(this, _getPrototypeOf(CrateMode).call(this, props)); - _this4.handleOnClickMode = _this4.handleOnClickMode.bind(_assertThisInitialized(_this4)); - return _this4; + _this5 = _possibleConstructorReturn(this, _getPrototypeOf(CrateMode).call(this, props)); + _this5.handleOnClickMode = _this5.handleOnClickMode.bind(_assertThisInitialized(_this5)); + return _this5; } _createClass(CrateMode, [{ @@ -729,7 +921,7 @@ function (_React$PureComponent6) { }, { key: "render", value: function render() { - var _this5 = this; + var _this6 = this; var _this$props6 = this.props, mode = _this$props6.mode, @@ -740,7 +932,7 @@ function (_React$PureComponent6) { return React.createElement("a", { key: item.id, className: mode == item.id ? 'active' : '', - onClick: _this5.handleOnClickMode.bind(_this5, item.id), + onClick: _this6.handleOnClickMode.bind(_this6, item.id), href: "#", role: "button" }, item.name); @@ -831,14 +1023,22 @@ function (_React$PureComponent8) { summaryPrice = _this$props8.summaryPrice, form = _this$props8.form, isMobile = _this$props8.isMobile, - onClickToggleMobileSideMenu = _this$props8.onClickToggleMobileSideMenu; + onClickToggleMobileSideMenu = _this$props8.onClickToggleMobileSideMenu, + onClickOpenImport = _this$props8.onClickOpenImport; return React.createElement("section", { className: "panel" }, React.createElement("h2", null, title), React.createElement("div", { className: "control" }, React.createElement("p", { className: "description" - }, description), crateMode), isMobile ? React.createElement("div", { + }, description), crateMode), React.createElement("div", null, React.createElement("input", { + className: "btn btn-sm btn-outline-primary m-0 mb-2", + style: { + 'cursor': 'pointer' + }, + value: "Import configurations", + onClick: onClickOpenImport + })), isMobile ? React.createElement("div", { className: "mobileBtnDisplaySideMenu" }, React.createElement("button", { onClick: onClickToggleMobileSideMenu @@ -860,7 +1060,8 @@ function (_React$PureComponent8) { summaryPrice: PropTypes.element, form: PropTypes.element, isMobile: PropTypes.bool, - onClickToggleMobileSideMenu: PropTypes.func + onClickToggleMobileSideMenu: PropTypes.func, + onClickOpenImport: PropTypes.func }; } }]); @@ -881,57 +1082,205 @@ function (_React$PureComponent9) { key: "propTypes", get: function get() { return { + isProcessing: PropTypes.bool, + isProcessingComplete: PropTypes.bool, onClickSubmit: PropTypes.func }; } }]); function OrderForm(props) { - var _this6; + var _this7; _classCallCheck(this, OrderForm); - _this6 = _possibleConstructorReturn(this, _getPrototypeOf(OrderForm).call(this, props)); - _this6.state = { - note: '' + _this7 = _possibleConstructorReturn(this, _getPrototypeOf(OrderForm).call(this, props)); + _this7.state = { + note: '', + email: '', + error: { + note: null, + email: null + }, + empty: { + note: null, + email: null + } }; - _this6.handleNoteChange = _this6.handleNoteChange.bind(_assertThisInitialized(_this6)); - _this6.handleSubmit = _this6.handleSubmit.bind(_assertThisInitialized(_this6)); - return _this6; + _this7.handleEmail = _this7.handleEmail.bind(_assertThisInitialized(_this7)); + _this7.handleNote = _this7.handleNote.bind(_assertThisInitialized(_this7)); + _this7.handleSubmit = _this7.handleSubmit.bind(_assertThisInitialized(_this7)); + _this7.resetEmptyError = _this7.resetEmptyError.bind(_assertThisInitialized(_this7)); + _this7.checkValidation = _this7.checkValidation.bind(_assertThisInitialized(_this7)); + return _this7; } _createClass(OrderForm, [{ - key: "handleNoteChange", - value: function handleNoteChange(event) { - this.setState({ - note: event.target.value + key: "checkValidation", + value: function checkValidation() { + var isValid = true; + + var validationFields = _objectSpread({}, this.state); + + var _this$validateEmail = this.validateEmail(this.state.email), + isEmailEmpty = _this$validateEmail.isEmpty, + isEmailError = _this$validateEmail.isError; + + validationFields = _objectSpread({}, validationFields, { + error: _objectSpread({}, this.state.error, { + email: isEmailError + }), + empty: _objectSpread({}, this.state.empty, { + email: isEmailEmpty + }) }); + this.setState(validationFields); + isValid = !isEmailEmpty && !isEmailError; + return isValid; + } + }, { + key: "validateEmail", + value: function validateEmail(value) { + var isEmpty = null; + var isError = null; + var t = this.props.t; + + if (!value || value.trim() === '') { + isEmpty = true; + } else if (value && !value.match(/^\w+([\+\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/)) { + isError = { + message: 'Your email is incomplete' + }; + } + + return { + isEmpty: isEmpty, + isError: isError + }; + } + }, { + key: "validateNote", + value: function validateNote(value) { + var isEmpty = null; + + if (!value || value.trim() === '') { + isEmpty = true; + } + + return { + isEmpty: isEmpty + }; + } + }, { + key: "resetEmptyError", + value: function resetEmptyError(key) { + this.setState(_objectSpread({}, this.state, { + error: _objectSpread({}, this.state.error, _defineProperty({}, key, null)), + empty: _objectSpread({}, this.state.empty, _defineProperty({}, key, null)) + })); + } + }, { + key: "handleEmail", + value: function handleEmail(e) { + var value = e.target.value; + + var _this$validateEmail2 = this.validateEmail(value), + isEmpty = _this$validateEmail2.isEmpty, + isError = _this$validateEmail2.isError; + + this.setState(_objectSpread({}, this.state, { + email: value, + error: _objectSpread({}, this.state.error, { + email: isError + }), + empty: _objectSpread({}, this.state.empty, { + email: isEmpty + }) + })); + } + }, { + key: "handleNote", + value: function handleNote(e) { + var value = e.target.value; + this.setState(_objectSpread({}, this.state, { + note: value + })); } }, { key: "handleSubmit", value: function handleSubmit(event) { - if (this.props.onClickSubmit) { - this.props.onClickSubmit(this.state.note); - } - event.preventDefault(); + + if (this.props.onClickSubmit) { + // check validation input fields + var isValidated = this.checkValidation(); + + if (!isValidated) { + return false; + } + + this.props.onClickSubmit(this.state.note, this.state.email); + } } }, { key: "render", value: function render() { + var handleEmail = this.handleEmail, + handleNote = this.handleNote, + resetEmptyError = this.resetEmptyError, + handleSubmit = this.handleSubmit; + var onClickShow = this.props.onClickShow; + var _this$state = this.state, + email = _this$state.email, + note = _this$state.note, + error = _this$state.error, + empty = _this$state.empty; + var _this$props9 = this.props, + isProcessing = _this$props9.isProcessing, + isProcessingComplete = _this$props9.isProcessingComplete; return React.createElement("div", { className: "summary-form" }, React.createElement("form", { - onSubmit: this.handleSubmit - }, React.createElement("textarea", { - value: this.state.note, - onChange: this.handleNoteChange, + onSubmit: handleSubmit, + noValidate: true + }, React.createElement("input", { + className: "".concat(error && error.email ? 'errorField' : ''), + type: "email", + placeholder: "Email", + onFocus: function onFocus() { + return resetEmptyError('email'); + }, + onChange: handleEmail, + onBlur: handleEmail, + value: email + }), empty && empty.email ? React.createElement("div", { + className: "error" + }, React.createElement("small", null, "Required")) : null, error && error.email ? React.createElement("div", { + className: "error" + }, React.createElement("small", null, "Your email is incomplete")) : null, React.createElement("textarea", { + onChange: handleNote, + value: note, rows: "5", placeholder: "Additional notes" + }), React.createElement("div", { + className: "d-flex flex-column flex-sm-row justify-content-between" + }, React.createElement("input", { + className: "btn btn-outline-primary w-100 m-0 mb-2 mb-sm-0 mr-sm-2", + style: { + 'cursor': 'pointer', + 'fontWeight': '700' + }, + value: "Show configurations", + onClick: onClickShow }), React.createElement("input", { + className: "btn btn-primary w-100 m-0 ml-sm-2", + style: Object.assign({}, isProcessingComplete ? { + 'backgroundColor': 'gray' + } : {}), + disabled: isProcessingComplete, type: "submit", - value: "Request quote" - }), "This will open an email window. Send the email to make your request.")); + value: "".concat(isProcessing ? 'Processing ...' : 'Request quote') + })))); } }]); @@ -967,17 +1316,17 @@ function (_React$PureComponent10) { }]); function OrderSumary(props) { - var _this7; + var _this8; _classCallCheck(this, OrderSumary); - _this7 = _possibleConstructorReturn(this, _getPrototypeOf(OrderSumary).call(this, props)); - _this7.handleOnDeleteItem = _this7.handleOnDeleteItem.bind(_assertThisInitialized(_this7)); - _this7.handleOnDeleteAllItems = _this7.handleOnDeleteAllItems.bind(_assertThisInitialized(_this7)); - _this7.handleOnMouseEnterItem = _this7.handleOnMouseEnterItem.bind(_assertThisInitialized(_this7)); - _this7.handleOnMouseLeaveItem = _this7.handleOnMouseLeaveItem.bind(_assertThisInitialized(_this7)); - _this7.handleOnClickSelectItem = _this7.handleOnClickSelectItem.bind(_assertThisInitialized(_this7)); - return _this7; + _this8 = _possibleConstructorReturn(this, _getPrototypeOf(OrderSumary).call(this, props)); + _this8.handleOnDeleteItem = _this8.handleOnDeleteItem.bind(_assertThisInitialized(_this8)); + _this8.handleOnDeleteAllItems = _this8.handleOnDeleteAllItems.bind(_assertThisInitialized(_this8)); + _this8.handleOnMouseEnterItem = _this8.handleOnMouseEnterItem.bind(_assertThisInitialized(_this8)); + _this8.handleOnMouseLeaveItem = _this8.handleOnMouseLeaveItem.bind(_assertThisInitialized(_this8)); + _this8.handleOnClickSelectItem = _this8.handleOnClickSelectItem.bind(_assertThisInitialized(_this8)); + return _this8; } _createClass(OrderSumary, [{ @@ -1030,14 +1379,14 @@ function (_React$PureComponent10) { }, { key: "render", value: function render() { - var _this8 = this; + var _this9 = this; - var _this$props9 = this.props, - currency = _this$props9.currency, - modes = _this$props9.modes, - currentMode = _this$props9.currentMode, - summary = _this$props9.summary, - itemsData = _this$props9.itemsData; + var _this$props10 = this.props, + currency = _this$props10.currency, + modes = _this$props10.modes, + currentMode = _this$props10.currentMode, + summary = _this$props10.summary, + itemsData = _this$props10.itemsData; var mode = modes.find(function (elem) { return elem.id === currentMode; }); @@ -1084,15 +1433,15 @@ function (_React$PureComponent10) { return React.createElement("tr", { key: item.id, className: "hoverable ".concat(item.selected ? 'selected' : ''), - onClick: _this8.handleOnClickSelectItem.bind(_this8, index), - onMouseEnter: _this8.handleOnMouseEnterItem.bind(_this8, item.id), - onMouseLeave: _this8.handleOnMouseLeaveItem + onClick: _this9.handleOnClickSelectItem.bind(_this9, index), + onMouseEnter: _this9.handleOnMouseEnterItem.bind(_this9, item.id), + onMouseLeave: _this9.handleOnMouseLeaveItem }, React.createElement("td", { className: "item-card-name" }, React.createElement("div", null, "".concat(item.name_number, " ").concat(item.name, " ").concat(item.name_codename))), React.createElement("td", { className: "price" }, React.createElement("div", null, "".concat(currency, " ").concat(formatMoney(item.price)), React.createElement("button", { - onClick: _this8.handleOnDeleteItem.bind(_this8, index) + onClick: _this9.handleOnDeleteItem.bind(_this9, index) }, React.createElement("img", { src: "/images/shop/icon-remove.svg" }))), warning && React.createElement("img", { @@ -1151,13 +1500,13 @@ function (_React$PureComponent11) { _createClass(Backlog, [{ key: "render", value: function render() { - var _this$props10 = this.props, - currency = _this$props10.currency, - data = _this$props10.data, - items = _this$props10.items, - onClickAddItem = _this$props10.onClickAddItem, - onClickToggleMobileSideMenu = _this$props10.onClickToggleMobileSideMenu, - isMobile = _this$props10.isMobile; + var _this$props11 = this.props, + currency = _this$props11.currency, + data = _this$props11.data, + items = _this$props11.items, + onClickAddItem = _this$props11.onClickAddItem, + onClickToggleMobileSideMenu = _this$props11.onClickToggleMobileSideMenu, + isMobile = _this$props11.isMobile; var ordered_items = data.itemIds.map(function (itemId) { return items[itemId]; }); @@ -1239,28 +1588,32 @@ function (_React$PureComponent12) { }]); function Shop(props) { - var _this9; + var _this10; _classCallCheck(this, Shop); - _this9 = _possibleConstructorReturn(this, _getPrototypeOf(Shop).call(this, props)); - _this9.state = _this9.props.data; - _this9.handleCrateModeChange = _this9.handleCrateModeChange.bind(_assertThisInitialized(_this9)); - _this9.handleOnDragEnd = _this9.handleOnDragEnd.bind(_assertThisInitialized(_this9)); - _this9.handleDeleteItem = _this9.handleDeleteItem.bind(_assertThisInitialized(_this9)); - _this9.handleDeleteAllItems = _this9.handleDeleteAllItems.bind(_assertThisInitialized(_this9)); - _this9.handleMouseEnterItem = _this9.handleMouseEnterItem.bind(_assertThisInitialized(_this9)); - _this9.handleMouseLeaveItem = _this9.handleMouseLeaveItem.bind(_assertThisInitialized(_this9)); - _this9.handleClickAddItem = _this9.handleClickAddItem.bind(_assertThisInitialized(_this9)); - _this9.checkAlerts = _this9.checkAlerts.bind(_assertThisInitialized(_this9)); - _this9.handleToggleItemProgress = _this9.handleToggleItemProgress.bind(_assertThisInitialized(_this9)); - _this9.handleToggleItemWarning = _this9.handleToggleItemWarning.bind(_assertThisInitialized(_this9)); - _this9.handleClickSelectItem = _this9.handleClickSelectItem.bind(_assertThisInitialized(_this9)); - _this9.handleClickSubmit = _this9.handleClickSubmit.bind(_assertThisInitialized(_this9)); - _this9.handleToggleOverlayRemove = _this9.handleToggleOverlayRemove.bind(_assertThisInitialized(_this9)); - _this9.handleClickToggleMobileSideMenu = _this9.handleClickToggleMobileSideMenu.bind(_assertThisInitialized(_this9)); - _this9.timer = null; - return _this9; + _this10 = _possibleConstructorReturn(this, _getPrototypeOf(Shop).call(this, props)); + _this10.state = _this10.props.data; + _this10.handleCrateModeChange = _this10.handleCrateModeChange.bind(_assertThisInitialized(_this10)); + _this10.handleOnDragEnd = _this10.handleOnDragEnd.bind(_assertThisInitialized(_this10)); + _this10.handleDeleteItem = _this10.handleDeleteItem.bind(_assertThisInitialized(_this10)); + _this10.handleDeleteAllItems = _this10.handleDeleteAllItems.bind(_assertThisInitialized(_this10)); + _this10.handleMouseEnterItem = _this10.handleMouseEnterItem.bind(_assertThisInitialized(_this10)); + _this10.handleMouseLeaveItem = _this10.handleMouseLeaveItem.bind(_assertThisInitialized(_this10)); + _this10.handleClickAddItem = _this10.handleClickAddItem.bind(_assertThisInitialized(_this10)); + _this10.checkAlerts = _this10.checkAlerts.bind(_assertThisInitialized(_this10)); + _this10.handleToggleItemProgress = _this10.handleToggleItemProgress.bind(_assertThisInitialized(_this10)); + _this10.handleToggleItemWarning = _this10.handleToggleItemWarning.bind(_assertThisInitialized(_this10)); + _this10.handleClickSelectItem = _this10.handleClickSelectItem.bind(_assertThisInitialized(_this10)); + _this10.handleClickSubmit = _this10.handleClickSubmit.bind(_assertThisInitialized(_this10)); + _this10.handleToggleOverlayRemove = _this10.handleToggleOverlayRemove.bind(_assertThisInitialized(_this10)); + _this10.handleClickToggleMobileSideMenu = _this10.handleClickToggleMobileSideMenu.bind(_assertThisInitialized(_this10)); + _this10.handleClickCloseRFQFeedback = _this10.handleClickCloseRFQFeedback.bind(_assertThisInitialized(_this10)); + _this10.handleClickShowOrder = _this10.handleClickShowOrder.bind(_assertThisInitialized(_this10)); + _this10.handleClickOpenImport = _this10.handleClickOpenImport.bind(_assertThisInitialized(_this10)); + _this10.handleLoadCustomConf = _this10.handleLoadCustomConf.bind(_assertThisInitialized(_this10)); + _this10.timer = null; + return _this10; } _createClass(Shop, [{ @@ -1284,7 +1637,7 @@ function (_React$PureComponent12) { }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { - var _this10 = this; + var _this11 = this; /** * We check alerts (reminder + warning) only when items inside crate or @@ -1300,7 +1653,7 @@ function (_React$PureComponent12) { if (this.state.newCardJustAdded) { this.timer = setTimeout(function () { - _this10.setState({ + _this11.setState({ newCardJustAdded: false }); }, 2000); @@ -1444,8 +1797,8 @@ function (_React$PureComponent12) { })); } }, { - key: "handleClickSubmit", - value: function handleClickSubmit(note) { + key: "handleClickShowOrder", + value: function handleClickShowOrder() { var crate = { items: [], type: this.state.currentMode @@ -1459,15 +1812,111 @@ function (_React$PureComponent12) { }); } + this.setState({ + isProcessing: false, + shouldShowRFQFeedback: true, + RFQBodyType: 'show', + RFQBodyOrder: JSON.stringify(crate) + }); + } + }, { + key: "handleClickOpenImport", + value: function handleClickOpenImport() { + this.setState({ + isProcessing: false, + shouldShowRFQFeedback: true, + RFQBodyType: 'import' + }); + } + }, { + key: "handleLoadCustomConf", + value: function handleLoadCustomConf(customconf) { + if (!customconf) { + return; + } + + var items = this.props.data.items; + var self = this; + var new_items = []; + this.setState(_objectSpread({}, this.state, { + columns: _objectSpread({}, this.state.columns, { + cart: _objectSpread({}, this.state.columns.cart, { + items: [] + }) + }) + }), function () { + customconf.items.map(function (item) { + Object.keys(items).map(function (key) { + if (item.pn && item.pn === items[key].name_number) { + new_items.push(Object.assign(_objectSpread({}, items[key]), { + id: uuidv4() + })); + } + }); + return item; + }); + this.setState(_objectSpread({}, this.state, { + columns: _objectSpread({}, this.state.columns, { + cart: _objectSpread({}, this.state.columns.cart, { + items: new_items + }) + }), + currentMode: customconf.type + })); + }); + } + }, { + key: "handleClickSubmit", + value: function handleClickSubmit(note, email) { + var _this12 = this; + + var crate = { + items: [], + type: this.state.currentMode + }; + var clonedCart = Array.from(this.state.columns.cart.items); + + for (var i in clonedCart) { + var item = clonedCart[i]; + crate.items.push({ + 'pn': item.name_number + }); + } + + var data = this.props.data; var a = document.createElement('a'); var num = new Date().getTime(); var subject = "[Order hardware] - Request Quote"; - var body = "Hello!\n\nI would like to request a quotation for my below configuration:\n\n".concat(JSON.stringify(crate), "\n\n(Please do not edit the machine-readable representation above)\n\n"); + var body = "Hello!

I would like to request a quotation for my below configuration:

".concat(JSON.stringify(crate), "

(Please do not edit the machine-readable representation above)

"); if (note) { - body = "".concat(body, "\n\nAdditional note:\n\n").concat(note ? note.trim() : ''); + body = "".concat(body, "

Additional note:

").concat(note ? note.trim() : ''); } + this.setState({ + isProcessing: true + }); + axios.post(data.API_RFQ, { + email: email, + body: body, + headers: { + 'X-MLABS-OH': 'rlebcleu' + } + }).then(function (response) { + _this12.setState({ + isProcessing: false, + shouldShowRFQFeedback: true, + RFQBodyType: 'email', + isProcessingComplete: true + }); + })["catch"](function (err) { + _this12.setState({ + isProcessing: false + }, function () { + alert("We cannot receive your request. Try using the export by coping the configuration and send it to us at sales[at]m-labs.hk"); + }); + }); + return; document.body.appendChild(a); a.style = 'display: none'; a.href = "mailto:sales@m-labs.hk?subject=".concat(subject, "&body=").concat(encodeURIComponent(body)); @@ -1523,16 +1972,23 @@ function (_React$PureComponent12) { mobileSideMenuShouldOpen: !this.state.mobileSideMenuShouldOpen })); } + }, { + key: "handleClickCloseRFQFeedback", + value: function handleClickCloseRFQFeedback() { + this.setState({ + shouldShowRFQFeedback: false + }); + } }, { key: "checkAlerts", value: function checkAlerts(prevItems, newItems) { - var _this11 = this; + var _this13 = this; console.log('--- START CHECKING CRATE WARNING ---'); - var _this$state = this.state, - currentMode = _this$state.currentMode, - crateModeSlots = _this$state.crateModeSlots, - crateRules = _this$state.crateRules; + var _this$state2 = this.state, + currentMode = _this$state2.currentMode, + crateModeSlots = _this$state2.crateModeSlots, + crateRules = _this$state2.crateRules; var itemsCloned = Array.from(newItems); var itemsData = {}; var rules = {}; // check number of slot in crate @@ -1704,7 +2160,7 @@ function (_React$PureComponent12) { if (itemsCloned.find(function (elem) { return elem.type === _type; })) { - rules[_this11.state.items[_type].rules.connectors.type] = _objectSpread({}, _this11.state.items[_type].rules.connectors); + rules[_this13.state.items[_type].rules.connectors.type] = _objectSpread({}, _this13.state.items[_type].rules.connectors); } return _type; @@ -1846,26 +2302,36 @@ function (_React$PureComponent12) { }, { key: "render", value: function render() { - var _this$state2 = this.state, - currency = _this$state2.currency, - currentItemHovered = _this$state2.currentItemHovered, - currentMode = _this$state2.currentMode, - crateModeSlots = _this$state2.crateModeSlots, - crateModeItems = _this$state2.crateModeItems, - items = _this$state2.items, - columns = _this$state2.columns, - rules = _this$state2.rules, - mobileSideMenuShouldOpen = _this$state2.mobileSideMenuShouldOpen, - newCardJustAdded = _this$state2.newCardJustAdded; + var _this$state3 = this.state, + currency = _this$state3.currency, + currentItemHovered = _this$state3.currentItemHovered, + currentMode = _this$state3.currentMode, + crateModeSlots = _this$state3.crateModeSlots, + crateModeItems = _this$state3.crateModeItems, + items = _this$state3.items, + columns = _this$state3.columns, + rules = _this$state3.rules, + mobileSideMenuShouldOpen = _this$state3.mobileSideMenuShouldOpen, + newCardJustAdded = _this$state3.newCardJustAdded, + isProcessing = _this$state3.isProcessing, + shouldShowRFQFeedback = _this$state3.shouldShowRFQFeedback, + RFQBodyType = _this$state3.RFQBodyType, + RFQBodyOrder = _this$state3.RFQBodyOrder, + isProcessingComplete = _this$state3.isProcessingComplete; var isMobile = window.deviceIsMobile(); return React.createElement(DragDropContext, { onDragEnd: this.handleOnDragEnd }, React.createElement(Layout, { + showRFQFeedback: shouldShowRFQFeedback, + RFQBodyType: RFQBodyType, + RFQBodyOrder: RFQBodyOrder, className: "shop", mobileSideMenuShouldOpen: mobileSideMenuShouldOpen, isMobile: isMobile, newCardJustAdded: newCardJustAdded, onClickToggleMobileSideMenu: this.handleClickToggleMobileSideMenu, + onClickCloseRFQFeedback: this.handleClickCloseRFQFeedback, + onClickLoadCustomConf: this.handleLoadCustomConf, aside: React.createElement(Backlog, { currency: currency, items: items, @@ -1876,6 +2342,7 @@ function (_React$PureComponent12) { }), main: React.createElement(OrderPanel, { onClickToggleMobileSideMenu: this.handleClickToggleMobileSideMenu, + onClickOpenImport: this.handleClickOpenImport, isMobile: isMobile, title: "Order hardware", description: " Drag and drop the cards you want into the crate below to see how the combination would look like. If you have any issues with this ordering system, or if you need other configurations, email us directly anytime at sales@m-****.hk. The price is estimated and must be confirmed by a quote.", @@ -1912,7 +2379,11 @@ function (_React$PureComponent12) { onClickSelectItem: this.handleClickSelectItem }), form: React.createElement(OrderForm, { - onClickSubmit: this.handleClickSubmit + isProcessingComplete: isProcessingComplete, + processingComplete: this.handleProcessingComplete, + isProcessing: isProcessing, + onClickSubmit: this.handleClickSubmit, + onClickShow: this.handleClickShowOrder }) }) }));