@growupsell/react-ecommerce-core 2.0.17 → 2.0.18

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.
@@ -2,7 +2,7 @@ import { BusinessConfigContext } from './chunk-SP77KIKJ.js';
2
2
  import { createContext, useState, useContext, useEffect, useMemo, useRef, useCallback } from 'react';
3
3
  import { jsx, Fragment } from 'react/jsx-runtime';
4
4
  import { WAApi, api } from '@growupsell/api';
5
- import { retrieveThemeContent, updateThemeContent, getCustomPageContent, splitCustomPageContent, createCustomerSession, getBusinessSetting, getRewardPointBusinessConfig, getOrderBusinessConfig, updateCustomPageContent, mergeCustomPageContent } from '@growupsell/api/api';
5
+ import { retrieveThemeContent, updateThemeContent, getCustomPageContent, splitCustomPageContent, readHeroSectionValue, createCustomerSession, getBusinessSetting, getRewardPointBusinessConfig, getOrderBusinessConfig, updateCustomPageContent, mergeCustomPageContent } from '@growupsell/api/api';
6
6
  import 'lodash';
7
7
 
8
8
  var StorageContext = createContext({
@@ -554,10 +554,18 @@ var CartProvider = (props) => {
554
554
  );
555
555
  };
556
556
  var useCart = () => useContext(CartContext);
557
+ var getRouteCategoryId = () => {
558
+ if (typeof window === "undefined") return null;
559
+ const match = window.location.pathname.match(/\/products\/[^/]+\/(\d+)\/?$/);
560
+ if (!match) return null;
561
+ const id = Number(match[1]);
562
+ return Number.isFinite(id) ? id : null;
563
+ };
557
564
  var FilterContext = createContext({
558
565
  selectedCategoryId: [],
559
566
  addCategoryFilterId: () => null,
560
567
  removeCategoryFilterId: () => null,
568
+ replaceCategoryFilterIds: () => null,
561
569
  menuList: [],
562
570
  productLoading: true,
563
571
  currentPage: 1,
@@ -614,6 +622,7 @@ var FilterProvider = (props) => {
614
622
  const [limit, setLimit] = useState(10);
615
623
  const [offset, setOffset] = useState(0);
616
624
  const [total, setTotal] = useState(0);
625
+ const waitingForRouteCategory = useRef(getRouteCategoryId() != null);
617
626
  const fetchBrandList = async () => {
618
627
  setBrandLoading(true);
619
628
  let body = {
@@ -637,6 +646,15 @@ var FilterProvider = (props) => {
637
646
  });
638
647
  setCurrentPage(1);
639
648
  };
649
+ const replaceCategoryFilterIds = (ids) => {
650
+ const unique = Array.from(new Set(ids.filter((id) => Number.isFinite(id))));
651
+ setSelectedCategoryId(unique);
652
+ setCurrentPage(1);
653
+ setOffset(0);
654
+ setMenuList([]);
655
+ setProductLoading(true);
656
+ waitingForRouteCategory.current = false;
657
+ };
640
658
  const categoryFilterKey = selectedCategoryId.length === 1 ? selectedCategoryId[0] : void 0;
641
659
  useEffect(() => {
642
660
  let active = true;
@@ -733,9 +751,10 @@ var FilterProvider = (props) => {
733
751
  setVariantLoading(false);
734
752
  };
735
753
  useEffect(() => {
736
- if (!filterConfigLoading) {
737
- fetchProductList();
738
- }
754
+ if (filterConfigLoading) return;
755
+ if (waitingForRouteCategory.current && selectedCategoryId.length === 0) return;
756
+ waitingForRouteCategory.current = false;
757
+ fetchProductList();
739
758
  }, [
740
759
  selectedCategoryId,
741
760
  currentPage,
@@ -788,6 +807,7 @@ var FilterProvider = (props) => {
788
807
  setMenuList,
789
808
  addCategoryFilterId,
790
809
  removeCategoryFilterId,
810
+ replaceCategoryFilterIds,
791
811
  menuList,
792
812
  productLoading,
793
813
  currentPage,
@@ -997,6 +1017,7 @@ var HomeConfigProvider = (props) => {
997
1017
  });
998
1018
  const { token } = useThemeEdit();
999
1019
  const themeConfig = useContext(BusinessConfigContext);
1020
+ const themeId = themeConfig.theme.id;
1000
1021
  const [themeConfigData, setThemeConfigData] = useState(
1001
1022
  props.initialThemeContent ?? {}
1002
1023
  );
@@ -1004,16 +1025,13 @@ var HomeConfigProvider = (props) => {
1004
1025
  const updateRef = useRef(false);
1005
1026
  const [loading, setLoading] = useState(!hasInitial);
1006
1027
  const getThemeConfig = useCallback(async () => {
1007
- if (!hasInitial) {
1008
- setLoading(true);
1009
- } else {
1028
+ if (hasInitial || !themeId) {
1029
+ if (!themeId) setLoading(false);
1010
1030
  return;
1011
1031
  }
1032
+ setLoading(true);
1012
1033
  try {
1013
- const response = await retrieveThemeContent(
1014
- themeConfig.theme.id,
1015
- props.page
1016
- );
1034
+ const response = await retrieveThemeContent(themeId, props.page);
1017
1035
  setThemeConfigData(response);
1018
1036
  if (response?.data && Array.isArray(response.data)) {
1019
1037
  setSelectedConfig(
@@ -1028,7 +1046,7 @@ var HomeConfigProvider = (props) => {
1028
1046
  } finally {
1029
1047
  setLoading(false);
1030
1048
  }
1031
- }, [themeConfig.theme.id, hasInitial, props.page]);
1049
+ }, [themeId, hasInitial, props.page]);
1032
1050
  const onUpdateThemeContent = useCallback(
1033
1051
  async (configToUpdate = selectedConfig) => {
1034
1052
  try {
@@ -1039,16 +1057,9 @@ var HomeConfigProvider = (props) => {
1039
1057
  };
1040
1058
  if (updateRef.current) return;
1041
1059
  updateRef.current = true;
1042
- await updateThemeContent(
1043
- body,
1044
- themeConfig?.theme?.id,
1045
- props.page,
1046
- token
1047
- );
1048
- const updatedResponse = await retrieveThemeContent(
1049
- themeConfig.theme.id,
1050
- props.page
1051
- );
1060
+ if (!themeId) return;
1061
+ await updateThemeContent(body, themeId, props.page, token);
1062
+ const updatedResponse = await retrieveThemeContent(themeId, props.page);
1052
1063
  setThemeConfigData(updatedResponse);
1053
1064
  } catch (error) {
1054
1065
  console.error("Error updating theme content:", error);
@@ -1056,7 +1067,7 @@ var HomeConfigProvider = (props) => {
1056
1067
  updateRef.current = false;
1057
1068
  }
1058
1069
  },
1059
- [isInitialized, token, themeConfig?.theme?.id, selectedConfig]
1070
+ [isInitialized, token, themeId, selectedConfig]
1060
1071
  );
1061
1072
  const addConfig = useCallback(
1062
1073
  async (config) => {
@@ -1122,73 +1133,76 @@ var HomeConfigProvider = (props) => {
1122
1133
  );
1123
1134
  };
1124
1135
  var useHomeConfig = () => useContext(HomeConfigContext);
1125
- var HomeConfigHeroSliderContext = createContext({
1136
+ var HERO_SECTION_SLUG = "hero_section";
1137
+ function resolveHeroSection(sectionRow) {
1138
+ if (sectionRow == null) return null;
1139
+ const data = sectionRow.data !== void 0 ? sectionRow.data : sectionRow;
1140
+ if (!data || typeof data !== "object" || Array.isArray(data)) return null;
1141
+ if (typeof data.type !== "string" || !data.type) return null;
1142
+ return { type: data.type, data: data.data };
1143
+ }
1144
+ var HomeConfigHeroSectionContext = createContext({
1126
1145
  loading: true,
1127
- heroSliderConfigData: [],
1128
- onUpdateHeroSlider: () => null
1146
+ heroSection: null,
1147
+ onUpdateHeroSection: async () => void 0
1129
1148
  });
1130
- var HomeConfigHeroSliderProvider = (props) => {
1131
- const hasInitial = Array.isArray(props.initialThemeContent?.data);
1132
- const [loading, setLoading] = useState(!hasInitial);
1133
- const [heroSliderConfigData, setHeroSliderConfigData] = useState(
1134
- () => hasInitial ? props.initialThemeContent.data : []
1149
+ var HomeConfigHeroSectionProvider = (props) => {
1150
+ const [heroSection, setHeroSection] = useState(
1151
+ () => props.heroContentFetched ? resolveHeroSection(props.initialHeroSection) : null
1135
1152
  );
1153
+ const [loading, setLoading] = useState(!props.heroContentFetched);
1136
1154
  const { token } = useThemeEdit();
1137
1155
  const themeConfig = useContext(BusinessConfigContext);
1138
- const getHeroSliderConfig = useCallback(async () => {
1139
- if (hasInitial) {
1156
+ const themeId = themeConfig.theme.id;
1157
+ const loadHeroSection = useCallback(async () => {
1158
+ if (props.heroContentFetched || !themeId) {
1159
+ if (!themeId) setLoading(false);
1140
1160
  return;
1141
1161
  }
1142
1162
  setLoading(true);
1143
1163
  try {
1144
- const response = await retrieveThemeContent(
1145
- themeConfig.theme.id,
1146
- "hero_slider"
1147
- );
1148
- setHeroSliderConfigData(response.data);
1164
+ let sectionRow = null;
1165
+ try {
1166
+ sectionRow = await retrieveThemeContent(themeId, HERO_SECTION_SLUG);
1167
+ } catch {
1168
+ sectionRow = null;
1169
+ }
1170
+ setHeroSection(resolveHeroSection(sectionRow));
1149
1171
  } catch (error) {
1150
- console.error("Error fetching hero slider content:", error);
1172
+ console.error("Error fetching hero section:", error);
1151
1173
  } finally {
1152
1174
  setLoading(false);
1153
1175
  }
1154
- }, [themeConfig.theme.id, hasInitial]);
1176
+ }, [props.heroContentFetched, themeId]);
1155
1177
  useEffect(() => {
1156
- getHeroSliderConfig();
1157
- }, [getHeroSliderConfig]);
1158
- const onUpdateHeroSlider = async (configToUpdate) => {
1178
+ loadHeroSection();
1179
+ }, [loadHeroSection]);
1180
+ const onUpdateHeroSection = async (next) => {
1159
1181
  setLoading(true);
1160
1182
  try {
1161
1183
  const body = {
1162
- data: configToUpdate,
1163
- slug: "hero_slider",
1184
+ data: next ? { type: next.type, data: next.data } : { type: null, data: null },
1185
+ slug: HERO_SECTION_SLUG,
1164
1186
  platform: typeof window !== "undefined" ? "website" : "app"
1165
1187
  };
1166
- await updateThemeContent(
1167
- body,
1168
- themeConfig?.theme?.id,
1169
- "hero_slider",
1170
- token
1171
- );
1172
- const updatedResponse = await retrieveThemeContent(
1173
- themeConfig.theme.id,
1174
- "hero_slider"
1175
- );
1176
- setHeroSliderConfigData(updatedResponse.data);
1188
+ await updateThemeContent(body, themeId, HERO_SECTION_SLUG, token);
1189
+ setHeroSection(next);
1177
1190
  } catch (error) {
1178
- console.error("Error updating theme content:", error);
1191
+ console.error("Error updating hero section:", error);
1192
+ throw error;
1179
1193
  } finally {
1180
1194
  setLoading(false);
1181
1195
  }
1182
1196
  };
1183
1197
  return /* @__PURE__ */ jsx(
1184
- HomeConfigHeroSliderContext.Provider,
1198
+ HomeConfigHeroSectionContext.Provider,
1185
1199
  {
1186
- value: { loading, heroSliderConfigData, onUpdateHeroSlider },
1200
+ value: { loading, heroSection, onUpdateHeroSection },
1187
1201
  children: props.children
1188
1202
  }
1189
1203
  );
1190
1204
  };
1191
- var useHomeConfigHeroSlider = () => useContext(HomeConfigHeroSliderContext);
1205
+ var useHomeConfigHeroSection = () => useContext(HomeConfigHeroSectionContext);
1192
1206
  var CustomPageConfigContext = createContext({
1193
1207
  selectedConfig: [],
1194
1208
  setSelectedConfig: () => null,
@@ -1196,28 +1210,26 @@ var CustomPageConfigContext = createContext({
1196
1210
  updateConfig: () => null,
1197
1211
  removeConfig: () => null,
1198
1212
  moveConfig: () => null,
1199
- heroSliderConfigData: [],
1200
- onUpdateHeroSlider: async () => void 0,
1201
1213
  loading: true
1202
1214
  });
1203
1215
  var CustomPageConfigProvider = (props) => {
1204
1216
  const { token } = useThemeEdit();
1205
1217
  const [selectedConfig, setSelectedConfig] = useState([]);
1206
- const [heroSliderConfigData, setHeroSliderConfigData] = useState([]);
1218
+ const [heroSection, setHeroSection] = useState(null);
1207
1219
  const [loading, setLoading] = useState(true);
1208
1220
  const selectedConfigRef = useRef([]);
1209
- const heroSlidesRef = useRef([]);
1221
+ const heroSectionRef = useRef(null);
1210
1222
  const saveQueueRef = useRef(Promise.resolve());
1211
1223
  const load = useCallback(async () => {
1212
1224
  setLoading(true);
1213
1225
  try {
1214
1226
  const row = await getCustomPageContent(props.pageId, token);
1215
1227
  const fromContent = splitCustomPageContent(row?.content);
1216
- const slides = Array.isArray(row?.hero_content) ? row.hero_content : fromContent.heroSlides;
1228
+ const hero = row?.hero_content !== void 0 && row?.hero_content !== null ? readHeroSectionValue(row.hero_content) : fromContent.heroSection;
1217
1229
  selectedConfigRef.current = fromContent.blocks;
1218
- heroSlidesRef.current = slides;
1230
+ heroSectionRef.current = hero;
1219
1231
  setSelectedConfig(fromContent.blocks);
1220
- setHeroSliderConfigData(slides);
1232
+ setHeroSection(hero);
1221
1233
  } catch (e) {
1222
1234
  console.error("Error loading custom page content:", e);
1223
1235
  } finally {
@@ -1225,16 +1237,16 @@ var CustomPageConfigProvider = (props) => {
1225
1237
  }
1226
1238
  }, [props.pageId, token]);
1227
1239
  const persistLatest = useCallback(
1228
- (writeHeroField = false) => {
1240
+ () => {
1229
1241
  const run = async () => {
1230
1242
  try {
1231
1243
  const blocks = selectedConfigRef.current;
1232
- const slides = heroSlidesRef.current;
1244
+ const hero = heroSectionRef.current;
1233
1245
  await updateCustomPageContent(
1234
1246
  props.pageId,
1235
1247
  {
1236
- content: mergeCustomPageContent(blocks, slides),
1237
- ...writeHeroField ? { hero_content: slides } : {}
1248
+ content: mergeCustomPageContent(blocks, hero),
1249
+ hero_content: hero ? { type: hero.type, data: hero.data } : { type: null, data: null }
1238
1250
  },
1239
1251
  token
1240
1252
  );
@@ -1293,12 +1305,11 @@ var CustomPageConfigProvider = (props) => {
1293
1305
  },
1294
1306
  [persistLatest]
1295
1307
  );
1296
- const onUpdateHeroSlider = useCallback(
1297
- async (slidesToSave) => {
1298
- const slides = Array.isArray(slidesToSave) ? slidesToSave : [];
1299
- heroSlidesRef.current = slides;
1300
- setHeroSliderConfigData(slides);
1301
- await persistLatest(true);
1308
+ const onUpdateHeroSection = useCallback(
1309
+ async (next) => {
1310
+ heroSectionRef.current = next;
1311
+ setHeroSection(next);
1312
+ await persistLatest();
1302
1313
  },
1303
1314
  [persistLatest]
1304
1315
  );
@@ -1315,14 +1326,12 @@ var CustomPageConfigProvider = (props) => {
1315
1326
  updateConfig,
1316
1327
  removeConfig,
1317
1328
  moveConfig,
1318
- heroSliderConfigData,
1319
- onUpdateHeroSlider,
1320
1329
  loading
1321
1330
  },
1322
1331
  children: /* @__PURE__ */ jsx(
1323
- HomeConfigHeroSliderContext.Provider,
1332
+ HomeConfigHeroSectionContext.Provider,
1324
1333
  {
1325
- value: { loading, heroSliderConfigData, onUpdateHeroSlider },
1334
+ value: { loading, heroSection, onUpdateHeroSection },
1326
1335
  children: props.children
1327
1336
  }
1328
1337
  )
@@ -1483,17 +1492,16 @@ var HeaderFooterProvider = (props) => {
1483
1492
  );
1484
1493
  const { token } = useThemeEdit();
1485
1494
  const themeConfig = useBusiness();
1495
+ const themeId = themeConfig.theme.id;
1486
1496
  const [loading, setLoading] = useState(!hasInitial);
1487
1497
  const getThemeConfig = useCallback(async () => {
1488
- if (hasInitial) {
1498
+ if (hasInitial || !themeId) {
1499
+ if (!themeId) setLoading(false);
1489
1500
  return;
1490
1501
  }
1491
1502
  setLoading(true);
1492
1503
  try {
1493
- const response = await api.retrieveThemeContent(
1494
- themeConfig.theme.id,
1495
- props.page
1496
- );
1504
+ const response = await api.retrieveThemeContent(themeId, props.page);
1497
1505
  response.slug === "header" && setHeaderConfig(response.data);
1498
1506
  response.slug === "footer" && setFooterConfig(response.data);
1499
1507
  response.slug === "announcement" && setAnnouncementConfig(response.data);
@@ -1502,7 +1510,7 @@ var HeaderFooterProvider = (props) => {
1502
1510
  } finally {
1503
1511
  setLoading(false);
1504
1512
  }
1505
- }, [themeConfig.theme.id, hasInitial, props.page]);
1513
+ }, [themeId, hasInitial, props.page]);
1506
1514
  const onUpdateThemeContent = useCallback(
1507
1515
  async (configToUpdate) => {
1508
1516
  try {
@@ -1511,14 +1519,10 @@ var HeaderFooterProvider = (props) => {
1511
1519
  slug: props.page,
1512
1520
  platform: typeof window !== "undefined" ? "website" : "app"
1513
1521
  };
1514
- await api.updateThemeContent(
1515
- body,
1516
- themeConfig.theme.id,
1517
- props.page,
1518
- token
1519
- );
1522
+ if (!themeId) return;
1523
+ await api.updateThemeContent(body, themeId, props.page, token);
1520
1524
  const updatedResponse = await api.retrieveThemeContent(
1521
- themeConfig.theme.id,
1525
+ themeId,
1522
1526
  props.page
1523
1527
  );
1524
1528
  updatedResponse.slug === "header" && setHeaderConfig(updatedResponse.data);
@@ -1530,7 +1534,7 @@ var HeaderFooterProvider = (props) => {
1530
1534
  setLoading(false);
1531
1535
  }
1532
1536
  },
1533
- [props.page, themeConfig.theme.id, token]
1537
+ [props.page, themeId, token]
1534
1538
  );
1535
1539
  useEffect(() => {
1536
1540
  getThemeConfig();
@@ -2003,6 +2007,6 @@ var BaseProvider = ({
2003
2007
  return /* @__PURE__ */ jsx(StorageProvider, { storage, children: /* @__PURE__ */ jsx(ToastSupportProvider, { value: toast, children: /* @__PURE__ */ jsx(BusinessConfigProvider, { data: businessConfig, baseURL, children: /* @__PURE__ */ jsx(ReferralCodeProvider, { referralCodeFromUrl, children: /* @__PURE__ */ jsx(ThemeEditProvider, { isThemeEdit: isEdit, token, isHeader, isFooter, isAnnouncementBar, children: /* @__PURE__ */ jsx(BusinessMediaProvider, { children: /* @__PURE__ */ jsx(CustomerConfigProvider, { children: /* @__PURE__ */ jsx(AuthProvider, { children: /* @__PURE__ */ jsx(ModalProvider, { children: /* @__PURE__ */ jsx(LiveSupportWidgetProvider, { children: businessConfig.category.type == "retail" ? /* @__PURE__ */ jsx(ProductConfigProvider, { children: /* @__PURE__ */ jsx(CartWishlistRefreshProvider, { children: /* @__PURE__ */ jsx(CartProvider, { children: /* @__PURE__ */ jsx(WishlistProvider, { children: /* @__PURE__ */ jsx(FilterProvider, { children: /* @__PURE__ */ jsx(Fragment, { children }) }) }) }) }) }) : /* @__PURE__ */ jsx(MenuCartProvider, { children: /* @__PURE__ */ jsx(MenuFilterProvider, { children: /* @__PURE__ */ jsx(Fragment, { children }) }) }) }) }) }) }) }) }) }) }) }) });
2004
2008
  };
2005
2009
 
2006
- export { AuthContext, AuthProvider, BaseProvider, BusinessConfigProvider, BusinessMediaContext, BusinessMediaProvider, CartContext, CartProvider, CartWishlistRefreshContext, CartWishlistRefreshProvider, CustomPageConfigContext, CustomPageConfigProvider, CustomerConfigContext, CustomerConfigProvider, FilterContext, FilterProvider, HeaderFooterContext, HeaderFooterProvider, HomeConfigContext, HomeConfigHeroSliderContext, HomeConfigHeroSliderProvider, HomeConfigProvider, LiveSupportWidgetProvider, MenuCartContext, MenuCartProvider, MenuFilterContext, MenuFilterProvider, ModalProvider, ProductConfigContext, ProductConfigProvider, ProductDetailContext, ProductDetailProvider, ReferralCodeProvider, StorageContext, StorageProvider, ThemeEditContext, ThemeEditProvider, ToastSupportProvider, WishlistContext, WishlistProvider, useAuth, useBusiness, useBusinessContext, useBusinessMedia, useCart, useCartWishlistRefresh, useCustomPageConfig, useCustomer, useFilter, useHeaderFooter, useHomeConfig, useHomeConfigHeroSlider, useLiveSupportWidget, useMenuCart, useMenuFilter, useModal, useProductConfig, useProductDetail, useReferralCode, useStorage, useThemeEdit, useToastSupport, useWishlist };
2007
- //# sourceMappingURL=chunk-D24PXFD3.js.map
2008
- //# sourceMappingURL=chunk-D24PXFD3.js.map
2010
+ export { AuthContext, AuthProvider, BaseProvider, BusinessConfigProvider, BusinessMediaContext, BusinessMediaProvider, CartContext, CartProvider, CartWishlistRefreshContext, CartWishlistRefreshProvider, CustomPageConfigContext, CustomPageConfigProvider, CustomerConfigContext, CustomerConfigProvider, FilterContext, FilterProvider, HERO_SECTION_SLUG, HeaderFooterContext, HeaderFooterProvider, HomeConfigContext, HomeConfigHeroSectionContext, HomeConfigHeroSectionProvider, HomeConfigProvider, LiveSupportWidgetProvider, MenuCartContext, MenuCartProvider, MenuFilterContext, MenuFilterProvider, ModalProvider, ProductConfigContext, ProductConfigProvider, ProductDetailContext, ProductDetailProvider, ReferralCodeProvider, StorageContext, StorageProvider, ThemeEditContext, ThemeEditProvider, ToastSupportProvider, WishlistContext, WishlistProvider, resolveHeroSection, useAuth, useBusiness, useBusinessContext, useBusinessMedia, useCart, useCartWishlistRefresh, useCustomPageConfig, useCustomer, useFilter, useHeaderFooter, useHomeConfig, useHomeConfigHeroSection, useLiveSupportWidget, useMenuCart, useMenuFilter, useModal, useProductConfig, useProductDetail, useReferralCode, useStorage, useThemeEdit, useToastSupport, useWishlist };
2011
+ //# sourceMappingURL=chunk-FOGKAOV4.js.map
2012
+ //# sourceMappingURL=chunk-FOGKAOV4.js.map