@anker-in/shopify-react 0.1.1-beta.2 → 0.1.1-beta.20

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.
@@ -1,5 +1,5 @@
1
1
  import { createContext, useMemo, useContext, useState, useCallback, useEffect, useRef } from 'react';
2
- import { createShopifyClient, getCart, updateCartAttributes, updateCartLines, getProductsByHandles } from '@anker-in/shopify-sdk';
2
+ import { createShopifyClient, getCart, updateCartAttributes, updateCartLines, btoaID, getProductsByHandles, getLocalStorage, atobID } from '@anker-in/shopify-sdk';
3
3
  import Cookies5 from 'js-cookie';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
  import Decimal2 from 'decimal.js';
@@ -95,6 +95,81 @@ var CODE_AMOUNT_KEY = "_sku_code_money";
95
95
  var SCRIPT_CODE_AMOUNT_KEY = "_code_money";
96
96
  var MAIN_PRODUCT_CODE = ["WS24", "WSTD", "WS7D", "WSCP", "WSPE", "WSPD"];
97
97
 
98
+ // src/hooks/cart/utils/normalize-add-to-cart-lines.ts
99
+ function normalizeAddToCartLines(lines) {
100
+ return lines.filter((line) => line.variant?.id).map((line, index) => {
101
+ const variant = line.variant;
102
+ const product = variant.product;
103
+ const quantity = line.quantity || 1;
104
+ const price = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : variant.price?.amount ? Number(variant.price.amount) : 0;
105
+ const subtotalAmount = price * quantity;
106
+ const totalAmount = subtotalAmount;
107
+ return {
108
+ id: `temp-line-${index}-${variant.id}`,
109
+ // Temporary ID for pre-cart lines
110
+ name: product?.title || variant.title || "",
111
+ quantity,
112
+ variantId: variant.id,
113
+ productId: product?.id || variant.id.split("/").slice(0, -2).join("/"),
114
+ totalAmount,
115
+ subtotalAmount,
116
+ discountAllocations: [],
117
+ customAttributes: line.attributes || [],
118
+ variant: {
119
+ id: variant.id,
120
+ price,
121
+ listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
122
+ sku: variant.sku || "",
123
+ name: variant.title || "",
124
+ image: variant.image ? {
125
+ url: variant.image.url,
126
+ altText: variant.image.altText || void 0
127
+ } : void 0,
128
+ requiresShipping: false,
129
+ // Default value, not available in NormalizedProductVariant
130
+ availableForSale: variant.availableForSale ?? true,
131
+ quantityAvailable: variant.quantityAvailable ?? 0,
132
+ currentlyNotInStock: false,
133
+ // Default value, will be updated when added to cart
134
+ weight: variant.weight,
135
+ metafields: variant.metafields
136
+ },
137
+ product,
138
+ path: product?.handle ? `/products/${product.handle}` : "",
139
+ discounts: [],
140
+ options: variant.selectedOptions?.map((opt) => ({
141
+ name: opt.name,
142
+ value: opt.value
143
+ }))
144
+ };
145
+ });
146
+ }
147
+ function createMockCartFromLines(lines, existingCart) {
148
+ const normalizedLines = normalizeAddToCartLines(lines);
149
+ const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
150
+ const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
151
+ return {
152
+ id: existingCart?.id || "temp-cart-id",
153
+ customerId: existingCart?.customerId,
154
+ email: existingCart?.email,
155
+ createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
156
+ currency: existingCart?.currency || { code: "USD" },
157
+ taxesIncluded: existingCart?.taxesIncluded,
158
+ lineItems: normalizedLines,
159
+ totalLineItemsDiscount: 0,
160
+ orderDiscounts: 0,
161
+ lineItemsSubtotalPrice: subtotalPrice,
162
+ subtotalPrice,
163
+ totalPrice,
164
+ totalTaxAmount: 0,
165
+ discountCodes: existingCart?.discountCodes || [],
166
+ discountAllocations: [],
167
+ url: existingCart?.url || "",
168
+ ready: true,
169
+ customAttributes: existingCart?.customAttributes
170
+ };
171
+ }
172
+
98
173
  // src/hooks/cart/utils/index.ts
