UNPKG

@shopgate/engage

Version:
28 lines • 10.1 kB
function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}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,{Fragment,useState,useMemo,useEffect,useCallback}from'react';import classnames from'classnames';import moment from'moment';import PropTypes from'prop-types';import{connect}from'react-redux';import{css}from'glamor';import groupBy from'lodash/groupBy';import{SheetDrawer,Button}from'@shopgate/engage/components';import{i18n}from'@shopgate/engage/core';import{getActiveFulfillmentSlot}from'@shopgate/engage/cart/cart.selectors';import{makeGetFulfillmentSlotsForLocation,getPreferredLocation}from"../../selectors";import fetchFulfillmentSlots from"../../actions/fetchFulfillmentSlots";/** * Map state to props. * @returns {Function} */var makeMapStateToProps=function makeMapStateToProps(){var getFulfillmentSlotsForLocation=makeGetFulfillmentSlotsForLocation(function(state){var _getPreferredLocation;return((_getPreferredLocation=getPreferredLocation(state))===null||_getPreferredLocation===void 0?void 0:_getPreferredLocation.code)||null;});return function(state){var _getPreferredLocation2;return{fulfillmentSlot:getActiveFulfillmentSlot(state),locationCode:(_getPreferredLocation2=getPreferredLocation(state))===null||_getPreferredLocation2===void 0?void 0:_getPreferredLocation2.code,fulfillmentSlots:getFulfillmentSlotsForLocation(state)};};};/** * Map dispatch to props. * @param {Function} dispatch Dispatch * @returns {Object} */var mapDispatchToProps=function mapDispatchToProps(dispatch){return{fetch:function fetch(locationCode){return dispatch(fetchFulfillmentSlots(locationCode));}};};var styles={root:css({position:'relative',display:'flex',flexDirection:'column',padding:16,paddingBottom:0}).toString(),title:css({fontSize:24,fontWeight:'500',marginBottom:8}).toString(),subtitle:css({fontSize:20,fontWeight:'500',marginBottom:8,marginTop:16}).toString(),row:css({display:'flex',flexDirection:'row',flexWrap:'wrap',marginLeft:-8,marginRight:-8}).toString(),button:css({position:'relative',cursor:'pointer',display:'flex',margin:8,justifyContent:'center',alignItems:'center',border:'1px solid var(--color-secondary)',borderRadius:4,background:'#fff',transition:'background, color 500ms',outline:'none'}).toString(),buttonActive:css({color:'#fff',background:'var(--color-secondary)'}).toString(),buttonDate:css({width:124,height:70,lineHeight:1.3}).toString(),buttonLabel:css({fontSize:20,textAlign:'center'}).toString(),buttonLabelSlot:css({padding:2,fontSize:16,textAlign:'center'}).toString(),buttonDisabled:css({cursor:'blocked',pointerEvents:'none',border:'1px solid #444'}).toString(),buttonStrikethrough:css({position:'absolute',background:'#444',left:0,right:0,height:2,transform:'rotate(-5deg)'}).toString(),buttonScheduleContainer:css({position:'sticky',bottom:'calc(-1 * env(safe-area-inset-bottom))',margin:-16,marginTop:8,background:'#fff',padding:16,paddingBottom:24}).toString(),buttonSchedule:css({'&&':{width:'100%'}}).toString()};/** * Get Month day time. * @param {string} time Time * @return {string} */var getMonthDay=function getMonthDay(time){var momentTime=moment(time,'YYYY-MM-DD');return momentTime.format('L').replace(new RegExp("[^.]?".concat(momentTime.format('YYYY'),".?")),'');};/** * Get Range for a time. * @param {string} from From * @param {string} to To * @return {string} */var getRange=function getRange(from,to){var _from$split$map=from.split(':').map(function(x){return parseInt(x,10);}),_from$split$map2=_slicedToArray(_from$split$map,2),fromHours=_from$split$map2[0],fromMinutes=_from$split$map2[1];var fromMoment=moment().set({hours:fromHours,minutes:fromMinutes});var _to$split$map=to.split(':').map(function(x){return parseInt(x,10);}),_to$split$map2=_slicedToArray(_to$split$map,2),toHours=_to$split$map2[0],toMinutes=_to$split$map2[1];var toMoment=moment().set({hours:toHours,minutes:toMinutes});return"".concat(fromMoment.format('LT')," - ").concat(toMoment.format('LT'));};/** Ranges for different times */var MORNING_RANGE=[0,11];var AFTERNOON_RANGE=[12,17];var EVENING_RANGE=[18,23];var RANGES={morning:MORNING_RANGE,afternoon:AFTERNOON_RANGE,evening:EVENING_RANGE};/** * @param {Object} props Props. * @returns {JSX} */var FulfillmentSlotSheet=function FulfillmentSlotSheet(_ref){var isOpen=_ref.isOpen,onClose=_ref.onClose,onChange=_ref.onChange,fulfillmentSlots=_ref.fulfillmentSlots,locationCode=_ref.locationCode,fetch=_ref.fetch,allowClose=_ref.allowClose,fulfillmentSlot=_ref.fulfillmentSlot;// Group by date. var groupedSlots=useMemo(function(){return groupBy(fulfillmentSlots,'date');},[fulfillmentSlots]);// Load slots when opening. useEffect(function(){if(!isOpen){return;}fetch({locationCode:locationCode});},[fetch,isOpen,locationCode]);// Handle active selected date. var _useState=useState(null),_useState2=_slicedToArray(_useState,2),selectedDate=_useState2[0],setSelectedDate=_useState2[1];useEffect(function(){if(!Object.keys(groupedSlots).length){return;}// Don't change if selected date is still available if(groupedSlots[selectedDate]){return;}setSelectedDate(Object.keys(groupedSlots)[0]);/* eslint-disable react-hooks/exhaustive-deps */},[groupedSlots]);/* eslint-enable react-hooks/exhaustive-deps */ // Handle groups of time slots var _useState3=useState(null),_useState4=_slicedToArray(_useState3,2),selectedSlot=_useState4[0],setSelectedSlot=_useState4[1];var _useState5=useState(null),_useState6=_slicedToArray(_useState5,2),slotGroups=_useState6[0],setSlotGroups=_useState6[1];useEffect(function(){if(!groupedSlots||!groupedSlots[selectedDate]){setSlotGroups(null);return;}var slotGroupsNew=Object.keys(RANGES).map(function(rangeName){var _RANGES$rangeName=_slicedToArray(RANGES[rangeName],2),start=_RANGES$rangeName[0],end=_RANGES$rangeName[1];return{name:rangeName,slots:groupedSlots[selectedDate].filter(function(slot){var _slot$from$split$map=slot.from.split(':').map(function(x){return parseInt(x,10);}),_slot$from$split$map2=_slicedToArray(_slot$from$split$map,1),startHour=_slot$from$split$map2[0];return startHour>=start&&startHour<=end;})};}).filter(function(group){return group.slots.length>0;});setSlotGroups(slotGroupsNew);},[selectedDate,groupedSlots]);useEffect(function(){var _groupedSlots$selecte,_groupedSlots$selecte2;if(!selectedDate||!groupedSlots||!groupedSlots[selectedDate]){setSelectedSlot(null);return;}// Only switch if not found. if(groupedSlots[selectedDate].find(function(slot){return slot.id===selectedSlot;})){return;}// Select first active slot. setSelectedSlot(((_groupedSlots$selecte=groupedSlots[selectedDate])===null||_groupedSlots$selecte===void 0?void 0:(_groupedSlots$selecte2=_groupedSlots$selecte.find(function(slot){return slot.status==='active';}))===null||_groupedSlots$selecte2===void 0?void 0:_groupedSlots$selecte2.id)||null);/* eslint-disable react-hooks/exhaustive-deps */},[selectedDate]);/* eslint-enable react-hooks/exhaustive-deps */ // When opening the selected values are set to active selected content. useEffect(function(){if(!isOpen||!fulfillmentSlot||!fulfillmentSlot.date){return;}setSelectedDate(fulfillmentSlot.date);setSelectedSlot(fulfillmentSlot.id);},[fulfillmentSlot,isOpen]);var handleChange=useCallback(function(){onChange(fulfillmentSlots.find(function(slot){return slot.id===selectedSlot;}));},[fulfillmentSlots,onChange,selectedSlot]);return React.createElement(SheetDrawer,{isOpen:isOpen,title:i18n.text('locations.your_current_timeslot.dialog.title'),onDidClose:onClose,allowClose:allowClose},React.createElement("div",{className:styles.root},React.createElement("span",{className:styles.title},i18n.text('locations.your_current_timeslot.dialog.date')),React.createElement("div",{className:styles.row},Object.keys(groupedSlots).map(function(date){return React.createElement("button",{type:"button",key:date,className:classnames(styles.button,styles.buttonDate,_defineProperty({},styles.buttonActive,selectedDate===date)),onClick:function onClick(){return setSelectedDate(date);}},React.createElement("span",{className:styles.buttonLabel},moment(date,'YYYY-MM-DD').format('dddd'),' ',getMonthDay(date)));})),slotGroups&&slotGroups.map(function(group){return React.createElement(Fragment,{key:group.name},React.createElement("span",{className:styles.subtitle},i18n.text("locations.your_current_timeslot.dialog.".concat(group.name))),React.createElement("div",{className:styles.row},group.slots.map(function(slot){return React.createElement("button",{type:"button",key:"".concat(slot.from,"-").concat(slot.to),onClick:function onClick(){return setSelectedSlot(slot.id);},className:classnames(styles.button,_defineProperty(_defineProperty({},styles.buttonDisabled,slot.status!=='active'),styles.buttonActive,slot.id===selectedSlot))},React.createElement("span",{className:styles.buttonLabelSlot},getRange(slot.from,slot.to)),slot.status!=='active'?React.createElement("div",{className:styles.buttonStrikethrough}):null);})));}),React.createElement("div",{className:styles.buttonScheduleContainer},React.createElement(Button,{className:styles.buttonSchedule,type:"secondary",onClick:handleChange,disabled:!selectedDate||!selectedSlot},i18n.text('locations.your_current_timeslot.dialog.schedule')))));};FulfillmentSlotSheet.defaultProps={isOpen:false,locationCode:null,fulfillmentSlots:[],fulfillmentSlot:null,allowClose:true};export default connect(makeMapStateToProps,mapDispatchToProps)(FulfillmentSlotSheet);