@bonlineza/luxity-lib 2.35.8 → 2.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -66,7 +66,7 @@
66
66
  src: accountIcon,
67
67
  alt: "close-icon",
68
68
  className: "side-nav__menu-icon"
69
- }), "Account"))), /*#__PURE__*/React.createElement("div", {
69
+ }), "Account"))), onInterestClick && /*#__PURE__*/React.createElement("div", {
70
70
  className: "side-nav__menu-item"
71
71
  }, /*#__PURE__*/React.createElement("button", {
72
72
  type: "button",
@@ -189,11 +189,11 @@
189
189
  onClick: onMenuItemClick
190
190
  }, "All ", categoryTitle)), !!brandElements.length && brandElements.map(function (brand) {
191
191
  return /*#__PURE__*/React__default.createElement("div", {
192
- className: "dropdown__brand-element"
192
+ className: "dropdown__brand-element",
193
+ key: brand.name
193
194
  }, /*#__PURE__*/React__default.createElement(LinkComponent, {
194
195
  href: "".concat(productsUrl, "/").concat(categorySlug, "/").concat(brand === null || brand === void 0 ? void 0 : brand.slug),
195
196
  className: "dropdown__element",
196
- key: brand.name,
197
197
  onClick: onMenuItemClick
198
198
  }, brand === null || brand === void 0 ? void 0 : brand.name));
199
199
  }))), /*#__PURE__*/React__default.createElement("div", {
@@ -297,37 +297,6 @@
297
297
  }, contactNumber)));
298
298
  };
299
299
 
300
- var categories = {
301
- shoes: {
302
- name: 'Shoes',
303
- slug: 'shoes'
304
- },
305
- bags: {
306
- name: 'Bags',
307
- slug: 'bags'
308
- },
309
- clothing: {
310
- name: 'Clothing',
311
- slug: 'apparel'
312
- },
313
- watches: {
314
- name: 'Watches',
315
- slug: 'watches'
316
- },
317
- accessories: {
318
- name: 'Accessories',
319
- slug: 'accessories'
320
- }
321
- };
322
-
323
- var removeCategoryByName = function removeCategoryByName(categories, name) {
324
- var _categories$filter;
325
-
326
- return (_categories$filter = categories === null || categories === void 0 ? void 0 : categories.filter(function (category) {
327
- return category.name !== name;
328
- })) !== null && _categories$filter !== void 0 ? _categories$filter : [];
329
- };
330
-
331
300
  var SearchResults = function SearchResults(_ref) {
332
301
  var _searchResults$brands, _searchResults$produc, _searchResults$brands2, _searchResults$produc2, _initialSearchData$tr, _initialSearchData$la, _limitBrands, _limitBrands2, _initialSearchData$la2, _searchResults$produc3;
333
302
 
@@ -697,6 +666,7 @@
697
666
  var endpoint = _ref.endpoint,
698
667
  onProductIdsReceived = _ref.onProductIdsReceived,
699
668
  currency = _ref.currency;
669
+ var currentSearchRequestToken = React.useRef(null);
700
670
  var debounce = React.useCallback(function (func, wait) {
701
671
  var timeout;
702
672
  return function executedFunction() {
@@ -727,49 +697,75 @@
727
697
  });
728
698
  });
729
699
  }, []);