99
174
  var getQuery = () => {
100
175
  const url = typeof window !== "undefined" ? window.location.search : "";
@@ -112,16 +187,6 @@ var getQuery = () => {
112
187
  }
113
188
  return theRequest;
114
189
  };
115
- function atobID(id) {
116
- if (id && typeof id === "string" && id.includes("/")) {
117
- return id.split("/").pop()?.split("?")?.shift();
118
- } else {
119
- return id;
120
- }
121
- }
122
- function btoaID(id, type = "ProductVariant") {
123
- return `gid://shopify/${type}/${id}`;
124
- }
125
190
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
126
191
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
127
192
  const matchedList = cartData?.lineItems?.filter((line) => {
@@ -319,12 +384,15 @@ var formatFunctionAutoFreeGift = ({
319
384
  };
320
385
  return result;
321
386
  };
322
- var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
387
+ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
323
388
  const tags = useMemo(() => customer?.tags || [], [customer?.tags]);
324
389
  const isCustomerLoading = useMemo(() => !customer ? true : false, [customer]);
325
390
  const dealsType = "";
326
391
  const { client, locale } = useShopify();
327
392
  const giftProductsCache = useRef(null);
393
+ const effectiveCart = useMemo(() => {
394
+ return cart;
395
+ }, [lines, cart]);
328
396
  const { activeCampaign, subtotal } = useMemo(() => {
329
397
  for (const campaign of autoFreeGiftConfig) {
330
398
  const { rule_conditions = [], rule_result } = campaign;
@@ -332,7 +400,7 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
332
400
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
333
401
  if (isPreCheckPassed && spend_get_reward) {
334
402
  const matchedSubtotal = getMatchedMainProductSubTotal(
335
- cart,
403
+ effectiveCart,
336
404
  spend_get_reward.main_product?.variant_list?.map((v) => v.variant_id) || [],
337
405
  {
338
406
  spend_money_type: spend_get_reward.main_product?.spend_money_type || 1,
@@ -346,13 +414,13 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
346
414
  }
347
415
  }
348
416
  return { activeCampaign: null, subtotal: 0 };
349
- }, [autoFreeGiftConfig, cart, tags, dealsType]);
417
+ }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
350
418
  const { qualifyingGift, nextTierGoal } = useMemo(() => {
351
419
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
352
420
  return { qualifyingGift: null, nextTierGoal: null };
353
421
  }
354
422
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
355
- const qualifyingTier = [...giftTiers].reverse().find((tier) => subtotal >= Number(tier.spend_sum_money));
423
+ const qualifyingTier = [...giftTiers].sort((a, b) => Number(b.spend_sum_money) - Number(a.spend_sum_money)).find((tier) => subtotal >= Number(tier.spend_sum_money));
356
424
  const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
357
425
  if (!qualifyingTier) {
358
426
  return { qualifyingGift: null, nextTierGoal: nextGoal || null };
@@ -399,18 +467,24 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer) => {
399
467
  }
400
468
  return true;
401
469
  }, [giftHandles]);
402
- const { data: giftProductsResult } = useSWR(shouldFetch ? giftHandles : null, async () => {
403
- const res = await getProductsByHandles(client, {
404
- handles: giftHandles,
405
- locale
406
- });
407
- const result = Array.isArray(res) ? res : [];
408
- giftProductsCache.current = {
409
- data: result,
410
- giftHandles: [...giftHandles]
411
- };
412
- return result;
413
- });
470
+ const { data: giftProductsResult } = useSWR(
471
+ shouldFetch ? giftHandles : null,
472
+ async () => {
473
+ const res = await getProductsByHandles(client, {
474
+ handles: giftHandles,
475
+ locale
476
+ });
477
+ const result = Array.isArray(res) ? res : [];
478
+ giftProductsCache.current = {
479
+ data: result,
480
+ giftHandles: [...giftHandles]
481
+ };
482
+ return result;
483
+ },
484
+ {
485
+ revalidateOnFocus: false
486
+ }
487
+ );
414
488
  const finalGiftProductsResult = useMemo(() => {
415
489
  if (giftProductsCache.current && !shouldFetch) {
416
490
  return giftProductsCache.current.data || void 0;
@@ -429,12 +503,19 @@ var useScriptAutoFreeGift = ({
429
503
  campaign,
430
504
  _giveaway,
431
505
  cart,
432
- locale: providedLocale
506
+ locale: providedLocale,
507
+ lines
433
508
  }) => {
434
509
  const { client, locale: contextLocale } = useShopify();
435
510
  const locale = providedLocale || contextLocale;
436
511
  const [points_subscribe, set_points_subscribe] = useState(false);
437
512
  const giftProductsCache = useRef(null);
513
+ const effectiveCart = useMemo(() => {
514
+ if (lines && lines.length > 0) {
515
+ return createMockCartFromLines(lines, cart);
516
+ }
517
+ return cart;
518
+ }, [lines, cart]);
438
519
  useEffect(() => {
439
520
  if (locale === "au") {
440
521
  const isPointsSubscribe = Cookies5.get("points_subscribe");
@@ -456,14 +537,16 @@ var useScriptAutoFreeGift = ({
456
537
  upgrade_multiple2 = 1.2;
457
538
  upgrade_value2 = 40;
458
539
  }
459
- cart?.lineItems?.forEach(({ customAttributes }) => {
460
- customAttributes?.forEach(({ key, value }) => {
461
- if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
462
- if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
463
- });
464
- });
540
+ effectiveCart?.lineItems?.forEach(
541
+ ({ customAttributes }) => {
542
+ customAttributes?.forEach(({ key, value }) => {
543
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
544
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
545
+ });
546
+ }
547
+ );
465
548
  return [upgrade_multiple2, upgrade_value2];
466
- }, [cart?.lineItems, points_subscribe]);
549
+ }, [effectiveCart?.lineItems, points_subscribe]);
467
550
  const breakpoints = useMemo(() => {
468
551
  if (!isActivityAvailable) return [];
469
552
  return (campaign?.breakpoints || []).map((item) => ({
@@ -491,7 +574,7 @@ var useScriptAutoFreeGift = ({
491
574
  }, [giftHandles]);
492
575
  const involvedLines = useMemo(() => {
493
576
  if (!isActivityAvailable) return [];
494
- return (cart?.lineItems || []).filter((line) => {
577
+ return (effectiveCart?.lineItems || []).filter((line) => {
495
578
  const isNotGift = line?.totalAmount && Number(line.totalAmount) > 0 && line.customAttributes?.every(
496
579
  (item) => item.key !== _giveaway
497
580
  );
@@ -500,7 +583,7 @@ var useScriptAutoFreeGift = ({
500
583
  );
501
584
  return isNotGift && hasCampaignTag;
502
585
  });
503
- }, [cart?.lineItems, isActivityAvailable, _giveaway]);
586
+ }, [effectiveCart?.lineItems, isActivityAvailable, _giveaway]);
504
587
  const involvedSubTotal = useMemo(() => {
505
588
  if (!isActivityAvailable) return new Decimal2(0);
506
589
  return involvedLines.reduce((prev, item) => {
@@ -526,18 +609,24 @@ var useScriptAutoFreeGift = ({
526
609
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
527
610
  return [currentLevel, nextLevel];
528
611
  }, [breakpoints, involvedSubTotal, involvedLines.length]);
529
- const { data: giftProductsResult } = useSWR(shouldFetch ? giftHandles : null, async () => {
530
- const res = await getProductsByHandles(client, {
531
- handles: giftHandles,
532
- locale
533
- });
534
- const result = Array.isArray(res) ? res : [];
535
- giftProductsCache.current = {
536
- data: result,
537
- giftHandles: [...giftHandles]
538
- };
539
- return result;
540
- });
612
+ const { data: giftProductsResult } = useSWR(
613
+ shouldFetch ? giftHandles : null,
614
+ async () => {
615
+ const res = await getProductsByHandles(client, {
616
+ handles: giftHandles,
617
+ locale
618
+ });
619
+ const result = Array.isArray(res) ? res : [];
620
+ giftProductsCache.current = {
621
+ data: result,
622
+ giftHandles: [...giftHandles]
623
+ };
624
+ return result;
625
+ },
626
+ {
627
+ revalidateOnFocus: false
628
+ }
629
+ );
541
630
  const finalGiftProductsResult = useMemo(() => {
542
631
  if (giftProductsCache.current && !shouldFetch) {
543
632
  return giftProductsCache.current.data || void 0;
@@ -619,12 +708,10 @@ function useHasPlusMemberInCart({
619
708
  };
620
709
  }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
621
710
  }
622
-
623
- // src/hooks/cart/feature/use-cart-attributes.ts
624
711
  var getReferralAttributes = () => {
625
- const inviteCode = Cookies5.get("invite_code");
626
- const playModeId = Cookies5.get("playModeId");
627
- const popup = Cookies5.get("_popup");
712
+ const inviteCode = getLocalStorage("invite_code") || Cookies5.get("invite_code");
713
+ const playModeId = getLocalStorage("playModeId") || Cookies5.get("playModeId");
714
+ const popup = getLocalStorage("_popup") || Cookies5.get("_popup");
628
715
  if (inviteCode && playModeId) {
629
716
  return popup ? [
630
717
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -648,8 +735,6 @@ var useCartAttributes = ({
648
735
  memberSetting,
649
736
  cart
650
737
  });
651
- console.log("memberSetting", memberSetting);
652
- console.log("hasPlusMember", hasPlusMember);
653
738
  useEffect(() => {
654
739
  setCurrentUrl(window.location.href);
655
740
  }, []);
@@ -675,7 +760,7 @@ var useCartAttributes = ({
675
760
  return "new_user_login";
676
761
  }, [customer]);
677
762
  const memberAttributes = useMemo(() => {
678
- return [
763
+ const attributes = [
679
764
  {
680
765
  key: "_token",
681
766
  value: profile?.token
@@ -696,17 +781,28 @@ var useCartAttributes = ({
696
781
  value: profile?.token ? "true" : "false"
697
782
  }
698
783
  ];
784
+ if (profile?.token) {
785
+ attributes.push({
786
+ key: "_login_user",
787
+ value: "1"
788
+ });
789
+ }
790
+ return attributes;
699
791
  }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
700
792
  const functionAttributes = useMemo(() => {
701
- return [
702
- cart?.discountCodes && {
793
+ const hasFunctionEnvAttribute = cart?.lineItems.some(
794
+ (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
795
+ );
796
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
797
+ return hasFunctionEnvAttribute ? [
798
+ {
703
799
  key: "_discounts_function_env",
704
800
  value: JSON.stringify({
705
- discount_code: cart?.discountCodes.map((item) => item.code),
801
+ discount_code: discountCodes,
706
802
  user_tags: customer?.tags || []
707
803
  })
708
804
  }
709
- ];
805
+ ] : [];
710
806
  }, [cart]);
711
807
  const presellAttributes = useMemo(() => {
712
808
  return [
@@ -738,18 +834,50 @@ var useCartAttributes = ({
738
834
  }
739
835
  ];
740
836
  }, [currentUrl]);
837
+ const commonAttributes = useMemo(
838
+ () => [
839
+ ...memberAttributes,
840
+ ...functionAttributes,
841
+ ...presellAttributes,
842
+ ...weightAttributes,
843
+ ...trackingAttributes,
844
+ ...getReferralAttributes()
845
+ ].filter((item) => item?.value),
846
+ [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
847
+ );
848
+ const extraAttributesInCart = useMemo(() => {
849
+ const commonAttributeKeys = [
850
+ // member attributes
851
+ "_token",
852
+ "_member_type",
853
+ "_user_type",
854
+ "_is_login",
855
+ "_login_user",
856
+ // function attributes
857
+ "_discounts_function_env",
858
+ // presell attributes
859
+ "_presale",
860
+ // weight attributes
861
+ "_weight",
862
+ "_app_source_name",
863
+ // tracking attributes
864
+ "utm_params",
865
+ // referral attributes
866
+ "_invite_code",
867
+ "_play_mode_id",
868
+ "_popup"
869
+ ];
870
+ return cart?.customAttributes?.filter(
871
+ (item) => !commonAttributeKeys.includes(item.key)
872
+ ) || [];
873
+ }, [cart]);
741
874
  return useMemo(
742
875
  () => ({
743
- attributes: [
744
- ...memberAttributes,
745
- ...functionAttributes,
746
- ...presellAttributes,
747
- ...weightAttributes,
748
- ...trackingAttributes,
749
- ...getReferralAttributes()
750
- ].filter((item) => item?.value)
876
+ attributes: [...commonAttributes, ...extraAttributesInCart].filter(
877
+ (item) => item?.value
878
+ )
751
879
  }),
752
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
880
+ [commonAttributes, extraAttributesInCart]
753
881
  );
754
882
  };
755
883
  var useUpdateLineCodeAmountAttributes = ({
@@ -965,8 +1093,13 @@ function CartProvider({
965
1093
  const { attributes } = useCartAttributes({ profile, customer, cart, memberSetting });
966
1094
  useRequest(
967
1095
  () => {
968
- const newAttributes = [...attributes, ...customAttributes];
969
- const needUpdate = cart && !checkAttributesUpdateNeeded(
1096
+ const newAttributes = [...attributes];
1097
+ customAttributes.forEach((item) => {
1098
+ if (item.value && !newAttributes.some((attr) => attr.key === item.key)) {
1099
+ newAttributes.push(item);
1100
+ }
1101
+ });
1102
+ const needUpdate = cart && checkAttributesUpdateNeeded(
970
1103
  cart.customAttributes,
971
1104
  newAttributes,
972
1105
  customAttributesNeedDelete
@@ -1070,8 +1203,14 @@ function CartProvider({
1070
1203
  );
1071
1204
  return result;
1072
1205
  }, [cart?.lineItems, scriptAutoFreeGift, functionAutoFreeGift]);
1206
+ const totalQuantity = useMemo(() => {
1207
+ const cartLinesCount = cart?.lineItems.reduce((acc, item) => acc + item.quantity, 0) || 0;
1208
+ const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
1209
+ return cartLinesCount + giftLinesCount;
1210
+ }, [cart?.lineItems, giftNeedAddToCartLines]);
1073
1211
  const value = useMemo(
1074
1212
  () => ({
1213
+ totalQuantity,
1075
1214
  cart,
1076
1215
  isCartLoading,
1077
1216
  triggerFetch: fetchCart,
@@ -1083,6 +1222,7 @@ function CartProvider({
1083
1222
  isCodeChanging,
1084
1223
  setIsCodeChanging,
1085
1224
  autoFreeGiftConfig,
1225
+ gradientGiftsConfig,
1086
1226
  setLoadingState,
1087
1227
  loadingState,
1088
1228
  // function满赠
@@ -1098,6 +1238,7 @@ function CartProvider({
1098
1238
  }),
1099
1239
  [
1100
1240
  cart,
1241
+ totalQuantity,
1101
1242
  isCartLoading,
1102
1243
  fetchCart,
1103
1244
  mutateCart,
@@ -1106,6 +1247,7 @@ function CartProvider({
1106
1247
  locale,
1107
1248
  isCodeChanging,
1108
1249
  autoFreeGiftConfig,
1250
+ gradientGiftsConfig,
1109
1251
  loadingState,
1110
1252
  // function满赠
1111
1253
  functionAutoFreeGift,