UNPKG

@shopgate/engage

Version:
49 lines • 17.6 kB
import _regeneratorRuntime from"@babel/runtime/regenerator";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 asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value;}catch(error){reject(error);return;}if(info.done){resolve(value);}else{Promise.resolve(value).then(_next,_throw);}}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value);}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err);}_next(undefined);});};}function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_nonIterableRest();}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance");}function _iterableToArrayLimit(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break;}}catch(err){_d=true;_e=err;}finally{try{if(!_n&&_i["return"]!=null)_i["return"]();}finally{if(_d)throw _e;}}return _arr;}function _arrayWithHoles(arr){if(Array.isArray(arr))return arr;}import React,{useState,useMemo,useRef,useEffect,useCallback}from'react';import{logger,i18n,UIEvents}from"../../core";import{withCurrentProduct}from"../../core/hocs/withCurrentProduct";import{FulfillmentContext}from"../locations.context";import{FulfillmentPathSelector}from"../components/FulfillmentPathSelector";import{STAGE_SELECT_STORE,STAGE_RESERVE_FORM,STAGE_RESPONSE_SUCCESS,STAGE_RESPONSE_ERROR,STAGE_FULFILLMENT_METHOD,QUICK_RESERVE,MULTI_LINE_RESERVE,DIRECT_SHIP,ROPIS,BOPIS}from"../constants";import connect from"./FulfillmentProvider.connector";export var EVENT_SET_OPEN='FulfillmentProvider.setOpen';var callback;/** * Provides the fulfillment context. * @param {Object} props The component props. * @returns {JSX} */function FulfillmentProvider(props){var children=props.children,locations=props.locations,propsBaseProduct=props.baseProduct,propsProduct=props.product,productLocation=props.location,inventory=props.inventory,userInput=props.userInput,defaultFulfillmentMethod=props.fulfillmentMethod,defaultFulfillmentPath=props.fulfillmentPath,fulfillmentPaths=props.fulfillmentPaths,fulfillmentMethods=props.fulfillmentMethods,enabledFulfillmentMethods=props.enabledFulfillmentMethods,shopSettings=props.shopSettings,selectLocation=props.selectLocation,submitReservation=props.submitReservation,storeFormInput=props.storeFormInput,updateProductsInCart=props.updateProductsInCart,isFetching=props.isFetching,_props$noInventory=props.noInventory,noInventory=_props$noInventory===void 0?false:_props$noInventory,_props$open=props.open,open=_props$open===void 0?false:_props$open,_props$noLocationSele=props.noLocationSelection,noLocationSelection=_props$noLocationSele===void 0?false:_props$noLocationSele,_props$isStoreFinder=props.isStoreFinder,isStoreFinder=_props$isStoreFinder===void 0?false:_props$isStoreFinder,_props$isCart=props.isCart,isCart=_props$isCart===void 0?false:_props$isCart,defaultIsInitialized=props.isInitialized,updatePreferredLocation=props.updatePreferredLocation,_props$restrictMultiL=props.restrictMultiLocationOrders,restrictMultiLocationOrders=_props$restrictMultiL===void 0?false:_props$restrictMultiL,_props$cartProducts=props.cartProducts,cartProducts=_props$cartProducts===void 0?[]:_props$cartProducts,showModal=props.showModal,_props$fulfillmentSch=props.fulfillmentSchedulingEnabled,fulfillmentSchedulingEnabled=_props$fulfillmentSch===void 0?null:_props$fulfillmentSch,_props$activeFulfillm=props.activeFulfillmentSlot,activeFulfillmentSlot=_props$activeFulfillm===void 0?null:_props$activeFulfillm,_props$activeFulfillm2=props.activeFulfillmentSlotLocationCode,activeFulfillmentSlotLocationCode=_props$activeFulfillm2===void 0?null:_props$activeFulfillm2;var _useState=useState(defaultFulfillmentPath||null),_useState2=_slicedToArray(_useState,2),fulfillmentPath=_useState2[0],setFulfillmentPath=_useState2[1];var _useState3=useState(props.changeOnly),_useState4=_slicedToArray(_useState3,2),changeOnly=_useState4[0],setChangeOnly=_useState4[1];var _useState5=useState(open),_useState6=_slicedToArray(_useState5,2),isOpen=_useState6[0],setIsOpen=_useState6[1];var _useState7=useState(props.stage||null),_useState8=_slicedToArray(_useState7,2),stage=_useState8[0],setStage=_useState8[1];var _useState9=useState(null),_useState10=_slicedToArray(_useState9,2),fulfillmentMethod=_useState10[0],setFulfillmentMethod=_useState10[1];var _useState11=useState(null),_useState12=_slicedToArray(_useState11,2),orderNumbers=_useState12[0],setOrderNumbers=_useState12[1];var _useState13=useState(null),_useState14=_slicedToArray(_useState13,2),errors=_useState14[0],setErrors=_useState14[1];var _useState15=useState(propsProduct),_useState16=_slicedToArray(_useState15,2),product=_useState16[0],setProduct=_useState16[1];var _useState17=useState(false),_useState18=_slicedToArray(_useState17,2),isChangeFulfillment=_useState18[0],setIsChangeFulfillment=_useState18[1];var _useState19=useState(null),_useState20=_slicedToArray(_useState19,2),cartItem=_useState20[0],setCartItem=_useState20[1];var _useState21=useState(productLocation),_useState22=_slicedToArray(_useState21,2),storeFinderLocation=_useState22[0],setStoreFinderLocation=_useState22[1];var _useState23=useState(!isFetching),_useState24=_slicedToArray(_useState23,2),isLoading=_useState24[0],setIsLoading=_useState24[1];var isInitialized=useRef(defaultIsInitialized);useEffect(function(){if(defaultFulfillmentMethod){setFulfillmentMethod(defaultFulfillmentMethod);}},[defaultFulfillmentMethod]);var title=useMemo(function(){if(props.title!==null){return i18n.text(props.title);}switch(stage){default:case STAGE_SELECT_STORE:return i18n.text('locations.headline');case STAGE_RESERVE_FORM:return i18n.text('locations.place_reservation');case STAGE_RESPONSE_SUCCESS:return i18n.text('locations.success_heading');case STAGE_RESPONSE_ERROR:return i18n.text('locations.error_heading');case STAGE_FULFILLMENT_METHOD:return i18n.text('locations.change_fulfillment_method');}},[props.title,stage]);/** Effects for updating a state based on new props */useEffect(function(){return setIsOpen(open);},[open]);useEffect(function(){return setProduct(propsProduct);},[propsProduct]);useEffect(function(){if(updatePreferredLocation&&productLocation&&!isInitialized.current){isInitialized.current=true;selectLocation(productLocation);}},[productLocation,selectLocation,updatePreferredLocation]);useEffect(function(){setIsLoading(isFetching);},[isFetching]);/** * Checks whether the given stage is currently set. * @param {string} inputStage The stage to check for. * @returns {boolean} */function isStage(inputStage){return inputStage===stage;}/** * Handles opening of the sheet. * @param {Object} params The sheet open parameters. */function handleOpen(params){setIsOpen(true);setStage(function(prevState){return params.stage||prevState;});setChangeOnly(function(prevState){return params.changeOnly||prevState;});setFulfillmentPath(function(prevState){return params.fulfillmentPath||prevState;});callback=params.callback||null;}/** * Is called when the sheet closed. * @param {Object} [location=null] The selected location. * @param {string} [productId=null] The product ID. */function handleClose(){var location=arguments.length>0&&arguments[0]!==undefined?arguments[0]:null;var productId=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;var orderSuccess=true;if(isStage(STAGE_RESPONSE_ERROR)){orderSuccess=errors===null;}if(isStage(STAGE_RESERVE_FORM)){orderSuccess=null;}if(props.onClose){props.onClose(location,productId,orderSuccess);}else if(callback){callback(location,productId,orderSuccess);callback=null;}setIsOpen(false);setStage(null);setOrderNumbers(null);setErrors(null);setIsChangeFulfillment(false);setFulfillmentMethod(null);}useEffect(function(){UIEvents.addListener(EVENT_SET_OPEN,handleOpen);return function(){UIEvents.removeListener(EVENT_SET_OPEN,handleOpen);};},[]);/** * Handles the sending of the reservation. * @param {Object} values The form values. */function sendReservation(_x){return _sendReservation.apply(this,arguments);}/** * @param {Object} location The selected location. * @returns {boolean} */function _sendReservation(){_sendReservation=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(values){var response;return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:_context2.prev=0;_context2.next=3;return submitReservation(values,product);case 3:response=_context2.sent;if(response.errors&&response.errors.length>0){setStage(STAGE_RESPONSE_ERROR);setOrderNumbers(null);setErrors(response.errors);}setStage(STAGE_RESPONSE_SUCCESS);setOrderNumbers(response.orderNumbers);setErrors(null);_context2.next=16;break;case 10:_context2.prev=10;_context2.t0=_context2["catch"](0);logger.error(_context2.t0);setStage(STAGE_RESPONSE_ERROR);setOrderNumbers(null);setErrors([_context2.t0.message]);case 16:// Store the user's form in the user data. storeFormInput(values);case 17:case"end":return _context2.stop();}},_callee2,null,[[0,10]]);}));return _sendReservation.apply(this,arguments);}var confirmSelection=/*#__PURE__*/function(){var _ref=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(location){var code,name,ropeCartProducts,cartHasDifferentCodes,confirmed,updateData;return _regeneratorRuntime.wrap(function _callee$(_context){while(1)switch(_context.prev=_context.next){case 0:code=location.code,name=location.name;ropeCartProducts=cartProducts.filter(function(cartProduct){var _cartProduct$fulfillm;return[ROPIS,BOPIS].includes(cartProduct===null||cartProduct===void 0?void 0:(_cartProduct$fulfillm=cartProduct.fulfillment)===null||_cartProduct$fulfillm===void 0?void 0:_cartProduct$fulfillm.method);});if(!(!restrictMultiLocationOrders||ropeCartProducts.length===0)){_context.next=4;break;}return _context.abrupt("return",true);case 4:if(!(isCart&&ropeCartProducts.length===1)){_context.next=6;break;}return _context.abrupt("return",true);case 6:cartHasDifferentCodes=!!ropeCartProducts.map(function(_ref2){var _fulfillment$location;var fulfillment=_ref2.fulfillment;return fulfillment===null||fulfillment===void 0?void 0:(_fulfillment$location=fulfillment.location)===null||_fulfillment$location===void 0?void 0:_fulfillment$location.code;}).filter(Boolean).filter(function(cartProductCode){return cartProductCode!==code;}).length;if(!(ropeCartProducts.length>=1&&!cartHasDifferentCodes)){_context.next=9;break;}return _context.abrupt("return",true);case 9:_context.next=11;return showModal({title:'locations.multi_location_modal.title',message:'locations.multi_location_modal.message',confirm:'locations.multi_location_modal.change_store',dismiss:'common.cancel'});case 11:confirmed=_context.sent;if(!(confirmed&&ropeCartProducts.length)){_context.next=18;break;}updateData=ropeCartProducts.map(function(_ref3){var cartItemId=_ref3.id,fulfillment=_ref3.fulfillment;return{cartItemId:cartItemId,fulfillment:{method:fulfillment===null||fulfillment===void 0?void 0:fulfillment.method,location:{code:code,name:name||''}}};});setIsLoading(true);_context.next=17;return updateProductsInCart(updateData);case 17:setIsLoading(false);case 18:return _context.abrupt("return",confirmed);case 19:case"end":return _context.stop();}},_callee);}));return function confirmSelection(_x2){return _ref.apply(this,arguments);};}();/** * Handles multiline reservation. * @param {Object} location The selected location. */function handleMultilineReservation(location){if(product===null||location.code===null){return;}var fulfillment=_extends({method:fulfillmentMethod,location:{code:location.code,name:location.name||''}},fulfillmentSchedulingEnabled&&activeFulfillmentSlotLocationCode===location.code&&(activeFulfillmentSlot===null||activeFulfillmentSlot===void 0?void 0:activeFulfillmentSlot.id)?{slotId:activeFulfillmentSlot.id}:null);if(isChangeFulfillment&&cartItem){updateProductsInCart([{quantity:cartItem.quantity,cartItemId:cartItem.id,fulfillment:fulfillment}]);}handleClose(location,product.id);}/** * Handles quick reservation. */function handleQuickReservation(){setStage(STAGE_RESERVE_FORM);}/** * Handles the selection of a store location from the sheet. * @param {Object} location The selected location. */function handleSelectLocation(_x3){return _handleSelectLocation.apply(this,arguments);}/** * @param {string} method The selected fulfillment method. * @param {Object} item The cart item to change. */function _handleSelectLocation(){_handleSelectLocation=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(location){var selectionConfirmed,handleReservationMethod;return _regeneratorRuntime.wrap(function _callee3$(_context3){while(1)switch(_context3.prev=_context3.next){case 0:if(!isLoading){_context3.next=2;break;}return _context3.abrupt("return");case 2:if(!updatePreferredLocation){_context3.next=7;break;}_context3.next=5;return confirmSelection(location);case 5:selectionConfirmed=_context3.sent;if(selectionConfirmed){selectLocation({code:location.code,name:location.name});}case 7:if(!changeOnly){_context3.next=10;break;}if(selectionConfirmed){handleClose(location,product&&product.id);}return _context3.abrupt("return");case 10:/** * Select the reservation method strategy. * @param {string} method The reservation method. * @param {Object} storeLocation A store location */handleReservationMethod=function handleReservationMethod(method,storeLocation){if(!method){return;}if(method===QUICK_RESERVE){handleQuickReservation();}if(method===MULTI_LINE_RESERVE){handleMultilineReservation(storeLocation);}};// No fulfillment path selected yet. if(!(fulfillmentPath===null)){_context3.next=14;break;}if(fulfillmentPaths.length>1){FulfillmentPathSelector.open(function(method){if(!method){return;}handleReservationMethod(method,location);});}else if(fulfillmentPaths.length===1){handleReservationMethod(fulfillmentPaths[0],location);}return _context3.abrupt("return");case 14:if(!(fulfillmentPath===MULTI_LINE_RESERVE&&fulfillmentPaths.includes(MULTI_LINE_RESERVE))){_context3.next=17;break;}handleMultilineReservation(location);return _context3.abrupt("return");case 17:if(fulfillmentPath===QUICK_RESERVE){handleQuickReservation();}case 18:case"end":return _context3.stop();}},_callee3);}));return _handleSelectLocation.apply(this,arguments);}function handleChangeFulfillmentMethod(method,item){logger.assert(item.product.id===product.id,'Change fulfillment method is called with unexpected product id');setIsChangeFulfillment(true);setCartItem(item);if([ROPIS,BOPIS].includes(method)&&(item.fulfillment===null||item.fulfillment.method===DIRECT_SHIP)){/** * When the fulfillment method of the current cart item was DIRECT_SHIP before, and is * switched to a ROPE method, the customer needs to pick a store for the item. */setFulfillmentPath(MULTI_LINE_RESERVE);setStage(STAGE_SELECT_STORE);setFulfillmentMethod(method);setIsOpen(true);return;}if([DIRECT_SHIP,ROPIS,BOPIS].includes(method)){updateProductsInCart([{quantity:item.quantity,cartItemId:item.id,fulfillment:{method:method}}]);handleClose(null,item.product.id);}}var handleSelectStoreFinderLocation=useCallback(function(location){setStoreFinderLocation(location);},[]);var context={stage:stage,title:title,fulfillmentPath:fulfillmentPath,changeOnly:changeOnly,isStage:isStage,isOpen:isOpen,handleOpen:handleOpen,handleClose:handleClose,locations:locations,inventory:inventory,baseProduct:propsBaseProduct,product:product,location:productLocation,storeFinderLocation:storeFinderLocation,userInput:userInput,fulfillmentPaths:fulfillmentPaths,fulfillmentMethods:fulfillmentMethods,enabledFulfillmentMethods:enabledFulfillmentMethods,shopSettings:shopSettings,selectLocation:handleSelectLocation,selectStoreFinderLocation:handleSelectStoreFinderLocation,changeFulfillment:handleChangeFulfillmentMethod,sendReservation:sendReservation,orderNumbers:orderNumbers,errors:errors,noInventory:noInventory,noLocationSelection:noLocationSelection,isStoreFinder:isStoreFinder,isFetching:isFetching,isLoading:isLoading,setIsLoading:setIsLoading,meta:props.meta||undefined};return React.createElement(FulfillmentContext.Provider,{value:context},children);}FulfillmentProvider.defaultProps={open:false,changeOnly:false,updatePreferredLocation:true,fulfillmentMethods:null,title:null};var FulfillmentProviderWrapped=withCurrentProduct(connect(FulfillmentProvider));/** * Opens the sheet that is wrapped inside the provider. * @param {Object} params The opening parameters. * @property {Function} [params.callback] A callback function that's when the sheet closes. * @property {string} [params.stage] A specific stage to show. * @property {string} [params.fulfillmentPath] The fulfillment path that was chosen. * @property {boolean} [params.changeOnly=false] Whether only the location will be changed. */export function openSheet(params){UIEvents.emit(EVENT_SET_OPEN,params);}export default FulfillmentProviderWrapped;