730
- var performSearch = React.useCallback(function (nextValue, setSearchResults) {
731
- if (!nextValue || nextValue.trim() === '') {
700
+ var performSearch = React.useCallback(function (searchQuery, setSearchResults) {
701
+ if (!searchQuery || searchQuery.trim() === '') {
732
702
  setSearchResults({
733
703
  brands: [],
734
704
  products: [],
735
705
  luxity_product_ids: []
736
706
  });
737
707
  return;
738
- }
708
+ } // Cancel any ongoing search request to prevent race conditions
709
+
739
710
 
740
- axios.post(endpoint, searchProducts(nextValue, 3, currency)).then(function (response) {
741
- var searchResults = response.data.data.luxity_products_serach_results;
742
- setSearchResults(searchResults);
711
+ if (currentSearchRequestToken.current) {
712
+ currentSearchRequestToken.current.cancel();
713
+ } // Create a new token for this specific search request
743
714
 
744
- if (searchResults && searchResults.luxity_product_ids) {
745
- onProductIdsReceived(searchResults.luxity_product_ids);
715
+
716
+ var newSearchToken = axios.CancelToken.source();
717
+ currentSearchRequestToken.current = newSearchToken;
718
+ axios.post(endpoint, searchProducts(searchQuery, 3, currency), {
719
+ cancelToken: newSearchToken.token
720
+ }).then(function (response) {
721
+ if (currentSearchRequestToken.current === newSearchToken) {
722
+ var searchResults = response.data.data.luxity_products_serach_results;
723
+ setSearchResults(searchResults);
724
+
725
+ if (searchResults && searchResults.luxity_product_ids) {
726
+ onProductIdsReceived(searchResults.luxity_product_ids);
727
+ }
728
+
729
+ currentSearchRequestToken.current = null;
730
+ }
731
+ }).catch(function (error) {
732
+ if (!axios.isCancel(error)) {
733
+ setSearchResults({
734
+ brands: [],
735
+ products: [],
736
+ luxity_product_ids: []
737
+ });
738
+ currentSearchRequestToken.current = null;
746
739
  }
747
- }).catch(function () {
748
- setSearchResults({
749
- brands: [],
750
- products: [],
751
- luxity_product_ids: []
752
- });
753
740
  });
754
741
  }, [endpoint, currency, onProductIdsReceived]);
755
742
  var debouncedSearch = React.useMemo(function () {
756
- return debounce(function (nextValue, setSearchResults) {
757
- return performSearch(nextValue, setSearchResults);
743
+ return debounce(function (searchQuery, setSearchResults) {
744
+ return performSearch(searchQuery, setSearchResults);
758
745
  }, 500);
759
746
  }, [debounce, performSearch]);
760
747
  var createDebouncedSearch = React.useCallback(function (setSearchResults) {
761
- return function (nextValue) {
762
- return debouncedSearch(nextValue, setSearchResults);
748
+ return function (searchQuery) {
749
+ return debouncedSearch(searchQuery, setSearchResults);
763
750
  };
764
751
  }, [debouncedSearch]);
765
752
  var createImmediateSearch = React.useCallback(function (setSearchValue, setSearchResults, onSearchSubmit) {
766
- return function (value) {
753
+ return function (searchQuery) {
754
+ /*
755
+ * Cancel any pending search request when immediate search is performed
756
+ * Immediate search is when the user types a search query and presses enter
757
+ */
758
+ if (currentSearchRequestToken.current) {
759
+ currentSearchRequestToken.current.cancel();
760
+ currentSearchRequestToken.current = null;
761
+ }
762
+
767
763
  setSearchValue('');
768
764
  setSearchResults({
769
765
  brands: [],
770
766
  products: []
771
767
  });
772
- onSearchSubmit(value);
768
+ onSearchSubmit(searchQuery);
773
769
  };
774
770
  }, []);
775
771
  return {
@@ -819,13 +815,16 @@
819
815
  }, [setSearchValue, setIsSearchFocused, debouncedSearch, setSearchResults, setCachedResults]);
820
816
  };
821
817
  var useSearchInputFocus = function useSearchInputFocus(searchValue, setIsSearchFocused, cachedResults, setSearchResults) {
818
+ var handleSearchClick = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
822
819
  return React.useCallback(function () {
823
820
  setIsSearchFocused(true);
824
821
 
825
- if (searchValue.trim().length >= 3) {
822
+ if (typeof handleSearchClick === 'function') {
823
+ handleSearchClick();
824
+ } else if (searchValue.trim().length >= 3) {
826
825
  setSearchResults(cachedResults);
827
826
  }
828
- }, [searchValue, setIsSearchFocused, cachedResults, setSearchResults]);
827
+ }, [searchValue, setIsSearchFocused, cachedResults, setSearchResults, handleSearchClick]);
829
828
  };
830
829
  var useSearchInputKeyDown = function useSearchInputKeyDown(searchValue, immediateSearch, setIsSearchFocused) {
831
830
  var setSearchValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
@@ -845,6 +844,14 @@
845
844
  }, [searchValue, immediateSearch, setIsSearchFocused, setSearchValue]);
846
845
  };
847
846
 
847
+ var removeCategoryByName = function removeCategoryByName(categories, name) {
848
+ var _categories$filter;
849
+
850
+ return (_categories$filter = categories === null || categories === void 0 ? void 0 : categories.filter(function (category) {
851
+ return category.name.toLowerCase() !== name.toLowerCase();
852
+ })) !== null && _categories$filter !== void 0 ? _categories$filter : [];
853
+ };
854
+
848
855
  var LuxityDesktopHeader = function LuxityDesktopHeader(_ref) {
849
856
  var accountIcon = _ref.accountIcon,
850
857
  cartIcon = _ref.cartIcon,
@@ -852,12 +859,6 @@
852
859
  cartCount = _ref.cartCount,
853
860
  logoSrc = _ref.logoSrc,
854
861
  categoryElements = _ref.categoryElements,
855
- newBrandsImage = _ref.newBrandsImage,
856
- bagsImage = _ref.bagsImage,
857
- shoesImage = _ref.shoesImage,
858
- clothingImage = _ref.clothingImage,
859
- accessoriesImage = _ref.accessoriesImage,
860
- watchesImage = _ref.watchesImage,
861
862
  stores = _ref.stores,
862
863
  contactNumber = _ref.contactNumber,
863
864
  productsUrl = _ref.productsUrl,
@@ -871,9 +872,9 @@
871
872
  ourStoryLink = _ref.ourStoryLink,
872
873
  onLogoClick = _ref.onLogoClick,
873
874
  endpoint = _ref.endpoint,
874
- menuData = _ref.menuData,
875
875
  initialSearchData = _ref.initialSearchData,
876
876
  onSearchSubmit = _ref.onSearchSubmit,
877
+ onSearchClick = _ref.onSearchClick,
877
878
  onProductIdsReceived = _ref.onProductIdsReceived,
878
879
  currency = _ref.currency,
879
880
  currencySymbol = _ref.currencySymbol,
@@ -885,7 +886,8 @@
885
886
  name = _ref.name,
886
887
  isVip = _ref.isVip,
887
888
  shop = _ref.shop,
888
- app = _ref.app;
889
+ app = _ref.app,
890
+ categoryConfig = _ref.categoryConfig;
889
891
 
890
892
  var _useSearch = useSearch({
891
893
  endpoint: endpoint,
@@ -912,26 +914,17 @@
912
914
  setIsSearchFocused = _useState6[1];
913
915
 
914
916
  var _useState7 = React.useState({
915
- latestArrivals: [],
916
- bags: [],
917
- shoes: [],
918
- clothing: [],
919
- accessories: [],
920
- watches: [],
921
- accessoriesCategories: [],
922
- apparelStyles: []
923
- }),
924
- _useState8 = _slicedToArray(_useState7, 2),
925
- dropdownData = _useState8[0],
926
- setDropdownData = _useState8[1];
927
-
928
- var _useState9 = React.useState({
929
917
  trending_brands: [],
930
918
  latest_products: []
931
919
  }),
920
+ _useState8 = _slicedToArray(_useState7, 2),
921
+ initialSearchView = _useState8[0],
922
+ setInitialSearchView = _useState8[1];
923
+
924
+ var _useState9 = React.useState({}),
932
925
  _useState10 = _slicedToArray(_useState9, 2),
933
- initialSearchView = _useState10[0],
934
- setInitialSearchView = _useState10[1];
926
+ dropdownData = _useState10[0],
927
+ setDropdownData = _useState10[1];
935
928
 
936
929
  var _useState11 = React.useState(false),
937
930
  _useState12 = _slicedToArray(_useState11, 2),
@@ -962,7 +955,17 @@
962
955
  var immediateSearch = createImmediateSearch(setSearchValue, setSearchResults, onSearchSubmit);
963
956
  var handleChange = useSearchInputChange(setSearchValue, setIsSearchFocused, debouncedSearch, setSearchResults, setCachedResults);
964
957
  useSearchClickOutside(searchResultsRef, searchResults, setCachedResults, setIsSearchFocused, setSearchResults);
965
- var handleSearchFocus = useSearchInputFocus(searchValue, setIsSearchFocused, cachedResults, setSearchResults);
958
+
959
+ var handleSearchClick = function handleSearchClick() {
960
+ if (typeof onSearchClick === 'function') {
961
+ onSearchClick();
962
+ return;
963
+ }
964
+
965
+ handleSearchFocus();
966
+ };
967
+
968
+ var handleSearchFocus = useSearchInputFocus(searchValue, setIsSearchFocused, cachedResults, setSearchResults, onSearchClick);
966
969
  var handleKeyDown = useSearchInputKeyDown(searchValue, immediateSearch, setIsSearchFocused);
967
970
 
968
971
  function addCategoryToElements(elements, categoryName) {
@@ -975,29 +978,58 @@
975
978
 
976
979
  React.useMemo(function () {
977
980
  setLoading(true);
978
- axios.get("".concat(menuData)).then(function (_ref2) {
981
+ axios.get("".concat(categoryConfig.menuData)).then(function (_ref2) {
979
982
  var data = _ref2.data;
980
983
  setLoading(false);
981
- setDropdownData(function (prev) {
982
- return _objectSpread2(_objectSpread2({}, prev), {}, {
983
- latestArrivals: data.latest_arrivals,
984
- bags: data.bags,
985
- shoes: data.shoes,
986
- apparel: data.apparel,
987
- accessories: data.accessories,
988
- watches: data.watches,
989
- accessoriesCategories: data.accessories_categories,
990
- apparelStyles: data.apparel_styles
991
- });
992
- });
984
+ setDropdownData(data);
993
985
  }).catch(function () {
994
986
  return setHasError(true);
995
987
  });
996
- }, [menuData]);
988
+ }, [categoryConfig.menuData]);
997
989
  React.useMemo(function () {
990
+ if (!initialSearchData) {
991
+ return;
992
+ }
993
+
998
994
  fetchInitialSearchData(initialSearchData, setInitialSearchView);
999
995
  }, [initialSearchData, fetchInitialSearchData]);
1000
996
 
997
+ var renderDropdownLinks = function renderDropdownLinks() {
998
+ return categoryConfig.categories.map(function (category) {
999
+ var title = category.title,
1000
+ imageSrc = category.imageSrc,
1001
+ categorySlug = category.categorySlug,
1002
+ categoryName = category.categoryName,
1003
+ elementsKey = category.elementsKey,
1004
+ subCategoryElementsKey = category.subCategoryElementsKey,
1005
+ styleElementsKey = category.styleElementsKey;
1006
+ var categoryElementsProcessed = categoryElements;
1007
+
1008
+ if (subCategoryElementsKey && dropdownData[subCategoryElementsKey]) {
1009
+ // show subcategory elements
1010
+ categoryElementsProcessed = removeCategoryByName(dropdownData[subCategoryElementsKey], categoryName);
1011
+ } else if (styleElementsKey && dropdownData[styleElementsKey]) {
1012
+ categoryElementsProcessed = addCategoryToElements(dropdownData[styleElementsKey], categorySlug);
1013
+ } else {
1014
+ categoryElementsProcessed = addCategoryToElements(categoryElementsProcessed, categorySlug);
1015
+ }
1016
+
1017
+ return /*#__PURE__*/React__default.createElement(DropdownLink, {
1018
+ key: categorySlug,
1019
+ title: title,
1020
+ imageSrc: imageSrc,
1021
+ categoryElements: categoryElementsProcessed,
1022
+ brandElements: dropdownData[elementsKey] || [],
1023
+ productsUrl: productsUrl,
1024
+ categorySlug: categorySlug,
1025
+ categoryTitle: categoryName,
1026
+ isLoading: loading,
1027
+ hasError: hasError,
1028
+ LinkComponent: LinkComponent
1029
+ });
1030
+ });
1031
+ };
1032
+
1001
1033
  var getMarginRight = function getMarginRight(userIsVip, userName) {
1002
1034
  if (userIsVip) return '15px';
1003
1035
  if (userName) return '5px';
@@ -1035,7 +1067,7 @@
1035
1067
  value: searchValue,
1036
1068
  onChange: handleChange,
1037
1069
  onKeyDown: handleKeyDown,
1038
- onClick: handleSearchFocus,
1070
+ onClick: handleSearchClick,
1039
1071
  onFocus: handleSearchFocus
1040
1072
  })), /*#__PURE__*/React__default.createElement(SearchResults, {
1041
1073
  searchValue: searchValue,
@@ -1059,74 +1091,9 @@
1059
1091
  currencySymbol: currencySymbol
1060
1092
  }), /*#__PURE__*/React__default.createElement("nav", {
1061
1093
  className: "navbar__nav-links navbar__nav-links--wrap"
1062
- }, /*#__PURE__*/React__default.createElement(DropdownLink, {
1063
- title: "New",
1064
- imageSrc: newBrandsImage,
1065
- categoryElements: categoryElements,
1066
- brandElements: dropdownData.latestArrivals,
1067
- productsUrl: productsUrl,
1068
- categorySlug: "brands",
1069
- categoryTitle: "Brands",
1070
- isLoading: loading,
1071
- hasError: hasError,
1072
- LinkComponent: LinkComponent
1073
- }), /*#__PURE__*/React__default.createElement(DropdownLink, {
1074
- title: "Bags",
1075
- imageSrc: bagsImage,
1076
- categoryElements: addCategoryToElements(categoryElements, categories.bags.slug),
1077
- brandElements: dropdownData.bags,
1078
- productsUrl: productsUrl,
1079
- categorySlug: categories.bags.slug,
1080
- categoryTitle: categories.bags.name,
1081
- isLoading: loading,
1082
- hasError: hasError,
1083
- LinkComponent: LinkComponent
1084
- }), /*#__PURE__*/React__default.createElement(DropdownLink, {
1085
- title: "Shoes",
1086
- imageSrc: shoesImage,
1087
- categoryElements: addCategoryToElements(categoryElements, categories.shoes.slug),
1088
- brandElements: dropdownData.shoes,
1089
- productsUrl: productsUrl,
1090
- categorySlug: categories.shoes.slug,
1091
- categoryTitle: categories.shoes.name,
1092
- isLoading: loading,
1093
- hasError: hasError,
1094
- LinkComponent: LinkComponent
1095
- }), /*#__PURE__*/React__default.createElement(DropdownLink, {
1096
- title: "Clothing",
1097
- imageSrc: clothingImage,
1098
- categoryElements: addCategoryToElements(dropdownData.apparelStyles, categories.clothing.slug),
1099
- brandElements: dropdownData.apparel,
1100
- productsUrl: productsUrl,
1101
- categorySlug: categories.clothing.slug,
1102
- categoryTitle: categories.clothing.name,
1103
- isLoading: loading,
1104
- hasError: hasError,
1105
- LinkComponent: LinkComponent
1106
- }), /*#__PURE__*/React__default.createElement(DropdownLink, {
1107
- title: "Accessories",
1108
- imageSrc: accessoriesImage,
1109
- categoryElements: removeCategoryByName(dropdownData.accessoriesCategories, 'ACCESSORIES'),
1110
- brandElements: dropdownData.accessories,
1111
- productsUrl: productsUrl,
1112
- categorySlug: categories.accessories.slug,
1113
- categoryTitle: categories.accessories.name,
1114
- isLoading: loading,
1115
- hasError: hasError,
1116
- LinkComponent: LinkComponent
1117
- }), /*#__PURE__*/React__default.createElement(DropdownLink, {
1118
- title: "Watches",
1119
- imageSrc: watchesImage,
1120
- categoryElements: addCategoryToElements(categoryElements, categories.watches.slug),
1121
- brandElements: dropdownData.watches,
1122
- productsUrl: productsUrl,
1123
- categorySlug: categories.watches.slug,
1124
- categoryTitle: categories.watches.name,
1125
- isLoading: loading,
1126
- hasError: hasError,
1127
- LinkComponent: LinkComponent
1128
- }), /*#__PURE__*/React__default.createElement("li", {
1129
- className: "navbar__link"
1094
+ }, renderDropdownLinks(), !!stores.length && /*#__PURE__*/React__default.createElement("li", {
1095
+ className: "navbar__link",
1096
+ key: "Stores"
1130
1097
  }, /*#__PURE__*/React__default.createElement(LinkComponent, {
1131
1098
  href: contactUsLink,
1132
1099
  className: "navbar__link-item navbar__link-item--desktop"
@@ -1169,7 +1136,7 @@
1169
1136
  onClick: onAccountClick
1170
1137
  }, /*#__PURE__*/React__default.createElement("span", {
1171
1138
  className: "text-sm"
1172
- }, name))), /*#__PURE__*/React__default.createElement("button", {
1139
+ }, name))), onInterestClick && /*#__PURE__*/React__default.createElement("button", {
1173
1140
  type: "button",
1174
1141
  className: "".concat(app ? 'navbar__icon--app' : 'navbar__icon'),
1175
1142
  onClick: onInterestClick
package/LuxityFooter.js CHANGED
@@ -2102,13 +2102,13 @@
2102
2102
  setError = _useForm.setError;
2103
2103
 
2104
2104
  var renderLinks = function renderLinks(links, title) {
2105
- return /*#__PURE__*/React__default.createElement("div", {
2105
+ return !!links.length && /*#__PURE__*/React__default.createElement("div", {
2106
2106
  className: "footer__link-container"
2107
2107
  }, /*#__PURE__*/React__default.createElement("div", {
2108
2108
  className: "footer__link-title"
2109
2109
  }, title), /*#__PURE__*/React__default.createElement("div", {
2110
2110
  className: "footer__links"
2111
- }, !!links.length && links.map(function (link) {
2111
+ }, links.map(function (link) {
2112
2112
  return /*#__PURE__*/React__default.createElement("div", {
2113
2113
  className: "footer__link-wrapper",
2114
2114
  key: link.label
@@ -2291,13 +2291,13 @@
2291
2291
  }), /*#__PURE__*/React__default.createElement(AccordionSection, {
2292
2292
  title: "POPULAR",
2293
2293
  links: popularLinks
2294
- }), /*#__PURE__*/React__default.createElement(AccordionSection, {
2294
+ }), !!sellLinks.length && /*#__PURE__*/React__default.createElement(AccordionSection, {
2295
2295
  title: "SELL",
2296
2296
  links: sellLinks
2297
2297
  }), /*#__PURE__*/React__default.createElement(AccordionSection, {
2298
2298
  title: "COMPANY",
2299
2299
  links: companyLinks
2300
- }), /*#__PURE__*/React__default.createElement(AccordionSection, {
2300
+ }), !!storeLinks.length && /*#__PURE__*/React__default.createElement(AccordionSection, {
2301
2301
  title: "CONNECT",
2302
2302
  links: storeLinks
2303
2303
  }), /*#__PURE__*/React__default.createElement("div", {