@anker-in/shopify-react 0.1.1-beta.5 → 0.1.1-beta.50

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.
@@ -6,6 +6,7 @@ var shopifySdk = require('@anker-in/shopify-sdk');
6
6
  var Cookies5 = require('js-cookie');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
  var Decimal2 = require('decimal.js');
9
+ var shopifyCore = require('@anker-in/shopify-core');
9
10
  var useSWR = require('swr');
10
11
  var ahooks = require('ahooks');
11
12
 
@@ -69,6 +70,7 @@ var CUSTOMER_ATTRIBUTE_KEY = "_discounts_function_env";
69
70
  var CUSTOMER_SCRIPT_GIFT_KEY = "_giveaway_gradient_gifts";
70
71
  var CODE_AMOUNT_KEY = "_sku_code_money";
71
72
  var SCRIPT_CODE_AMOUNT_KEY = "_code_money";
73
+ var MEMBER_PRICE_ATTRIBUTE_KEY = "_member_price";
72
74
  var MAIN_PRODUCT_CODE = ["WS24", "WSTD", "WS7D", "WSCP", "WSPE", "WSPD"];
73
75
 
74
76
  // src/hooks/cart/utils/normalize-add-to-cart-lines.ts
@@ -77,9 +79,10 @@ function normalizeAddToCartLines(lines) {
77
79
  const variant = line.variant;
78
80
  const product = variant.product;
79
81
  const quantity = line.quantity || 1;
80
- const price = variant.finalPrice?.amount ? Number(variant.finalPrice.amount) : variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : variant.price?.amount ? Number(variant.price.amount) : 0;
81
- const subtotalAmount = price * quantity;
82
- const totalAmount = subtotalAmount;
82
+ const originalPrice = variant.price?.amount ? Number(variant.price.amount) : 0;
83
+ const finalPrice = variant.finalPrice?.amount === void 0 ? originalPrice : Number(variant.finalPrice?.amount);
84
+ const subtotalAmount = originalPrice * quantity;
85
+ const totalAmount = finalPrice * quantity;
83
86
  return {
84
87
  id: `temp-line-${index}-${variant.id}`,
85
88
  // Temporary ID for pre-cart lines
@@ -93,7 +96,7 @@ function normalizeAddToCartLines(lines) {
93
96
  customAttributes: line.attributes || [],
94
97
  variant: {
95
98
  id: variant.id,
96
- price,
99
+ price: finalPrice,
97
100
  listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
98
101
  sku: variant.sku || "",
99
102
  name: variant.title || "",
@@ -124,15 +127,16 @@ function createMockCartFromLines(lines, existingCart) {
124
127
  const normalizedLines = normalizeAddToCartLines(lines);
125
128
  const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
126
129
  const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
130
+ const currency = lines[0]?.variant?.price?.currencyCode;
127
131
  return {
128
132
  id: existingCart?.id || "temp-cart-id",
129
133
  customerId: existingCart?.customerId,
130
134
  email: existingCart?.email,
131
135
  createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
132
- currency: existingCart?.currency || { code: "USD" },
136
+ currency: existingCart?.currency || { code: currency },
133
137
  taxesIncluded: existingCart?.taxesIncluded,
134
138
  lineItems: normalizedLines,
135
- totallineItemsDiscount: 0,
139
+ totalLineItemsDiscount: 0,
136
140
  orderDiscounts: 0,
137
141
  lineItemsSubtotalPrice: subtotalPrice,
138
142
  subtotalPrice,
@@ -163,22 +167,12 @@ var getQuery = () => {
163
167
  }
164
168
  return theRequest;
165
169
  };
166
- function atobID(id) {
167
- if (id && typeof id === "string" && id.includes("/")) {
168
- return id.split("/").pop()?.split("?")?.shift();
169
- } else {
170
- return id;
171
- }
172
- }
173
- function btoaID(id, type = "ProductVariant") {
174
- return `gid://shopify/${type}/${id}`;
175
- }
176
170
  var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
177
171
  const isAllStoreVariant = main_product?.all_store_variant ?? false;
178
172
  const matchedList = cartData?.lineItems?.filter((line) => {
179
173
  const { is_gift } = getDiscountEnvAttributeValue(line.customAttributes);
180
174
  return isAllStoreVariant ? !is_gift : variant_list?.find((item) => {
181
- return !is_gift && atobID(line.variantId) === item;
175
+ return !is_gift && shopifyCore.atobID(line.variantId) === item;
182
176
  });
183
177
  });
184
178
  return matchedList?.reduce((acc, line) => {
@@ -196,14 +190,6 @@ var getDiscountEnvAttributeValue = (attributes = []) => {
196
190
  const attr = attributes.find((attr2) => attr2.key === CUSTOMER_ATTRIBUTE_KEY);
197
191
  return safeParse(attr?.value ?? "") ?? {};
198
192
  };
199
- var checkAttributesUpdateNeeded = (oldAttributes, newAttributes, customAttributesNeedRemove) => {
200
- return oldAttributes.some((attr) => {
201
- const newAttr = newAttributes.find((newAttr2) => newAttr2.key === attr.key);
202
- return newAttr ? newAttr.value !== attr.value : true;
203
- }) || newAttributes.some((attr) => !oldAttributes.some((oldAttr) => oldAttr.key === attr.key)) || customAttributesNeedRemove.some(
204
- (removeAttr) => oldAttributes.some((oldAttr) => oldAttr.key === removeAttr.key)
205
- );
206
- };
207
193
  var containsAll = (source, requiredItems = []) => {
208
194
  if (!requiredItems?.length) return true;
209
195
  const sourceSet = new Set(source);
@@ -404,43 +390,29 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
404
390
  }
405
391
  return { activeCampaign: null, subtotal: 0 };
406
392
  }, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
407
- const { qualifyingGift, nextTierGoal } = react.useMemo(() => {
393
+ const { qualifyingTier, nextTierGoal, actualThreshold, currentCurrency } = react.useMemo(() => {
408
394
  if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
409
- return { qualifyingGift: null, nextTierGoal: null };
395
+ return { qualifyingTier: null, nextTierGoal: null, actualThreshold: 0, currentCurrency: "" };
410
396
  }
411
397
  const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
412
- const qualifyingTier = [...giftTiers].sort((a, b) => Number(b.spend_sum_money) - Number(a.spend_sum_money)).find((tier) => subtotal >= Number(tier.spend_sum_money));
413
- const nextGoal = giftTiers.find((tier) => subtotal < Number(tier.spend_sum_money));
414
- if (!qualifyingTier) {
415
- return { qualifyingGift: null, nextTierGoal: nextGoal || null };
416
- }
417
- const formattedGift = {
418
- tier: qualifyingTier,
419
- itemsToAdd: qualifyingTier.reward_list?.map((reward) => {
420
- const giftProduct = reward?.variant_list?.[0];
421
- if (!giftProduct) return null;
422
- return {
423
- variant: {
424
- id: btoaID(giftProduct.variant_id),
425
- handle: giftProduct.handle,
426
- sku: giftProduct.sku
427
- },
428
- quantity: reward?.get_unit || 1,
429
- attributes: [
430
- {
431
- key: CUSTOMER_ATTRIBUTE_KEY,
432
- value: JSON.stringify({
433
- is_gift: true,
434
- rule_id: activeCampaign.rule_id,
435
- spend_sum_money: qualifyingTier.spend_sum_money
436
- })
437
- }
438
- ]
439
- };
440
- }).filter((item) => item !== null)
398
+ const currentCurrency2 = effectiveCart?.currency?.code || "";
399
+ console.log("currentCurrency useCalcAutoFreeGift", effectiveCart, currentCurrency2);
400
+ const getThresholdAmount = (tier) => {
401
+ if (tier.spend_sum_money_multi_markets?.[currentCurrency2]?.value) {
402
+ return Number(tier.spend_sum_money_multi_markets[currentCurrency2].value);
403
+ }
404
+ return Number(tier.spend_sum_money || 0);
441
405
  };
442
- return { qualifyingGift: formattedGift, nextTierGoal: nextGoal || null };
443
- }, [activeCampaign, subtotal]);
406
+ const qualifyingTier2 = [...giftTiers].sort((a, b) => getThresholdAmount(b) - getThresholdAmount(a)).find((tier) => subtotal >= getThresholdAmount(tier));
407
+ const nextGoal = giftTiers.find((tier) => subtotal < getThresholdAmount(tier));
408
+ const actualThreshold2 = qualifyingTier2 ? getThresholdAmount(qualifyingTier2) : 0;
409
+ return {
410
+ qualifyingTier: qualifyingTier2,
411
+ nextTierGoal: nextGoal || null,
412
+ actualThreshold: actualThreshold2,
413
+ currentCurrency: currentCurrency2
414
+ };
415
+ }, [activeCampaign, subtotal, effectiveCart]);
444
416
  const giftHandles = react.useMemo(() => {
445
417
  const giftVariant = autoFreeGiftConfig.map(
446
418
  (item) => item.rule_result?.spend_get_reward?.gift_product?.map(
@@ -456,24 +428,82 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
456
428
  }
457
429
  return true;
458
430
  }, [giftHandles]);
459
- const { data: giftProductsResult } = useSWR__default.default(shouldFetch ? giftHandles : null, async () => {
460
- const res = await shopifySdk.getProductsByHandles(client, {
461
- handles: giftHandles,
462
- locale
463
- });
464
- const result = Array.isArray(res) ? res : [];
465
- giftProductsCache.current = {
466
- data: result,
467
- giftHandles: [...giftHandles]
468
- };
469
- return result;
470
- });
431
+ const { data: giftProductsResult } = useSWR__default.default(
432
+ shouldFetch ? giftHandles : null,
433
+ async () => {
434
+ const res = await shopifySdk.getProductsByHandles(client, {
435
+ handles: giftHandles,
436
+ locale
437
+ });
438
+ const result = Array.isArray(res) ? res : [];
439
+ giftProductsCache.current = {
440
+ data: result,
441
+ giftHandles: [...giftHandles]
442
+ };
443
+ return result;
444
+ },
445
+ {
446
+ revalidateOnFocus: false
447
+ }
448
+ );
471
449
  const finalGiftProductsResult = react.useMemo(() => {
472
450
  if (giftProductsCache.current && !shouldFetch) {
473
451
  return giftProductsCache.current.data || void 0;
474
452
  }
475
453
  return giftProductsResult;
476
454
  }, [giftProductsResult, shouldFetch]);
455
+ const qualifyingGift = react.useMemo(() => {
456
+ if (!qualifyingTier || !activeCampaign) {
457
+ return null;
458
+ }
459
+ const itemsToAdd = qualifyingTier.reward_list?.map((reward) => {
460
+ if (!reward.variant_list || reward.variant_list.length === 0) {
461
+ return null;
462
+ }
463
+ let selectedGiftProduct = null;
464
+ for (const giftVariant of reward.variant_list) {
465
+ const productInfo = finalGiftProductsResult?.find(
466
+ (p) => p.handle === giftVariant.handle
467
+ );
468
+ if (productInfo) {
469
+ const variantInfo = productInfo.variants?.find((v) => v.sku === giftVariant.sku);
470
+ if (variantInfo?.availableForSale) {
471
+ selectedGiftProduct = giftVariant;
472
+ break;
473
+ }
474
+ }
475
+ }
476
+ if (!selectedGiftProduct) {
477
+ selectedGiftProduct = reward.variant_list[0];
478
+ }
479
+ return {
480
+ variant: {
481
+ id: shopifyCore.btoaID(selectedGiftProduct.variant_id),
482
+ handle: selectedGiftProduct.handle,
483
+ sku: selectedGiftProduct.sku
484
+ },
485
+ quantity: reward?.get_unit || 1,
486
+ attributes: [
487
+ {
488
+ key: CUSTOMER_ATTRIBUTE_KEY,
489
+ value: JSON.stringify({
490
+ is_gift: true,
491
+ rule_id: activeCampaign.rule_id,
492
+ spend_sum_money: actualThreshold,
493
+ // 使用实际的门槛金额(多币种支持)
494
+ currency_code: currentCurrency
495
+ // 记录当前币种
496
+ })
497
+ }
498
+ ]
499
+ };
500
+ }).filter((item) => item !== null);
501
+ const formattedGift = {
502
+ tier: qualifyingTier,
503
+ itemsToAdd
504
+ };
505
+ return formattedGift;
506
+ }, [qualifyingTier, activeCampaign, finalGiftProductsResult, actualThreshold, currentCurrency]);
477
507
  return {
478
508
  qualifyingGift,
479
509
  nextTierGoal,
@@ -487,7 +517,8 @@ var useScriptAutoFreeGift = ({
487
517
  _giveaway,
488
518
  cart,
489
519
  locale: providedLocale,
490
- lines
520
+ lines,
521
+ profile
491
522
  }) => {
492
523
  const { client, locale: contextLocale } = useShopify();
493
524
  const locale = providedLocale || contextLocale;
@@ -511,8 +542,9 @@ var useScriptAutoFreeGift = ({
511
542
  const utmCampaign = Cookies5__default.default.get("utm_campaign") || query?.utm_campaign;
512
543
  if (campaign.activityAvailableQuery && !utmCampaign?.includes(campaign.activityAvailableQuery))
513
544
  return false;
545
+ if (campaign.requireLogin && !profile?.email) return false;
514
546
  return true;
515
- }, [campaign]);
547
+ }, [campaign, profile]);
516
548
  const [upgrade_multiple, upgrade_value] = react.useMemo(() => {
517
549
  let upgrade_multiple2 = 1;
518
550
  let upgrade_value2 = 0;
@@ -520,12 +552,14 @@ var useScriptAutoFreeGift = ({
520
552
  upgrade_multiple2 = 1.2;
521
553
  upgrade_value2 = 40;
522
554
  }
523
- effectiveCart?.lineItems?.forEach(({ customAttributes }) => {
524
- customAttributes?.forEach(({ key, value }) => {
525
- if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
526
- if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
527
- });
528
- });
555
+ effectiveCart?.lineItems?.forEach(
556
+ ({ customAttributes }) => {
557
+ customAttributes?.forEach(({ key, value }) => {
558
+ if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
559
+ if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
560
+ });
561
+ }
562
+ );
529
563
  return [upgrade_multiple2, upgrade_value2];
530
564
  }, [effectiveCart?.lineItems, points_subscribe]);
531
565
  const breakpoints = react.useMemo(() => {
@@ -590,18 +624,24 @@ var useScriptAutoFreeGift = ({
590
624
  const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
591
625
  return [currentLevel, nextLevel];
592
626
  }, [breakpoints, involvedSubTotal, involvedLines.length]);
593
- const { data: giftProductsResult } = useSWR__default.default(shouldFetch ? giftHandles : null, async () => {
594
- const res = await shopifySdk.getProductsByHandles(client, {
595
- handles: giftHandles,
596
- locale
597
- });
598
- const result = Array.isArray(res) ? res : [];
599
- giftProductsCache.current = {
600
- data: result,
601
- giftHandles: [...giftHandles]
602
- };
603
- return result;
604
- });
627
+ const { data: giftProductsResult } = useSWR__default.default(
628
+ shouldFetch ? giftHandles : null,
629
+ async () => {
630
+ const res = await shopifySdk.getProductsByHandles(client, {
631
+ handles: giftHandles,
632
+ locale
633
+ });
634
+ const result = Array.isArray(res) ? res : [];
635
+ giftProductsCache.current = {
636
+ data: result,
637
+ giftHandles: [...giftHandles]
638
+ };
639
+ return result;
640
+ },
641
+ {
642
+ revalidateOnFocus: false
643
+ }
644
+ );
605
645
  const finalGiftProductsResult = react.useMemo(() => {
606
646
  if (giftProductsCache.current && !shouldFetch) {
607
647
  return giftProductsCache.current.data || void 0;
@@ -634,16 +674,19 @@ var useScriptAutoFreeGift = ({
634
674
  };
635
675
  };
636
676
  var CartContext = react.createContext(null);
637
- function useCartContext() {
677
+ function useCartContext(options) {
638
678
  const context = react.useContext(CartContext);
639
- if (!context) {
679
+ if (!context && true) {
640
680
  throw new Error("useCartContext must be used within a CartProvider");
641
681
  }
642
682
  return context;
643
683
  }
644
684
 
645
685
  // src/hooks/cart/use-create-cart.ts
646
- function useCreateCart(options) {
686
+ function useCreateCart({
687
+ updateCookie = false,
688
+ options
689
+ }) {
647
690
  const { client, locale, cartCookieAdapter } = useShopify();
648
691
  const { mutateCart, metafieldIdentifiers } = useCartContext();
649
692
  const createNewCart = react.useCallback(
@@ -651,7 +694,8 @@ function useCreateCart(options) {
651
694
  let newCart = await shopifySdk.createCart(client, {
652
695
  ...arg,
653
696
  metafieldIdentifiers,
654
- cookieAdapter: cartCookieAdapter
697
+ cookieAdapter: cartCookieAdapter,
698
+ updateCookie
655
699
  });
656
700
  if (newCart) {
657
701
  const unApplicableCodes = newCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
@@ -678,11 +722,23 @@ function useAddCartLines(options) {
678
722
  const { mutateCart, metafieldIdentifiers } = useCartContext();
679
723
  const addLines = react.useCallback(
680
724
  async (_key, { arg }) => {
681
- let updatedCart = await shopifySdk.addCartLines(client, {
682
- ...arg,
683
- metafieldIdentifiers,
684
- cookieAdapter: cartCookieAdapter
685
- });
725
+ const { cartId, lines } = arg;
726
+ const id = cartId || cartCookieAdapter?.getCartId(locale);
727
+ let updatedCart;
728
+ if (!id) {
729
+ updatedCart = await shopifySdk.createCart(client, {
730
+ lines,
731
+ metafieldIdentifiers,
732
+ cookieAdapter: cartCookieAdapter
733
+ });
734
+ } else {
735
+ updatedCart = await shopifySdk.addCartLines(client, {
736
+ cartId: id,
737
+ lines,
738
+ metafieldIdentifiers,
739
+ cookieAdapter: cartCookieAdapter
740
+ });
741
+ }
686
742
  if (updatedCart) {
687
743
  const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
688
744
  if (unApplicableCodes.length > 0) {
@@ -729,7 +785,7 @@ var trackAddToCartGA = ({
729
785
  const currencyCode = variant.product?.price?.currencyCode;
730
786
  const totalPrice = lineItems?.reduce(
731
787
  (prev, { variant: variant2 }) => prev.plus(
732
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? variant2?.price?.amount ?? 0
788
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
733
789
  ),
734
790
  new Decimal2__default.default(0)
735
791
  ).toNumber();
@@ -762,10 +818,10 @@ var trackBuyNowGA = ({
762
818
  return;
763
819
  }
764
820
  const { variant } = lineItems[0];
765
- const currencyCode = variant.price?.currencyCode;
821
+ const currencyCode = variant.product?.price?.currencyCode || variant.price?.currencyCode;
766
822
  const totalPrice = lineItems?.reduce(
767
823
  (prev, { variant: variant2 }) => prev.plus(
768
- variant2?.finalPrice?.amount ?? variant2?.compareAtPrice?.amount ?? (variant2?.price?.amount || 0)
824
+ variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
769
825
  ),
770
826
  new Decimal2__default.default(0)
771
827
  ).toNumber();
@@ -839,7 +895,7 @@ function useApplyCartCodes(options) {
839
895
  if (!discountCodes?.length) {
840
896
  throw new Error("Invalid input used for this operation: Miss discountCode");
841
897
  }
842
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
898
+ const cartId = providedCartId || cart?.id;
843
899
  if (!cartId) {
844
900
  return void 0;
845
901
  }
@@ -852,12 +908,18 @@ function useApplyCartCodes(options) {
852
908
  cookieAdapter: cartCookieAdapter,
853
909
  metafieldIdentifiers
854
910
  });
911
+ const unApplicableCodes = discountCodes.filter(
912
+ (code) => updatedCart?.discountCodes?.find((item) => item.code === code && !item.applicable)
913
+ );
914
+ if (unApplicableCodes.length) {
915
+ throw new Error(`${unApplicableCodes.join(", ")} is not applicable to the cart`);
916
+ }
855
917
  if (updatedCart) {
856
918
  mutateCart(updatedCart);
857
919
  }
858
920
  return updatedCart;
859
921
  },
860
- [client, locale, cartCookieAdapter, mutateCart, cart]
922
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
861
923
  );
862
924
  return useSWRMutation__default.default("apply-codes", applyCodes, options);
863
925
  }
@@ -867,7 +929,7 @@ function useRemoveCartCodes(options) {
867
929
  const removeCodes = react.useCallback(
868
930
  async (_key, { arg }) => {
869
931
  const { cartId: providedCartId, discountCodes } = arg;
870
- const cartId = providedCartId ? void 0 : providedCartId || cart?.id;
932
+ const cartId = providedCartId || cart?.id;
871
933
  const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
872
934
  const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
873
935
  const updatedCart = await shopifySdk.updateCartCodes(client, {
@@ -881,225 +943,96 @@ function useRemoveCartCodes(options) {
881
943
  }
882
944
  return updatedCart;
883
945
  },
884
- [client, locale, cartCookieAdapter, mutateCart, cart]
946
+ [client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
885
947
  );
886
948
  return useSWRMutation__default.default("remove-codes", removeCodes, options);
887
949
  }
888
-
889
- // src/hooks/cart/use-add-to-cart.ts
890
- function useAddToCart({ withTrack = true } = {}, swrOptions) {
891
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
892
- const { cart } = useCartContext();
893
- const { trigger: applyCartCodes } = useApplyCartCodes();
894
- const { trigger: removeInvalidCodes } = useRemoveCartCodes();
895
- const { trigger: addCartLines2 } = useAddCartLines();
896
- const addToCart = react.useCallback(
897
- async (_key, { arg }) => {
898
- const {
899
- lineItems,
900
- cartId: providedCartId,
901
- discountCodes,
902
- gtmParams = {},
903
- buyerIdentity,
904
- needCreateCart = false,
905
- onCodesInvalid,
906
- replaceExistingCodes
907
- } = arg;
908
- if (!lineItems || lineItems.length === 0) {
909
- return;
910
- }
911
- const lines = lineItems.map((item) => ({
912
- merchandiseId: item.variant?.id || "",
913
- quantity: item.quantity || 1,
914
- attributes: item.attributes,
915
- sellingPlanId: item.sellingPlanId
916
- })).filter((item) => item.merchandiseId && item.quantity);
917
- if (lines.length === 0) {
918
- return;
919
- }
920
- const cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
921
- let resultCart = await addCartLines2({
922
- cartId,
923
- lines,
924
- buyerIdentity
925
- });
926
- if (!resultCart) {
927
- return void 0;
928
- }
929
- console.log("npm addCartLines resultCart", resultCart);
930
- if (resultCart.discountCodes && resultCart.discountCodes.length > 0) {
931
- const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
932
- if (unapplicableCodes.length > 0) {
933
- if (onCodesInvalid) {
934
- const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
935
- if (handledCart) {
936
- resultCart = handledCart;
937
- }
938
- } else {
939
- await removeInvalidCodes({
940
- discountCodes: unapplicableCodes
941
- });
942
- }
943
- }
944
- }
945
- if (discountCodes && discountCodes.length > 0) {
946
- applyCartCodes({
947
- replaceExistingCodes,
948
- discountCodes
949
- });
950
- }
951
- if (withTrack) {
952
- trackAddToCartGA({
953
- lineItems,
954
- gtmParams: { ...gtmParams, brand: config.getBrand() }
955
- });
956
- trackAddToCartFBQ({ lineItems });
957
- }
958
- return resultCart;
959
- },
960
- [client, locale, cartCookieAdapter, userAdapter, cart, withTrack]
950
+ var initSameLinesAttributes = ({
951
+ cart,
952
+ line
953
+ }) => {
954
+ const sameLineInCart = cart?.lineItems.find(
955
+ (lineInCart) => lineInCart.variant.sku === line.variant?.sku && lineInCart.product?.handle === line.variant?.product?.handle
961
956
  );
962
- return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
963
- }
964
- function useUpdateCartLines(options) {
965
- const { client, locale, cartCookieAdapter } = useShopify();
966
- const { mutateCart, metafieldIdentifiers } = useCartContext();
967
- const updateLines = react.useCallback(
968
- async (_key, { arg }) => {
969
- const updatedCart = await shopifySdk.updateCartLines(client, {
970
- ...arg,
971
- metafieldIdentifiers,
972
- cookieAdapter: cartCookieAdapter
973
- });
974
- if (updatedCart) {
975
- mutateCart(updatedCart);
976
- }
977
- return updatedCart;
978
- },
979
- [client, locale, cartCookieAdapter, mutateCart]
957
+ const codeAmountAttribute = sameLineInCart?.customAttributes?.find(
958
+ (attr) => attr.key === CODE_AMOUNT_KEY
980
959
  );
981
- return useSWRMutation__default.default("update-cart-lines", updateLines, options);
982
- }
983
- function useRemoveCartLines(options) {
984
- const { client, locale, cartCookieAdapter } = useShopify();
985
- const { mutateCart, metafieldIdentifiers } = useCartContext();
986
- const removeLines = react.useCallback(
987
- async (_key, { arg }) => {
988
- const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
989
- let updatedCart = await shopifySdk.removeCartLines(client, {
990
- cartId,
991
- lineIds,
992
- metafieldIdentifiers,
993
- cookieAdapter: cartCookieAdapter
994
- });
995
- if (updatedCart && autoRemoveInvalidCodes) {
996
- const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
997
- if (unApplicableCodes.length > 0) {
998
- if (onCodesRemoved) {
999
- const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1000
- if (handledCart) {
1001
- updatedCart = handledCart;
1002
- }
1003
- } else {
1004
- updatedCart = await shopifySdk.updateCartCodes(client, {
1005
- cartId: updatedCart.id,
1006
- discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1007
- metafieldIdentifiers,
1008
- cookieAdapter: cartCookieAdapter
1009
- }) || updatedCart;
1010
- }
1011
- }
1012
- }
1013
- if (updatedCart) {
1014
- mutateCart(updatedCart);
1015
- }
1016
- return updatedCart;
1017
- },
1018
- [client, locale, cartCookieAdapter, mutateCart]
960
+ const scriptCodeAmountAttribute = sameLineInCart?.customAttributes?.find(
961
+ (attr) => attr.key === SCRIPT_CODE_AMOUNT_KEY
1019
962
  );
1020
- return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
1021
- }
1022
- function useUpdateCartAttributes(mutate, metafieldIdentifiers, options) {
1023
- const { client, locale, cartCookieAdapter } = useShopify();
1024
- const updateAttributes = react.useCallback(
1025
- async (_key, { arg }) => {
1026
- const updatedCart = await shopifySdk.updateCartAttributes(client, {
1027
- ...arg,
1028
- metafieldIdentifiers,
1029
- cookieAdapter: cartCookieAdapter
1030
- });
1031
- console.log("useUpdateCartAttributes updatedCart", updatedCart);
1032
- if (updatedCart) {
1033
- mutate(updatedCart);
963
+ let functionAttribute = null;
964
+ try {
965
+ functionAttribute = sameLineInCart?.customAttributes?.find(
966
+ (attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY && JSON.parse(attr.value)?.discounted_amount
967
+ );
968
+ } catch (error) {
969
+ }
970
+ if (codeAmountAttribute || functionAttribute || scriptCodeAmountAttribute) {
971
+ return {
972
+ ...line,
973
+ attributes: [
974
+ ...line.attributes || [],
975
+ codeAmountAttribute,
976
+ functionAttribute,
977
+ scriptCodeAmountAttribute
978
+ ].filter(Boolean)
979
+ };
980
+ }
981
+ return line;
982
+ };
983
+ var initDiscountAttributes = ({ line }) => {
984
+ let itemAttributes = line.attributes || [];
985
+ const functionEnvAttribute = itemAttributes.find((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY);
986
+ if (!functionEnvAttribute) {
987
+ itemAttributes = itemAttributes.concat([
988
+ {
989
+ key: CUSTOMER_ATTRIBUTE_KEY,
990
+ value: JSON.stringify({
991
+ is_gift: false,
992
+ discounted_amount: line.variant?.finalPrice?.amount === void 0 ? Number(line.variant?.price?.amount) * (line.quantity || 1) : Number(line.variant?.finalPrice?.amount) * (line.quantity || 1)
993
+ })
1034
994
  }
1035
- return updatedCart;
1036
- },
1037
- [client, locale, cartCookieAdapter, mutate]
995
+ ]);
996
+ }
997
+ const memberPriceAttribute = itemAttributes.find(
998
+ (attr) => attr.key === MEMBER_PRICE_ATTRIBUTE_KEY
1038
999
  );
1039
- return useSWRMutation__default.default("update-cart-attributes", updateAttributes, options);
1040
- }
1041
- function useBuyNow({ withTrack = true } = {}, swrOptions) {
1042
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
1043
- const isLoggedIn = userAdapter?.isLoggedIn || false;
1044
- const buyNow = react.useCallback(
1045
- async (_key, { arg }) => {
1046
- const {
1047
- lineItems,
1048
- discountCodes,
1049
- gtmParams = {},
1050
- buyerIdentity,
1051
- fbqTrackConfig,
1052
- customAttributes,
1053
- metafieldIdentifiers,
1054
- redirectToCheckout
1055
- } = arg;
1056
- if (!lineItems || lineItems.length === 0) {
1057
- return;
1000
+ const coupon = line.coupon;
1001
+ if (!memberPriceAttribute && coupon) {
1002
+ itemAttributes = itemAttributes.concat([
1003
+ {
1004
+ key: MEMBER_PRICE_ATTRIBUTE_KEY,
1005
+ value: JSON.stringify({ code: coupon.code })
1058
1006
  }
1059
- const lines = lineItems.map((item) => ({
1060
- merchandiseId: item.variant?.id || "",
1061
- quantity: item.quantity || 1,
1062
- attributes: item.attributes,
1063
- sellingPlanId: item.sellingPlanId
1064
- })).filter((item) => item.merchandiseId && item.quantity);
1065
- if (lines.length === 0) {
1066
- return;
1007
+ ]);
1008
+ }
1009
+ const couponDiscountAttribute = itemAttributes.find(
1010
+ (attr) => attr.key === CODE_AMOUNT_KEY || attr.key === SCRIPT_CODE_AMOUNT_KEY
1011
+ );
1012
+ if (!couponDiscountAttribute && coupon && Number(coupon?.amount) > 0) {
1013
+ itemAttributes = itemAttributes.concat([
1014
+ {
1015
+ key: CODE_AMOUNT_KEY,
1016
+ value: new Decimal2__default.default(coupon.amount).times(line.quantity || 1).toString()
1017
+ },
1018
+ {
1019
+ key: SCRIPT_CODE_AMOUNT_KEY,
1020
+ value: new Decimal2__default.default(coupon.amount).times(line.quantity || 1).toString()
1067
1021
  }
1068
- const resultCart = await shopifySdk.createCart(client, {
1069
- lines,
1070
- metafieldIdentifiers,
1071
- cookieAdapter: cartCookieAdapter,
1072
- buyerIdentity,
1073
- discountCodes,
1074
- customAttributes
1075
- });
1076
- if (!resultCart) {
1077
- throw new Error("Failed to create cart for buy now");
1078
- }
1079
- if (withTrack && resultCart.lineItems) {
1080
- trackBuyNowGA({
1081
- lineItems,
1082
- gtmParams: { ...gtmParams, brand: config.getBrand() }
1083
- });
1084
- if (fbqTrackConfig) {
1085
- trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
1086
- }
1087
- }
1088
- if (redirectToCheckout) {
1089
- if (resultCart.url) {
1090
- if (typeof window !== "undefined") {
1091
- window.location.href = resultCart.url;
1092
- }
1093
- } else {
1094
- throw new Error("Failed to get checkout URL");
1095
- }
1096
- }
1097
- return resultCart;
1098
- },
1099
- [client, locale, isLoggedIn, cartCookieAdapter, withTrack]
1100
- );
1101
- return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
1102
- }
1022
+ ]);
1023
+ }
1024
+ return { ...line, attributes: itemAttributes };
1025
+ };
1026
+ var getLinesWithAttributes = ({
1027
+ cart,
1028
+ lineItems
1029
+ }) => {
1030
+ return lineItems.map((line) => {
1031
+ const sameLine = initSameLinesAttributes({ cart, line });
1032
+ const functionLine = initDiscountAttributes({ line: sameLine });
1033
+ return functionLine;
1034
+ });
1035
+ };
1103
1036
  function useCalcGiftsFromLines({
1104
1037
  lines,
1105
1038
  customer,
@@ -1116,17 +1049,41 @@ function useCalcGiftsFromLines({
1116
1049
  lines
1117
1050
  });
1118
1051
  const allGiftLines = react.useMemo(() => {
1119
- const functionGiftLines = functionGift.qualifyingGift?.itemsToAdd || [];
1120
- const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((product) => {
1121
- const giftProduct = scriptGift.giftProductsResult?.find(
1122
- (p) => p.handle === product.handle
1052
+ const functionGiftLines = (functionGift.qualifyingGift?.itemsToAdd || []).map((item) => {
1053
+ const product = functionGift.giftProductsResult?.find(
1054
+ (product2) => product2.handle === item.variant.handle
1055
+ );
1056
+ const variants = product?.variants;
1057
+ const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.variant.sku) : void 0;
1058
+ if (!variant) {
1059
+ console.warn(
1060
+ `Function gift: Variant not found for handle=${item.variant.handle}, sku=${item.variant.sku}`
1061
+ );
1062
+ return null;
1063
+ }
1064
+ return {
1065
+ variant: {
1066
+ ...variant,
1067
+ product
1068
+ },
1069
+ quantity: item.quantity ?? 1,
1070
+ attributes: item.attributes
1071
+ };
1072
+ }).filter((item) => item !== null);
1073
+ const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((item) => {
1074
+ const product = scriptGift.giftProductsResult?.find(
1075
+ (product2) => product2.handle === item.handle
1123
1076
  );
1124
- const variant = giftProduct?.variants?.[0];
1077
+ const variants = product?.variants;
1078
+ const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.sku) : void 0;
1079
+ if (!variant) {
1080
+ console.warn(`Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`);
1081
+ return null;
1082
+ }
1125
1083
  return {
1126
1084
  variant: {
1127
- id: variant?.id || "",
1128
- handle: product.handle,
1129
- sku: product.sku
1085
+ ...variant,
1086
+ product
1130
1087
  },
1131
1088
  quantity: 1,
1132
1089
  attributes: [
@@ -1136,10 +1093,11 @@ function useCalcGiftsFromLines({
1136
1093
  }
1137
1094
  ]
1138
1095
  };
1139
- }).filter((item) => item.variant.id) : [];
1096
+ }).filter((item) => item !== null) : [];
1140
1097
  return [...functionGiftLines, ...scriptGiftLines];
1141
1098
  }, [
1142
1099
  functionGift.qualifyingGift,
1100
+ functionGift.giftProductsResult,
1143
1101
  scriptGift.freeGiftLevel,
1144
1102
  scriptGift.giftProductsResult,
1145
1103
  scriptGiveawayKey
@@ -1174,7 +1132,7 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1174
1132
  const isCustomerLoading = react.useMemo(() => !customer ? true : false, [customer]);
1175
1133
  const dealsType = "";
1176
1134
  const { activeCampaign, subtotal } = react.useMemo(() => {
1177
- for (const campaign of orderDiscountConfig) {
1135
+ for (const campaign of orderDiscountConfig || []) {
1178
1136
  const { rule_conditions = [], result_detail } = campaign;
1179
1137
  const { main_product, order_discount_conf } = result_detail || {};
1180
1138
  const isPreCheckPassed = preCheck(rule_conditions, tags, []);
@@ -1204,9 +1162,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1204
1162
  discountAmount: 0
1205
1163
  };
1206
1164
  }
1207
- const tieredDiscounts = activeCampaign.result_detail.order_discount_conf.tiered_discounts;
1208
- const qualifyingTier = [...tieredDiscounts].reverse().find((tier) => subtotal >= Number(tier.amount));
1209
- const nextGoal = tieredDiscounts.find((tier) => subtotal < Number(tier.amount));
1165
+ const currentCurrency = cart?.currency?.code || "";
1166
+ console.log("currentCurrency", cart, currentCurrency);
1167
+ const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
1168
+ const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
1169
+ const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
1170
+ const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
1210
1171
  if (!qualifyingTier) {
1211
1172
  return {
1212
1173
  qualifyingDiscount: null,
@@ -1243,43 +1204,10 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1243
1204
  isLoading: isCustomerLoading
1244
1205
  };
1245
1206
  };
1246
- function useHasPlusMemberInCart({
1247
- memberSetting,
1248
- cart
1249
- }) {
1250
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1251
- return react.useMemo(() => {
1252
- if (!cart?.lineItems) {
1253
- return {
1254
- hasPlusMember: false,
1255
- hasMonthlyPlus: false,
1256
- hasAnnualPlus: false
1257
- };
1258
- }
1259
- const monthlyPlusItem = cart.lineItems.find(
1260
- (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
1261
- );
1262
- const annualPlusItem = cart.lineItems.find(
1263
- (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
1264
- );
1265
- const hasMonthlyPlus = !!monthlyPlusItem;
1266
- const hasAnnualPlus = !!annualPlusItem;
1267
- const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1268
- return {
1269
- hasPlusMember,
1270
- hasMonthlyPlus,
1271
- hasAnnualPlus,
1272
- monthlyPlusItem,
1273
- annualPlusItem
1274
- };
1275
- }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1276
- }
1277
-
1278
- // src/hooks/cart/feature/use-cart-attributes.ts
1279
1207
  var getReferralAttributes = () => {
1280
- const inviteCode = Cookies5__default.default.get("invite_code");
1281
- const playModeId = Cookies5__default.default.get("playModeId");
1282
- const popup = Cookies5__default.default.get("_popup");
1208
+ const inviteCode = shopifySdk.getLocalStorage("inviteCode") || Cookies5__default.default.get("inviteCode");
1209
+ const playModeId = shopifySdk.getLocalStorage("playModeId") || Cookies5__default.default.get("playModeId");
1210
+ const popup = shopifySdk.getLocalStorage("_popup") || Cookies5__default.default.get("_popup");
1283
1211
  if (inviteCode && playModeId) {
1284
1212
  return popup ? [
1285
1213
  { key: "_invite_code", value: inviteCode ? inviteCode : "" },
@@ -1292,117 +1220,130 @@ var getReferralAttributes = () => {
1292
1220
  }
1293
1221
  return [];
1294
1222
  };
1223
+ var getUserType = (customer) => {
1224
+ let userInfo = Cookies5__default.default.get("userInfo");
1225
+ if (userInfo) {
1226
+ userInfo = JSON.parse(userInfo);
1227
+ let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1228
+ userInfo.setId = arr[arr.length - 1];
1229
+ }
1230
+ const customerInfo = userInfo || customer;
1231
+ if (!customerInfo) {
1232
+ return "new_user_unlogin";
1233
+ }
1234
+ if (customer) {
1235
+ const { orders = {} } = customer;
1236
+ if (orders?.edges?.length === 1) {
1237
+ return "old_user_orders_once";
1238
+ } else if (orders?.edges?.length > 1) {
1239
+ return "old_user_orders_twice";
1240
+ }
1241
+ }
1242
+ return "new_user_login";
1243
+ };
1244
+ function getCartAttributes({
1245
+ profile,
1246
+ customer,
1247
+ cart,
1248
+ memberType,
1249
+ currentUrl = ""
1250
+ }) {
1251
+ const userType = getUserType(customer);
1252
+ const memberAttributes = [
1253
+ {
1254
+ key: "_token",
1255
+ value: profile?.token
1256
+ },
1257
+ {
1258
+ key: "_member_type",
1259
+ value: memberType ?? String(profile?.memberType)
1260
+ },
1261
+ {
1262
+ key: "_user_type",
1263
+ value: userType
1264
+ },
1265
+ {
1266
+ key: "_is_login",
1267
+ value: profile?.token ? "true" : "false"
1268
+ }
1269
+ ];
1270
+ if (profile?.token) {
1271
+ memberAttributes.push({
1272
+ key: "_login_user",
1273
+ value: "1"
1274
+ });
1275
+ }
1276
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1277
+ const functionAttributes = [
1278
+ {
1279
+ key: CUSTOMER_ATTRIBUTE_KEY,
1280
+ value: JSON.stringify({
1281
+ discount_code: discountCodes,
1282
+ user_tags: customer?.tags || []
1283
+ })
1284
+ }
1285
+ ];
1286
+ const presellAttributes = [
1287
+ {
1288
+ key: "_presale",
1289
+ value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1290
+ }
1291
+ ];
1292
+ const weightAttributes = [
1293
+ {
1294
+ key: "_weight",
1295
+ value: cart?.lineItems.reduce((acc, item) => {
1296
+ return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
1297
+ }, 0).toString()
1298
+ },
1299
+ {
1300
+ key: "_app_source_name",
1301
+ value: "dtc"
1302
+ }
1303
+ ];
1304
+ const trackingAttributes = [
1305
+ {
1306
+ key: "utm_params",
1307
+ value: currentUrl
1308
+ }
1309
+ ];
1310
+ const commonAttributes = [
1311
+ ...memberAttributes,
1312
+ ...functionAttributes,
1313
+ ...presellAttributes,
1314
+ ...weightAttributes,
1315
+ ...trackingAttributes,
1316
+ ...getReferralAttributes()
1317
+ ].filter((item) => item?.value);
1318
+ const extraAttributesInCart = cart?.customAttributes?.filter(
1319
+ (item) => !commonAttributes.some((attr) => attr.key === item.key)
1320
+ ) || [];
1321
+ return [...commonAttributes, ...extraAttributesInCart].filter((item) => item?.value);
1322
+ }
1295
1323
  var useCartAttributes = ({
1296
1324
  profile,
1297
1325
  customer,
1298
1326
  cart,
1299
- memberSetting
1327
+ memberType
1300
1328
  }) => {
1301
1329
  const [currentUrl, setCurrentUrl] = react.useState("");
1302
- const { hasPlusMember } = useHasPlusMemberInCart({
1303
- memberSetting,
1304
- cart
1305
- });
1306
1330
  react.useEffect(() => {
1307
1331
  setCurrentUrl(window.location.href);
1308
1332
  }, []);
1309
- const userType = react.useMemo(() => {
1310
- let userInfo = Cookies5__default.default.get("userInfo");
1311
- if (userInfo) {
1312
- userInfo = JSON.parse(userInfo);
1313
- let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1314
- userInfo.setId = arr[arr.length - 1];
1315
- }
1316
- const customerInfo = userInfo || customer;
1317
- if (!customerInfo) {
1318
- return "new_user_unlogin";
1319
- }
1320
- if (customer) {
1321
- const { orders = {} } = customer;
1322
- if (orders?.edges?.length === 1) {
1323
- return "old_user_orders_once";
1324
- } else if (orders?.edges?.length > 1) {
1325
- return "old_user_orders_twice";
1326
- }
1327
- }
1328
- return "new_user_login";
1329
- }, [customer]);
1330
- const memberAttributes = react.useMemo(() => {
1331
- return [
1332
- {
1333
- key: "_token",
1334
- value: profile?.token
1335
- //是否登录
1336
- },
1337
- {
1338
- key: "_member_type",
1339
- value: hasPlusMember ? "2" : profile?.memberType
1340
- //:0(游客),1(普通会员),2(付费会员)
1341
- },
1342
- {
1343
- key: "_user_type",
1344
- value: userType
1345
- // n
1346
- },
1347
- {
1348
- key: "_is_login",
1349
- value: profile?.token ? "true" : "false"
1350
- }
1351
- ];
1352
- }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1353
- const functionAttributes = react.useMemo(() => {
1354
- return [
1355
- cart?.discountCodes && {
1356
- key: "_discounts_function_env",
1357
- value: JSON.stringify({
1358
- discount_code: cart?.discountCodes.map((item) => item.code),
1359
- user_tags: customer?.tags || []
1360
- })
1361
- }
1362
- ];
1363
- }, [cart]);
1364
- const presellAttributes = react.useMemo(() => {
1365
- return [
1366
- {
1367
- key: "_presale",
1368
- value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1369
- }
1370
- ];
1371
- }, [cart]);
1372
- const weightAttributes = react.useMemo(() => {
1373
- return [
1374
- {
1375
- key: "_weight",
1376
- value: cart?.lineItems.reduce((acc, item) => {
1377
- return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
1378
- }, 0).toString()
1379
- },
1380
- {
1381
- key: "_app_source_name",
1382
- value: "dtc"
1383
- }
1384
- ];
1385
- }, [cart]);
1386
- const trackingAttributes = react.useMemo(() => {
1387
- return [
1388
- {
1389
- key: "utm_params",
1390
- value: currentUrl
1391
- }
1392
- ];
1393
- }, [currentUrl]);
1333
+ const attributes = react.useMemo(() => {
1334
+ return getCartAttributes({
1335
+ profile,
1336
+ customer,
1337
+ cart,
1338
+ memberType,
1339
+ currentUrl
1340
+ });
1341
+ }, [profile, customer, cart, memberType, currentUrl]);
1394
1342
  return react.useMemo(
1395
1343
  () => ({
1396
- attributes: [
1397
- ...memberAttributes,
1398
- ...functionAttributes,
1399
- ...presellAttributes,
1400
- ...weightAttributes,
1401
- ...trackingAttributes,
1402
- ...getReferralAttributes()
1403
- ].filter((item) => item?.value)
1344
+ attributes
1404
1345
  }),
1405
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1346
+ [attributes]
1406
1347
  );
1407
1348
  };
1408
1349
  var DEFAULT_MIN = 1;
@@ -1465,7 +1406,7 @@ var useUpdateLineCodeAmountAttributes = ({
1465
1406
  );
1466
1407
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1467
1408
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1468
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
1409
+ if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1469
1410
  attrNeedUpdate.push({
1470
1411
  key: CUSTOMER_ATTRIBUTE_KEY,
1471
1412
  value: JSON.stringify({
@@ -1504,29 +1445,22 @@ var useUpdateLineCodeAmountAttributes = ({
1504
1445
  }).filter(
1505
1446
  ({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
1506
1447
  ).map(({ line, attrNeedUpdate, attrNeedDelete }) => {
1448
+ let lineId = line.id;
1449
+ let attributes = line.customAttributes || [];
1450
+ if (attrNeedDelete.length) {
1451
+ attributes = attributes.filter(
1452
+ (attr) => !attrNeedDelete.includes(attr.key)
1453
+ );
1454
+ }
1507
1455
  if (attrNeedUpdate.length) {
1508
- return {
1509
- id: line.id,
1510
- attributes: [
1511
- ...line.customAttributes?.filter(
1512
- (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1513
- ) || [],
1514
- ...attrNeedUpdate
1515
- ]
1516
- };
1517
- } else if (attrNeedDelete.length) {
1518
- return {
1519
- id: line.id,
1520
- attributes: line.customAttributes?.filter(
1521
- (attr) => !attrNeedDelete.includes(attr.key)
1522
- ) || []
1523
- };
1524
- } else {
1525
- return {
1526
- id: line.id,
1527
- attributes: line.customAttributes || []
1528
- };
1456
+ attributes = attributes.filter(
1457
+ (attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
1458
+ ).concat(attrNeedUpdate);
1529
1459
  }
1460
+ return {
1461
+ id: lineId,
1462
+ attributes
1463
+ };
1530
1464
  }),
1531
1465
  [cart?.lineItems, mainProductDiscountCodes]
1532
1466
  );
@@ -1561,45 +1495,61 @@ var useUpdateLineCodeAmountAttributes = ({
1561
1495
  }, [loading, setLoadingState]);
1562
1496
  };
1563
1497
 
1564
- // src/hooks/cart/types/price-discount.ts
1565
- var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
1566
- PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
1567
- PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
1568
- return PriceDiscountType2;
1569
- })(PriceDiscountType || {});
1570
- var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
1571
- PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
1572
- PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
1573
- return PriceBasePriceType2;
1574
- })(PriceBasePriceType || {});
1575
- function useProduct(options = {}) {
1576
- const { client, locale } = useShopify();
1577
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
1578
- return useSWR__default.default(
1579
- handle ? ["product", locale, handle, metafieldIdentifiers] : null,
1580
- () => shopifySdk.getProduct(client, {
1581
- handle,
1582
- locale,
1583
- metafieldIdentifiers
1584
- }),
1585
- swrOptions
1586
- );
1587
- }
1588
- function useAllProducts(options = {}) {
1589
- const { client, locale } = useShopify();
1590
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
1591
- return useSWR__default.default(
1592
- ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
1593
- () => shopifySdk.getAllProducts(client, {
1594
- locale,
1595
- first,
1596
- query,
1597
- sortKey,
1598
- reverse,
1599
- metafieldIdentifiers
1600
- }),
1601
- swrOptions
1602
- );
1498
+ // src/hooks/member/plus/types.ts
1499
+ var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
1500
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
1501
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
1502
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
1503
+ return PLUS_MEMBER_TYPE2;
1504
+ })(PLUS_MEMBER_TYPE || {});
1505
+ var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
1506
+ PlusMemberMode2["MONTHLY"] = "monthly";
1507
+ PlusMemberMode2["ANNUAL"] = "annual";
1508
+ return PlusMemberMode2;
1509
+ })(PlusMemberMode || {});
1510
+ var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
1511
+ DeliveryPlusType2["FREE"] = "free";
1512
+ DeliveryPlusType2["MONTHLY"] = "monthly";
1513
+ DeliveryPlusType2["ANNUAL"] = "annual";
1514
+ return DeliveryPlusType2;
1515
+ })(DeliveryPlusType || {});
1516
+ var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
1517
+ ShippingMethodMode2["FREE"] = "free";
1518
+ ShippingMethodMode2["TDD"] = "tdd";
1519
+ ShippingMethodMode2["NDD"] = "ndd";
1520
+ return ShippingMethodMode2;
1521
+ })(ShippingMethodMode || {});
1522
+ var createInitialValue = () => ({
1523
+ plusMemberMetafields: {},
1524
+ selectedPlusMemberMode: "free",
1525
+ setSelectedPlusMemberMode: () => {
1526
+ },
1527
+ selectedShippingMethod: void 0,
1528
+ setSelectedShippingMethod: () => {
1529
+ },
1530
+ showMoreShippingMethod: false,
1531
+ setShowMoreShippingMethod: () => {
1532
+ },
1533
+ variant: {},
1534
+ product: {},
1535
+ shippingMethodsContext: {
1536
+ freeShippingMethods: [],
1537
+ paymentShippingMethods: [],
1538
+ nddOverweight: false,
1539
+ tddOverweight: false,
1540
+ nddCoupon: void 0,
1541
+ tddCoupon: void 0,
1542
+ isLoadingCoupon: false
1543
+ },
1544
+ selectedPlusMemberVariant: void 0,
1545
+ showPlusMemberBenefit: false,
1546
+ setShowPlusMemberBenefit: () => {
1547
+ },
1548
+ profile: void 0
1549
+ });
1550
+ var PlusMemberContext = react.createContext(createInitialValue());
1551
+ function usePlusMemberContext() {
1552
+ return react.useContext(PlusMemberContext);
1603
1553
  }
1604
1554
  function useProductsByHandles(options = {}) {
1605
1555
  const { client, locale } = useShopify();
@@ -1619,41 +1569,811 @@ function useProductsByHandles(options = {}) {
1619
1569
  metafieldIdentifiers
1620
1570
  });
1621
1571
  },
1622
- swrOptions || {
1623
- revalidateOnFocus: false
1572
+ {
1573
+ revalidateOnFocus: false,
1574
+ ...swrOptions
1624
1575
  }
1625
1576
  );
1626
1577
  }
1627
- function getFirstAvailableVariant(product) {
1628
- const availableVariant = product.variants.find((v) => v.availableForSale);
1629
- return availableVariant || product.variants[0];
1630
- }
1631
- function getVariantFromSelectedOptions(product, selectedOptions) {
1632
- return product.variants.find((variant) => {
1633
- return variant.selectedOptions.every((option) => {
1634
- return selectedOptions[option.name] === option.value;
1635
- });
1578
+
1579
+ // src/hooks/member/plus/use-plus-member-variants.ts
1580
+ function usePlusMemberVariants({
1581
+ memberSetting
1582
+ }) {
1583
+ const plusMonthly = memberSetting?.plus_monthly_product;
1584
+ const plusAnnual = memberSetting?.plus_annual_product;
1585
+ const plusMemberHandles = react.useMemo(() => {
1586
+ return [plusMonthly?.handle, plusAnnual?.handle].filter(Boolean);
1587
+ }, [plusMonthly?.handle, plusAnnual?.handle]);
1588
+ const { data: plusMemberProducts = [] } = useProductsByHandles({
1589
+ handles: plusMemberHandles
1636
1590
  });
1591
+ const monthlyProduct = react.useMemo(() => {
1592
+ return plusMemberProducts?.find((item) => item?.handle === plusMonthly?.handle);
1593
+ }, [plusMemberProducts, plusMonthly]);
1594
+ const annualProduct = react.useMemo(() => {
1595
+ return plusMemberProducts?.find((item) => item?.handle === plusAnnual?.handle);
1596
+ }, [plusMemberProducts, plusAnnual]);
1597
+ const monthlyVariant = react.useMemo(() => {
1598
+ return monthlyProduct?.variants?.find((item) => item.sku === plusMonthly?.sku);
1599
+ }, [monthlyProduct, plusMonthly]);
1600
+ const annualVariant = react.useMemo(() => {
1601
+ return annualProduct?.variants?.find((item) => item.sku === plusAnnual?.sku);
1602
+ }, [annualProduct, plusAnnual]);
1603
+ return {
1604
+ monthlyVariant: monthlyVariant ? {
1605
+ ...monthlyVariant,
1606
+ product: monthlyProduct
1607
+ } : void 0,
1608
+ annualVariant: annualVariant ? {
1609
+ ...annualVariant,
1610
+ product: annualProduct
1611
+ } : void 0
1612
+ };
1637
1613
  }
1638
- function useVariant({
1639
- product,
1640
- selectedOptions
1641
- }) {
1642
- const [variant, setVariant] = react.useState(
1643
- product ? getFirstAvailableVariant(product) : void 0
1644
- );
1645
- react.useEffect(() => {
1646
- if (!product) {
1647
- setVariant(void 0);
1648
- return;
1649
- }
1650
- const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
1651
- if (newVariant && newVariant.id !== variant?.id) {
1652
- setVariant(newVariant);
1653
- } else if (!newVariant) {
1654
- setVariant(getFirstAvailableVariant(product));
1614
+ var useAvailableDeliveryCoupon = ({
1615
+ profile
1616
+ }) => {
1617
+ const { data: availableDeliveryCoupon, isLoading } = useSWR__default.default(
1618
+ profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
1619
+ async ([apiPath]) => {
1620
+ return fetch(apiPath).then((res) => res.json());
1655
1621
  }
1656
- }, [selectedOptions, product, variant?.id]);
1622
+ );
1623
+ console.log("availableDeliveryCoupon", availableDeliveryCoupon);
1624
+ const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
1625
+ return {
1626
+ nddCoupon,
1627
+ tddCoupon,
1628
+ isLoading
1629
+ };
1630
+ };
1631
+
1632
+ // src/hooks/member/plus/use-shipping-methods.ts
1633
+ function useShippingMethods(options) {
1634
+ const { variant, plusMemberMetafields, selectedPlusMemberMode, profile } = options;
1635
+ const isPlus = profile?.isPlus || false;
1636
+ const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
1637
+ const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
1638
+ const nddOverweight = react.useMemo(() => {
1639
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
1640
+ }, [shippingMethod?.overWeight_ndd, variant?.weight]);
1641
+ const tddOverweight = react.useMemo(() => {
1642
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
1643
+ }, [shippingMethod?.overWeight_tdd, variant?.weight]);
1644
+ const paymentShippingMethods = react.useMemo(() => {
1645
+ const weight = variant?.weight || 0;
1646
+ const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
1647
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1648
+ return __mode !== "free" /* FREE */ && !__plus && fitWeight;
1649
+ }) || [];
1650
+ return methods.map((method) => {
1651
+ let disabled = false;
1652
+ const selectedFreeMember = selectedPlusMemberMode === "free";
1653
+ if (method.__mode === "ndd" /* NDD */) {
1654
+ disabled = selectedFreeMember || nddOverweight;
1655
+ } else if (method.__mode === "tdd" /* TDD */) {
1656
+ disabled = selectedFreeMember || tddOverweight;
1657
+ }
1658
+ return {
1659
+ ...method,
1660
+ id: method.__mode + method.__code,
1661
+ useCoupon: false,
1662
+ subtitle: plus_shipping?.directly || "",
1663
+ disabled
1664
+ };
1665
+ });
1666
+ }, [
1667
+ nddOverweight,
1668
+ plus_shipping?.directly,
1669
+ plus_shipping?.shipping_methods,
1670
+ selectedPlusMemberMode,
1671
+ tddOverweight,
1672
+ variant?.weight
1673
+ ]);
1674
+ const nddPrice = react.useMemo(() => {
1675
+ const weight = variant?.weight || 0;
1676
+ const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1677
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1678
+ return __mode === "ndd" && fitWeight;
1679
+ });
1680
+ return nddMethod?.price || 0;
1681
+ }, [variant?.weight, paymentShippingMethods]);
1682
+ const tddPrice = react.useMemo(() => {
1683
+ const weight = variant?.weight || 0;
1684
+ const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1685
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1686
+ return __mode === "tdd" && fitWeight;
1687
+ });
1688
+ return tddMethod?.price || 0;
1689
+ }, [variant?.weight, paymentShippingMethods]);
1690
+ const freeShippingMethods = react.useMemo(() => {
1691
+ const weight = variant?.weight || 0;
1692
+ let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
1693
+ if (__mode === "free" /* FREE */) {
1694
+ return true;
1695
+ }
1696
+ if (isPlus) {
1697
+ const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
1698
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1699
+ return hasCoupon && fitWeight && !__plus;
1700
+ } else {
1701
+ return __plus;
1702
+ }
1703
+ }) || [];
1704
+ if (isPlus) {
1705
+ methods = methods.sort((a, b) => {
1706
+ if (b.__mode === "free" /* FREE */) return -1;
1707
+ return 0;
1708
+ });
1709
+ }
1710
+ return methods.map((method) => {
1711
+ let price = 0;
1712
+ let coupon;
1713
+ let disabled;
1714
+ if (method.__mode !== "free" /* FREE */) {
1715
+ switch (method.__mode) {
1716
+ case "tdd":
1717
+ price = tddPrice;
1718
+ coupon = tddCoupon || nddCoupon;
1719
+ break;
1720
+ case "ndd":
1721
+ price = nddPrice;
1722
+ coupon = nddCoupon;
1723
+ break;
1724
+ }
1725
+ disabled = selectedPlusMemberMode === "free";
1726
+ if (method.__mode === "ndd" /* NDD */) {
1727
+ disabled = disabled || nddOverweight;
1728
+ } else if (method.__mode === "tdd" /* TDD */) {
1729
+ disabled = disabled || tddOverweight;
1730
+ }
1731
+ }
1732
+ return {
1733
+ ...method,
1734
+ id: method.__mode + method.__code,
1735
+ useCoupon: true,
1736
+ disabled,
1737
+ coupon,
1738
+ price
1739
+ };
1740
+ });
1741
+ }, [
1742
+ variant?.weight,
1743
+ plus_shipping?.shipping_methods,
1744
+ isPlus,
1745
+ nddCoupon,
1746
+ tddCoupon,
1747
+ selectedPlusMemberMode,
1748
+ tddPrice,
1749
+ nddPrice,
1750
+ nddOverweight,
1751
+ tddOverweight
1752
+ ]);
1753
+ return {
1754
+ freeShippingMethods,
1755
+ paymentShippingMethods,
1756
+ nddOverweight,
1757
+ tddOverweight,
1758
+ nddCoupon,
1759
+ tddCoupon,
1760
+ isLoadingCoupon: isLoading
1761
+ };
1762
+ }
1763
+ var useReplaceCartPlusMember = () => {
1764
+ const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
1765
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1766
+ const { cart } = useCartContext();
1767
+ const plusMonthly = plusMemberMetafields?.plus_monthly_product;
1768
+ const plusAnnual = plusMemberMetafields?.plus_annual_product;
1769
+ const handler = react.useCallback(async () => {
1770
+ const plusMonthlyInCart = cart?.lineItems.find(
1771
+ (item) => item.variant?.sku === plusMonthly?.sku
1772
+ );
1773
+ const plusAnnualInCart = cart?.lineItems.find(
1774
+ (item) => item.variant?.sku === plusAnnual?.sku
1775
+ );
1776
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
1777
+ await removeCartLines2({
1778
+ lineIds: [plusMonthlyInCart.id]
1779
+ });
1780
+ } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
1781
+ await removeCartLines2({
1782
+ lineIds: [plusAnnualInCart.id]
1783
+ });
1784
+ }
1785
+ }, [
1786
+ cart?.lineItems,
1787
+ selectedPlusMemberMode,
1788
+ plusMonthly?.sku,
1789
+ plusAnnual?.sku,
1790
+ removeCartLines2
1791
+ ]);
1792
+ return handler;
1793
+ };
1794
+ var usePlusMemberCheckoutCustomAttributes = ({
1795
+ disableShipping = false,
1796
+ isPresaleContains = false
1797
+ }) => {
1798
+ const { profile, selectedShippingMethod, selectedPlusMemberMode } = usePlusMemberContext();
1799
+ return react.useMemo(() => {
1800
+ const checkoutCustomAttributes = [
1801
+ {
1802
+ key: "_last_url",
1803
+ value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
1804
+ }
1805
+ ];
1806
+ checkoutCustomAttributes.push({
1807
+ key: "_checkout_delivery_custom",
1808
+ value: JSON.stringify({
1809
+ allow_nextday_delivery: true,
1810
+ allow_thirdday_delivery: true,
1811
+ selected_delivery_option: {
1812
+ code: selectedShippingMethod?.__code,
1813
+ mode: selectedShippingMethod?.__mode
1814
+ },
1815
+ is_presale: isPresaleContains,
1816
+ discount_code: selectedShippingMethod?.coupon ? [selectedShippingMethod.coupon] : [],
1817
+ plus_type: profile?.isPlus ? "free" /* FREE */ : selectedPlusMemberMode,
1818
+ is_prime: profile?.isPlus
1819
+ })
1820
+ });
1821
+ if (disableShipping) {
1822
+ checkoutCustomAttributes.push({
1823
+ key: "_hide_shipping",
1824
+ value: "true"
1825
+ });
1826
+ }
1827
+ return checkoutCustomAttributes;
1828
+ }, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
1829
+ };
1830
+ function useRemoveCartLines(options) {
1831
+ const { client, locale, cartCookieAdapter } = useShopify();
1832
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
1833
+ const removeLines = react.useCallback(
1834
+ async (_key, { arg }) => {
1835
+ const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1836
+ let updatedCart = await shopifySdk.removeCartLines(client, {
1837
+ cartId,
1838
+ lineIds,
1839
+ metafieldIdentifiers,
1840
+ cookieAdapter: cartCookieAdapter
1841
+ });
1842
+ if (updatedCart && autoRemoveInvalidCodes) {
1843
+ const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1844
+ if (unApplicableCodes.length > 0) {
1845
+ if (onCodesRemoved) {
1846
+ const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1847
+ if (handledCart) {
1848
+ updatedCart = handledCart;
1849
+ }
1850
+ } else {
1851
+ updatedCart = await shopifySdk.updateCartCodes(client, {
1852
+ cartId: updatedCart.id,
1853
+ discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1854
+ metafieldIdentifiers,
1855
+ cookieAdapter: cartCookieAdapter
1856
+ }) || updatedCart;
1857
+ }
1858
+ }
1859
+ }
1860
+ if (updatedCart) {
1861
+ mutateCart(updatedCart);
1862
+ }
1863
+ return updatedCart;
1864
+ },
1865
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1866
+ );
1867
+ return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
1868
+ }
1869
+
1870
+ // src/hooks/member/plus/use-auto-remove-plus-member-in-cart.ts
1871
+ function useAutoRemovePlusMemberInCart({
1872
+ cart,
1873
+ profile,
1874
+ memberSetting
1875
+ }) {
1876
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1877
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1878
+ react.useEffect(() => {
1879
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
1880
+ const removePlusProduct = async (productType) => {
1881
+ if (!productType) return;
1882
+ const product = cart.lineItems?.find(
1883
+ (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
1884
+ );
1885
+ if (product) {
1886
+ await removeCartLines2({
1887
+ lineIds: [product.id]
1888
+ });
1889
+ }
1890
+ };
1891
+ if (profile?.isMonthlyPlus) {
1892
+ removePlusProduct(plus_monthly_product);
1893
+ }
1894
+ if (profile?.isAnnualPlus) {
1895
+ removePlusProduct(plus_annual_product);
1896
+ }
1897
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
1898
+ }
1899
+ function hasPlusMemberInCart({
1900
+ memberSetting,
1901
+ cart
1902
+ }) {
1903
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1904
+ if (!cart?.lineItems) {
1905
+ return {
1906
+ hasPlusMember: false,
1907
+ hasMonthlyPlus: false,
1908
+ hasAnnualPlus: false
1909
+ };
1910
+ }
1911
+ const monthlyPlusItem = cart.lineItems.find(
1912
+ (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
1913
+ );
1914
+ const annualPlusItem = cart.lineItems.find(
1915
+ (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
1916
+ );
1917
+ const hasMonthlyPlus = !!monthlyPlusItem;
1918
+ const hasAnnualPlus = !!annualPlusItem;
1919
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1920
+ return {
1921
+ hasPlusMember,
1922
+ hasMonthlyPlus,
1923
+ hasAnnualPlus,
1924
+ monthlyPlusItem,
1925
+ annualPlusItem
1926
+ };
1927
+ }
1928
+ function useHasPlusMemberInCart({
1929
+ memberSetting,
1930
+ cart
1931
+ }) {
1932
+ return react.useMemo(
1933
+ () => hasPlusMemberInCart({
1934
+ memberSetting,
1935
+ cart
1936
+ }),
1937
+ [memberSetting, cart]
1938
+ );
1939
+ }
1940
+ function hasPlusMemberInLines({
1941
+ memberSetting,
1942
+ lines
1943
+ }) {
1944
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1945
+ if (!lines || lines.length === 0) {
1946
+ return {
1947
+ hasPlusMember: false,
1948
+ hasMonthlyPlus: false,
1949
+ hasAnnualPlus: false
1950
+ };
1951
+ }
1952
+ const monthlyPlusLine = lines.find((line) => {
1953
+ const variantHandle = line.variant?.product?.handle;
1954
+ const variantSku = line.variant?.sku;
1955
+ return variantHandle === plus_monthly_product?.handle && variantSku === plus_monthly_product?.sku;
1956
+ });
1957
+ const annualPlusLine = lines.find((line) => {
1958
+ const variantHandle = line.variant?.product?.handle;
1959
+ const variantSku = line.variant?.sku;
1960
+ return variantHandle === plus_annual_product?.handle && variantSku === plus_annual_product?.sku;
1961
+ });
1962
+ const hasMonthlyPlus = !!monthlyPlusLine;
1963
+ const hasAnnualPlus = !!annualPlusLine;
1964
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1965
+ return {
1966
+ hasPlusMember,
1967
+ hasMonthlyPlus,
1968
+ hasAnnualPlus,
1969
+ monthlyPlusLine,
1970
+ annualPlusLine
1971
+ };
1972
+ }
1973
+ function useHasPlusMemberInLines({
1974
+ memberSetting,
1975
+ lines
1976
+ }) {
1977
+ return react.useMemo(
1978
+ () => hasPlusMemberInLines({
1979
+ memberSetting,
1980
+ lines
1981
+ }),
1982
+ [memberSetting, lines]
1983
+ );
1984
+ }
1985
+ function usePlusMemberNeedAddToCart({
1986
+ cart,
1987
+ profile
1988
+ }) {
1989
+ const { selectedPlusMemberMode, selectedPlusMemberVariant, plusMemberMetafields } = usePlusMemberContext();
1990
+ const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
1991
+ memberSetting: plusMemberMetafields,
1992
+ cart
1993
+ });
1994
+ const plusMemberVariant = react.useMemo(() => {
1995
+ if (!selectedPlusMemberVariant || selectedPlusMemberMode === "free" /* FREE */) {
1996
+ return void 0;
1997
+ }
1998
+ if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
1999
+ return void 0;
2000
+ }
2001
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2002
+ return void 0;
2003
+ }
2004
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2005
+ return void 0;
2006
+ }
2007
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2008
+ return void 0;
2009
+ }
2010
+ return selectedPlusMemberVariant;
2011
+ }, [selectedPlusMemberMode, selectedPlusMemberVariant, hasMonthlyPlus, hasAnnualPlus]);
2012
+ return plusMemberVariant;
2013
+ }
2014
+ var PlusMemberProvider = ({
2015
+ variant,
2016
+ product,
2017
+ memberSetting,
2018
+ initialSelectedPlusMemberMode = "free",
2019
+ profile,
2020
+ children
2021
+ }) => {
2022
+ const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
2023
+ initialSelectedPlusMemberMode
2024
+ );
2025
+ const [selectedShippingMethod, setSelectedShippingMethod] = react.useState();
2026
+ const [showMoreShippingMethod, setShowMoreShippingMethod] = react.useState(false);
2027
+ const [showPlusMemberBenefit, setShowPlusMemberBenefit] = react.useState(false);
2028
+ const shippingMethodsContext = useShippingMethods({
2029
+ variant,
2030
+ plusMemberMetafields: memberSetting,
2031
+ selectedPlusMemberMode,
2032
+ profile
2033
+ });
2034
+ const { monthlyVariant, annualVariant } = usePlusMemberVariants({
2035
+ memberSetting
2036
+ });
2037
+ const selectedPlusMemberVariant = react.useMemo(() => {
2038
+ if (selectedPlusMemberMode === "free" /* FREE */) {
2039
+ return void 0;
2040
+ }
2041
+ return selectedPlusMemberMode === "monthly" /* MONTHLY */ ? monthlyVariant : annualVariant;
2042
+ }, [monthlyVariant, annualVariant, selectedPlusMemberMode]);
2043
+ return /* @__PURE__ */ jsxRuntime.jsx(
2044
+ PlusMemberContext.Provider,
2045
+ {
2046
+ value: {
2047
+ variant,
2048
+ plusMemberMetafields: memberSetting,
2049
+ selectedPlusMemberMode,
2050
+ setSelectedPlusMemberMode,
2051
+ selectedShippingMethod,
2052
+ setSelectedShippingMethod,
2053
+ shippingMethodsContext,
2054
+ showMoreShippingMethod,
2055
+ setShowMoreShippingMethod,
2056
+ selectedPlusMemberVariant,
2057
+ product,
2058
+ showPlusMemberBenefit,
2059
+ setShowPlusMemberBenefit,
2060
+ profile
2061
+ },
2062
+ children
2063
+ }
2064
+ );
2065
+ };
2066
+
2067
+ // src/hooks/cart/use-add-to-cart.ts
2068
+ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2069
+ const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
2070
+ const { cart, addCustomAttributes, memberSetting, profile, customer } = useCartContext();
2071
+ const { trigger: applyCartCodes } = useApplyCartCodes();
2072
+ const { trigger: removeInvalidCodes } = useRemoveCartCodes();
2073
+ const { trigger: addCartLines2 } = useAddCartLines();
2074
+ const { trigger: createCart4 } = useCreateCart({
2075
+ updateCookie: true
2076
+ });
2077
+ const { hasPlusMember } = useHasPlusMemberInCart({
2078
+ memberSetting,
2079
+ cart
2080
+ });
2081
+ const { attributes: cartAttributes } = useCartAttributes({
2082
+ profile,
2083
+ customer,
2084
+ cart,
2085
+ memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
2086
+ });
2087
+ const addToCart = react.useCallback(
2088
+ async (_key, { arg }) => {
2089
+ const {
2090
+ lineItems,
2091
+ cartId: providedCartId,
2092
+ discountCodes,
2093
+ gtmParams = {},
2094
+ buyerIdentity,
2095
+ needCreateCart = false,
2096
+ onCodesInvalid,
2097
+ replaceExistingCodes,
2098
+ customAttributes
2099
+ } = arg;
2100
+ if (!lineItems || lineItems.length === 0) {
2101
+ return;
2102
+ }
2103
+ performanceAdapter?.addToCartStart();
2104
+ const linesWithFunctionAttributes = getLinesWithAttributes({ cart, lineItems });
2105
+ const lines = linesWithFunctionAttributes.map((item) => ({
2106
+ merchandiseId: item.variant?.id || "",
2107
+ quantity: item.quantity || 1,
2108
+ attributes: item.attributes,
2109
+ sellingPlanId: item.sellingPlanId
2110
+ })).filter((item) => item.merchandiseId && item.quantity);
2111
+ if (lines.length === 0) {
2112
+ return;
2113
+ }
2114
+ let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
2115
+ let resultCart = null;
2116
+ if (!cartId) {
2117
+ resultCart = await createCart4({
2118
+ lines,
2119
+ buyerIdentity,
2120
+ discountCodes,
2121
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2122
+ // 初次加购时,就把所有 cart attributes 带上
2123
+ });
2124
+ } else {
2125
+ resultCart = await addCartLines2({
2126
+ cartId,
2127
+ lines
2128
+ });
2129
+ console.log("npm addCartLines resultCart", resultCart);
2130
+ if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
2131
+ const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
2132
+ if (unapplicableCodes.length > 0) {
2133
+ if (onCodesInvalid) {
2134
+ const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
2135
+ if (handledCart) {
2136
+ resultCart = handledCart;
2137
+ }
2138
+ } else {
2139
+ await removeInvalidCodes({
2140
+ discountCodes: unapplicableCodes
2141
+ });
2142
+ }
2143
+ }
2144
+ }
2145
+ if (resultCart && discountCodes && discountCodes.length > 0) {
2146
+ applyCartCodes({
2147
+ replaceExistingCodes,
2148
+ discountCodes
2149
+ });
2150
+ }
2151
+ if (customAttributes && customAttributes.length > 0) {
2152
+ addCustomAttributes(customAttributes);
2153
+ }
2154
+ }
2155
+ if (withTrack) {
2156
+ trackAddToCartGA({
2157
+ lineItems,
2158
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2159
+ });
2160
+ trackAddToCartFBQ({ lineItems });
2161
+ }
2162
+ performanceAdapter?.addToCartEnd();
2163
+ return resultCart;
2164
+ },
2165
+ [
2166
+ client,
2167
+ locale,
2168
+ cartCookieAdapter,
2169
+ userAdapter,
2170
+ cart,
2171
+ withTrack,
2172
+ performanceAdapter,
2173
+ createCart4,
2174
+ addCartLines2,
2175
+ applyCartCodes,
2176
+ removeInvalidCodes,
2177
+ addCustomAttributes,
2178
+ config
2179
+ ]
2180
+ );
2181
+ return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
2182
+ }
2183
+ function useUpdateCartLines(options) {
2184
+ const { client, locale, cartCookieAdapter } = useShopify();
2185
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
2186
+ const updateLines = react.useCallback(
2187
+ async (_key, { arg }) => {
2188
+ const updatedCart = await shopifySdk.updateCartLines(client, {
2189
+ ...arg,
2190
+ metafieldIdentifiers,
2191
+ cookieAdapter: cartCookieAdapter
2192
+ });
2193
+ if (updatedCart) {
2194
+ mutateCart(updatedCart);
2195
+ }
2196
+ console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
2197
+ return updatedCart;
2198
+ },
2199
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
2200
+ );
2201
+ return useSWRMutation__default.default("update-cart-lines", updateLines, options);
2202
+ }
2203
+ function useUpdateCartAttributes({
2204
+ mutate,
2205
+ metafieldIdentifiers,
2206
+ disabled = false,
2207
+ swrOptions
2208
+ }) {
2209
+ const { client, locale, cartCookieAdapter } = useShopify();
2210
+ const updateAttributes = react.useCallback(
2211
+ async (_key, { arg }) => {
2212
+ if (disabled) {
2213
+ return void 0;
2214
+ }
2215
+ const updatedCart = await shopifySdk.updateCartAttributes(client, {
2216
+ ...arg,
2217
+ metafieldIdentifiers,
2218
+ cookieAdapter: cartCookieAdapter
2219
+ });
2220
+ if (updatedCart) {
2221
+ mutate(updatedCart);
2222
+ }
2223
+ return updatedCart;
2224
+ },
2225
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers, disabled]
2226
+ );
2227
+ return useSWRMutation__default.default("update-cart-attributes", updateAttributes, swrOptions);
2228
+ }
2229
+ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2230
+ const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
2231
+ const { profile, customer, memberSetting } = useCartContext();
2232
+ const isLoggedIn = userAdapter?.isLoggedIn || false;
2233
+ const buyNow = react.useCallback(
2234
+ async (_key, { arg }) => {
2235
+ const {
2236
+ lineItems,
2237
+ discountCodes,
2238
+ gtmParams = {},
2239
+ buyerIdentity,
2240
+ fbqTrackConfig,
2241
+ customAttributes,
2242
+ metafieldIdentifiers,
2243
+ redirectToCheckout
2244
+ } = arg;
2245
+ if (!lineItems || lineItems.length === 0) {
2246
+ return;
2247
+ }
2248
+ const { hasPlusMember } = hasPlusMemberInLines({
2249
+ memberSetting,
2250
+ lines: lineItems
2251
+ });
2252
+ const memberType = hasPlusMember ? "2" : String(profile?.memberType ?? 0);
2253
+ const cartAttributes = getCartAttributes({
2254
+ profile,
2255
+ customer,
2256
+ memberType,
2257
+ currentUrl: window.location.href
2258
+ });
2259
+ const linesWithFunctionAttributes = getLinesWithAttributes({
2260
+ lineItems
2261
+ });
2262
+ const lines = linesWithFunctionAttributes.map((item) => ({
2263
+ merchandiseId: item.variant?.id || "",
2264
+ quantity: item.quantity || 1,
2265
+ attributes: item.attributes,
2266
+ sellingPlanId: item.sellingPlanId
2267
+ })).filter((item) => item.merchandiseId);
2268
+ if (lines.length === 0) {
2269
+ return;
2270
+ }
2271
+ const resultCart = await shopifySdk.createCart(client, {
2272
+ lines,
2273
+ metafieldIdentifiers,
2274
+ cookieAdapter: cartCookieAdapter,
2275
+ buyerIdentity,
2276
+ discountCodes,
2277
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2278
+ });
2279
+ if (!resultCart) {
2280
+ throw new Error("Failed to create cart for buy now");
2281
+ }
2282
+ if (withTrack && resultCart.lineItems) {
2283
+ trackBuyNowGA({
2284
+ lineItems,
2285
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2286
+ });
2287
+ if (fbqTrackConfig) {
2288
+ trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
2289
+ }
2290
+ }
2291
+ if (redirectToCheckout) {
2292
+ if (resultCart.url) {
2293
+ if (typeof window !== "undefined") {
2294
+ window.location.href = resultCart.url;
2295
+ }
2296
+ } else {
2297
+ throw new Error("Failed to get checkout URL");
2298
+ }
2299
+ }
2300
+ return resultCart;
2301
+ },
2302
+ [client, locale, isLoggedIn, cartCookieAdapter, withTrack, customer, profile, memberSetting]
2303
+ );
2304
+ return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
2305
+ }
2306
+
2307
+ // src/hooks/cart/types/price-discount.ts
2308
+ var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
2309
+ PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
2310
+ PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
2311
+ return PriceDiscountType2;
2312
+ })(PriceDiscountType || {});
2313
+ var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
2314
+ PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
2315
+ PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
2316
+ return PriceBasePriceType2;
2317
+ })(PriceBasePriceType || {});
2318
+ function useProduct(options = {}) {
2319
+ const { client, locale } = useShopify();
2320
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2321
+ return useSWR__default.default(
2322
+ handle ? ["product", locale, handle, metafieldIdentifiers] : null,
2323
+ () => shopifySdk.getProduct(client, {
2324
+ handle,
2325
+ locale,
2326
+ metafieldIdentifiers
2327
+ }),
2328
+ swrOptions
2329
+ );
2330
+ }
2331
+ function useAllProducts(options = {}) {
2332
+ const { client, locale } = useShopify();
2333
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2334
+ return useSWR__default.default(
2335
+ ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2336
+ () => shopifySdk.getAllProducts(client, {
2337
+ locale,
2338
+ first,
2339
+ query,
2340
+ sortKey,
2341
+ reverse,
2342
+ metafieldIdentifiers
2343
+ }),
2344
+ swrOptions
2345
+ );
2346
+ }
2347
+ function getFirstAvailableVariant(product) {
2348
+ const availableVariant = product.variants.find((v) => v.availableForSale);
2349
+ return availableVariant || product.variants[0];
2350
+ }
2351
+ function getVariantFromSelectedOptions(product, selectedOptions) {
2352
+ return product.variants.find((variant) => {
2353
+ return variant.selectedOptions.every((option) => {
2354
+ return selectedOptions[option.name] === option.value;
2355
+ });
2356
+ });
2357
+ }
2358
+ function useVariant({
2359
+ product,
2360
+ selectedOptions
2361
+ }) {
2362
+ const [variant, setVariant] = react.useState(
2363
+ product ? getFirstAvailableVariant(product) : void 0
2364
+ );
2365
+ react.useEffect(() => {
2366
+ if (!product) {
2367
+ setVariant(void 0);
2368
+ return;
2369
+ }
2370
+ const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
2371
+ if (newVariant && newVariant.id !== variant?.id) {
2372
+ setVariant(newVariant);
2373
+ } else if (!newVariant) {
2374
+ setVariant(getFirstAvailableVariant(product));
2375
+ }
2376
+ }, [selectedOptions, product, variant?.id]);
1657
2377
  return variant;
1658
2378
  }
1659
2379
  var FAKE_PRICE = 999999999e-2;
@@ -2057,714 +2777,141 @@ async function performSearch(client, locale, searchQuery, first = 20, types = ["
2057
2777
  id
2058
2778
  handle
2059
2779
  title
2060
- description
2061
- featuredImage {
2062
- url
2063
- altText
2064
- }
2065
- }
2066
- }
2067
- }
2068
- pageInfo {
2069
- hasNextPage
2070
- endCursor
2071
- }
2072
- }
2073
- }
2074
- `
2075
- );
2076
- const data = await client.query(query, {
2077
- query: searchQuery,
2078
- first,
2079
- types
2080
- });
2081
- if (!data || !data.search) {
2082
- return void 0;
2083
- }
2084
- const items = data.search.edges?.map((edge) => {
2085
- const node = edge.node;
2086
- const item = {
2087
- type: node.__typename.toUpperCase(),
2088
- id: node.id,
2089
- handle: node.handle,
2090
- title: node.title
2091
- };
2092
- if (node.__typename === "Product") {
2093
- item.description = node.description;
2094
- item.image = node.featuredImage ? {
2095
- url: node.featuredImage.url,
2096
- altText: node.featuredImage.altText
2097
- } : void 0;
2098
- } else if (node.__typename === "Article") {
2099
- item.description = node.excerpt;
2100
- item.image = node.image ? {
2101
- url: node.image.url,
2102
- altText: node.image.altText
2103
- } : void 0;
2104
- }
2105
- return item;
2106
- }) || [];
2107
- return {
2108
- items,
2109
- totalCount: data.search.totalCount || 0,
2110
- pageInfo: data.search.pageInfo
2111
- };
2112
- }
2113
- function useSearch(options = {}) {
2114
- const { client, locale } = useShopify();
2115
- const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2116
- return useSWR__default.default(
2117
- query ? ["search", locale, query, first, types] : null,
2118
- () => performSearch(client, locale, query, first, types),
2119
- swrOptions
2120
- );
2121
- }
2122
- async function getSiteInfo(client, locale, metafieldIdentifiers) {
2123
- const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2124
- const query = (
2125
- /* GraphQL */
2126
- `
2127
- query getSiteInfo(
2128
- ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2129
- ) @inContext(language: $language) {
2130
- shop {
2131
- name
2132
- description
2133
- primaryDomain {
2134
- url
2135
- host
2136
- }
2137
- brand {
2138
- logo {
2139
- image {
2140
- url
2141
- }
2142
- }
2143
- colors {
2144
- primary {
2145
- background
2146
- }
2147
- secondary {
2148
- background
2780
+ description
2781
+ featuredImage {
2782
+ url
2783
+ altText
2784
+ }
2149
2785
  }
2150
2786
  }
2151
2787
  }
2152
- ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2788
+ pageInfo {
2789
+ hasNextPage
2790
+ endCursor
2791
+ }
2153
2792
  }
2154
2793
  }
2155
2794
  `
2156
2795
  );
2157
- const variables = {};
2158
- if (hasMetafields) {
2159
- variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2160
- }
2161
- const data = await client.query(query, variables);
2162
- if (!data || !data.shop) {
2796
+ const data = await client.query(query, {
2797
+ query: searchQuery,
2798
+ first,
2799
+ types
2800
+ });
2801
+ if (!data || !data.search) {
2163
2802
  return void 0;
2164
2803
  }
2165
- const shop = data.shop;
2166
- const metafields = shop.metafields?.reduce((acc, mf) => {
2167
- if (mf && mf.key) {
2168
- acc[mf.key] = mf.value;
2804
+ const items = data.search.edges?.map((edge) => {
2805
+ const node = edge.node;
2806
+ const item = {
2807
+ type: node.__typename.toUpperCase(),
2808
+ id: node.id,
2809
+ handle: node.handle,
2810
+ title: node.title
2811
+ };
2812
+ if (node.__typename === "Product") {
2813
+ item.description = node.description;
2814
+ item.image = node.featuredImage ? {
2815
+ url: node.featuredImage.url,
2816
+ altText: node.featuredImage.altText
2817
+ } : void 0;
2818
+ } else if (node.__typename === "Article") {
2819
+ item.description = node.excerpt;
2820
+ item.image = node.image ? {
2821
+ url: node.image.url,
2822
+ altText: node.image.altText
2823
+ } : void 0;
2169
2824
  }
2170
- return acc;
2171
- }, {});
2825
+ return item;
2826
+ }) || [];
2172
2827
  return {
2173
- name: shop.name,
2174
- description: shop.description,
2175
- primaryDomain: shop.primaryDomain,
2176
- brand: shop.brand ? {
2177
- logo: shop.brand.logo,
2178
- colors: shop.brand.colors ? {
2179
- primary: shop.brand.colors.primary?.background,
2180
- secondary: shop.brand.colors.secondary?.background
2181
- } : void 0
2182
- } : void 0,
2183
- metafields
2828
+ items,
2829
+ totalCount: data.search.totalCount || 0,
2830
+ pageInfo: data.search.pageInfo
2184
2831
  };
2185
2832
  }
2186
- function useSite(options = {}) {
2833
+ function useSearch(options = {}) {
2187
2834
  const { client, locale } = useShopify();
2188
- const { metafieldIdentifiers, ...swrOptions } = options;
2189
- return useSWR__default.default(
2190
- ["site", locale, metafieldIdentifiers],
2191
- () => getSiteInfo(client, locale, metafieldIdentifiers),
2192
- swrOptions
2193
- );
2194
- }
2195
-
2196
- // src/hooks/member/plus/types.ts
2197
- var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
2198
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
2199
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
2200
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
2201
- return PLUS_MEMBER_TYPE2;
2202
- })(PLUS_MEMBER_TYPE || {});
2203
- var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
2204
- PlusMemberMode2["MONTHLY"] = "monthly";
2205
- PlusMemberMode2["ANNUAL"] = "annual";
2206
- return PlusMemberMode2;
2207
- })(PlusMemberMode || {});
2208
- var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
2209
- DeliveryPlusType2["FREE"] = "free";
2210
- DeliveryPlusType2["MONTHLY"] = "monthly";
2211
- DeliveryPlusType2["ANNUAL"] = "annual";
2212
- return DeliveryPlusType2;
2213
- })(DeliveryPlusType || {});
2214
- var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
2215
- ShippingMethodMode2["FREE"] = "free";
2216
- ShippingMethodMode2["TDD"] = "tdd";
2217
- ShippingMethodMode2["NDD"] = "ndd";
2218
- return ShippingMethodMode2;
2219
- })(ShippingMethodMode || {});
2220
- var createInitialValue = () => ({
2221
- zipCode: "",
2222
- plusMemberMetafields: {},
2223
- setZipCode: () => {
2224
- },
2225
- allowNextDayDelivery: false,
2226
- setAllowNextDayDelivery: () => {
2227
- },
2228
- allowThirdDayDelivery: false,
2229
- setAllowThirdDayDelivery: () => {
2230
- },
2231
- selectedPlusMemberMode: "free",
2232
- setSelectedPlusMemberMode: () => {
2233
- },
2234
- showAreaCheckModal: false,
2235
- setShowAreaCheckModal: () => {
2236
- },
2237
- selectedShippingMethod: void 0,
2238
- setSelectedShippingMethod: () => {
2239
- },
2240
- showTip: false,
2241
- setShowTip: () => {
2242
- },
2243
- showMoreShippingMethod: false,
2244
- setShowMoreShippingMethod: () => {
2245
- },
2246
- variant: {},
2247
- product: {},
2248
- shippingMethodsContext: {
2249
- freeShippingMethods: [],
2250
- paymentShippingMethods: [],
2251
- nddOverweight: false,
2252
- tddOverweight: false
2253
- },
2254
- selectedPlusMemberProduct: null,
2255
- plusMemberProducts: [],
2256
- showPlusMemberBenefit: false,
2257
- setShowPlusMemberBenefit: () => {
2258
- },
2259
- deleteMarginBottom: false,
2260
- setDeleteMarginBottom: () => {
2261
- },
2262
- profile: void 0,
2263
- locale: void 0
2264
- });
2265
- var PlusMemberContext = react.createContext(createInitialValue());
2266
- function usePlusMemberContext() {
2267
- return react.useContext(PlusMemberContext);
2268
- }
2269
- function usePlusMonthlyProductVariant() {
2270
- const { plusMemberProducts, plusMemberMetafields } = usePlusMemberContext();
2271
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2272
- const plusMonthlyProductVariant = react.useMemo(() => {
2273
- const product = plusMemberProducts?.find(
2274
- (item) => item?.handle === plusMonthly?.handle
2275
- );
2276
- const productVariant = product?.variants?.find(
2277
- (item) => item.sku === plusMonthly?.sku
2278
- );
2279
- return productVariant;
2280
- }, [plusMemberProducts, plusMonthly]);
2281
- return plusMonthlyProductVariant;
2282
- }
2283
- function usePlusAnnualProductVariant() {
2284
- const { plusMemberProducts, plusMemberMetafields } = usePlusMemberContext();
2285
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2286
- const plusAnnualProductVariant = react.useMemo(() => {
2287
- const product = plusMemberProducts?.find(
2288
- (item) => item?.handle === plusAnnual?.handle
2289
- );
2290
- const productVariant = product?.variants?.find(
2291
- (item) => item.sku === plusAnnual?.sku
2292
- );
2293
- return productVariant;
2294
- }, [plusMemberProducts, plusAnnual]);
2295
- return plusAnnualProductVariant;
2296
- }
2297
- function useShippingMethods(options) {
2298
- const {
2299
- variant,
2300
- plusMemberMetafields,
2301
- selectedPlusMemberMode,
2302
- isPlus = false,
2303
- nddCoupon,
2304
- tddCoupon
2305
- } = options;
2306
- const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
2307
- const nddOverweight = react.useMemo(() => {
2308
- return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
2309
- }, [shippingMethod?.overWeight_ndd, variant?.weight]);
2310
- const tddOverweight = react.useMemo(() => {
2311
- return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
2312
- }, [shippingMethod?.overWeight_tdd, variant?.weight]);
2313
- const paymentShippingMethods = react.useMemo(() => {
2314
- const weight = variant?.weight || 0;
2315
- const methods = plus_shipping?.shipping_methods?.filter(
2316
- ({ weight_low, weight_high, __mode, __plus }) => {
2317
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2318
- return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2319
- }
2320
- ) || [];
2321
- return methods.map((method) => {
2322
- let disabled = false;
2323
- const selectedFreeMember = selectedPlusMemberMode === "free";
2324
- if (method.__mode === "ndd" /* NDD */) {
2325
- disabled = selectedFreeMember || nddOverweight;
2326
- } else if (method.__mode === "tdd" /* TDD */) {
2327
- disabled = selectedFreeMember || tddOverweight;
2328
- }
2329
- return {
2330
- ...method,
2331
- id: method.__mode + method.__code,
2332
- useCoupon: false,
2333
- subtitle: plus_shipping?.directly || "",
2334
- disabled
2335
- };
2336
- });
2337
- }, [
2338
- nddOverweight,
2339
- plus_shipping?.directly,
2340
- plus_shipping?.shipping_methods,
2341
- selectedPlusMemberMode,
2342
- tddOverweight,
2343
- variant?.weight
2344
- ]);
2345
- const nddPrice = react.useMemo(() => {
2346
- const weight = variant?.weight || 0;
2347
- const nddMethod = paymentShippingMethods.find(
2348
- ({ __mode, weight_high, weight_low }) => {
2349
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2350
- return __mode === "ndd" && fitWeight;
2351
- }
2352
- );
2353
- return nddMethod?.price || 0;
2354
- }, [variant?.weight, paymentShippingMethods]);
2355
- const tddPrice = react.useMemo(() => {
2356
- const weight = variant?.weight || 0;
2357
- const tddMethod = paymentShippingMethods.find(
2358
- ({ __mode, weight_high, weight_low }) => {
2359
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2360
- return __mode === "tdd" && fitWeight;
2361
- }
2362
- );
2363
- return tddMethod?.price || 0;
2364
- }, [variant?.weight, paymentShippingMethods]);
2365
- const freeShippingMethods = react.useMemo(() => {
2366
- const weight = variant?.weight || 0;
2367
- let methods = plus_shipping?.shipping_methods?.filter(
2368
- ({ __mode, __plus, weight_low, weight_high }) => {
2369
- if (__mode === "free" /* FREE */) {
2370
- return true;
2371
- }
2372
- if (isPlus) {
2373
- const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2374
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2375
- return hasCoupon && fitWeight && !__plus;
2376
- } else {
2377
- return __plus;
2378
- }
2379
- }
2380
- ) || [];
2381
- if (isPlus) {
2382
- methods = methods.sort((a, b) => {
2383
- if (b.__mode === "free" /* FREE */) return -1;
2384
- return 0;
2385
- });
2386
- }
2387
- return methods.map((method) => {
2388
- let price = 0;
2389
- let coupon;
2390
- let disabled;
2391
- if (method.__mode !== "free" /* FREE */) {
2392
- switch (method.__mode) {
2393
- case "tdd":
2394
- price = tddPrice;
2395
- coupon = tddCoupon || nddCoupon;
2396
- break;
2397
- case "ndd":
2398
- price = nddPrice;
2399
- coupon = nddCoupon;
2400
- break;
2401
- }
2402
- disabled = selectedPlusMemberMode === "free";
2403
- if (method.__mode === "ndd" /* NDD */) {
2404
- disabled = disabled || nddOverweight;
2405
- } else if (method.__mode === "tdd" /* TDD */) {
2406
- disabled = disabled || tddOverweight;
2407
- }
2408
- }
2409
- return {
2410
- ...method,
2411
- id: method.__mode + method.__code,
2412
- useCoupon: true,
2413
- disabled,
2414
- coupon,
2415
- price
2416
- };
2417
- });
2418
- }, [
2419
- variant?.weight,
2420
- plus_shipping?.shipping_methods,
2421
- isPlus,
2422
- nddCoupon,
2423
- tddCoupon,
2424
- selectedPlusMemberMode,
2425
- tddPrice,
2426
- nddPrice,
2427
- nddOverweight,
2428
- tddOverweight
2429
- ]);
2430
- return {
2431
- freeShippingMethods,
2432
- paymentShippingMethods,
2433
- nddOverweight,
2434
- tddOverweight
2435
- };
2835
+ const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2836
+ return useSWR__default.default(
2837
+ query ? ["search", locale, query, first, types] : null,
2838
+ () => performSearch(client, locale, query, first, types),
2839
+ swrOptions
2840
+ );
2436
2841
  }
2437
- function useShippingMethodAvailableCheck() {
2438
- const {
2439
- zipCode,
2440
- allowNextDayDelivery,
2441
- allowThirdDayDelivery,
2442
- selectedShippingMethod,
2443
- setSelectedShippingMethod,
2444
- setShowTip,
2445
- shippingMethodsContext
2446
- } = usePlusMemberContext();
2447
- react.useEffect(() => {
2448
- const freeShippingMethod = shippingMethodsContext.freeShippingMethods[0];
2449
- const standardShippingMethod = shippingMethodsContext.freeShippingMethods?.find(
2450
- (item) => item.__mode === "free" /* FREE */
2451
- );
2452
- const freeTDD = shippingMethodsContext.freeShippingMethods.find(
2453
- (item) => item.__mode === "tdd" /* TDD */
2454
- );
2455
- const paymentTDD = shippingMethodsContext.paymentShippingMethods.find(
2456
- (item) => item.__mode === "tdd" /* TDD */
2457
- );
2458
- if (zipCode) {
2459
- console.log(
2460
- "allowNextDayDelivery, allowThirdDayDelivery:",
2461
- allowNextDayDelivery,
2462
- allowThirdDayDelivery
2463
- );
2464
- if (!allowNextDayDelivery && !allowThirdDayDelivery) {
2465
- setShowTip(true);
2466
- setSelectedShippingMethod(standardShippingMethod);
2467
- } else {
2468
- if (selectedShippingMethod?.__mode === "ndd" /* NDD */ && !allowNextDayDelivery) {
2469
- setShowTip(true);
2470
- if (allowThirdDayDelivery) {
2471
- if (selectedShippingMethod.useCoupon) {
2472
- const method = freeTDD || freeShippingMethod;
2473
- if (method) setSelectedShippingMethod(method);
2474
- } else {
2475
- const method = paymentTDD || freeShippingMethod;
2476
- if (method) setSelectedShippingMethod(method);
2842
+ async function getSiteInfo(client, locale, metafieldIdentifiers) {
2843
+ const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2844
+ const query = (
2845
+ /* GraphQL */
2846
+ `
2847
+ query getSiteInfo(
2848
+ ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2849
+ ) @inContext(language: $language) {
2850
+ shop {
2851
+ name
2852
+ description
2853
+ primaryDomain {
2854
+ url
2855
+ host
2856
+ }
2857
+ brand {
2858
+ logo {
2859
+ image {
2860
+ url
2861
+ }
2862
+ }
2863
+ colors {
2864
+ primary {
2865
+ background
2866
+ }
2867
+ secondary {
2868
+ background
2477
2869
  }
2478
- } else {
2479
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2480
2870
  }
2481
- } else if (
2482
- // TDD 无法使用
2483
- selectedShippingMethod?.__mode === "tdd" /* TDD */ && !allowThirdDayDelivery
2484
- ) {
2485
- setShowTip(true);
2486
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2487
2871
  }
2872
+ ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2488
2873
  }
2489
2874
  }
2490
- }, [
2491
- allowNextDayDelivery,
2492
- allowThirdDayDelivery,
2493
- zipCode,
2494
- shippingMethodsContext,
2495
- selectedShippingMethod,
2496
- setSelectedShippingMethod,
2497
- setShowTip
2498
- ]);
2499
- }
2500
- var useReplaceCartPlusMember = () => {
2501
- const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
2502
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2503
- const { cart } = useCartContext();
2504
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2505
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2506
- const handler = react.useCallback(async () => {
2507
- const plusMonthlyInCart = cart?.lineItems.find(
2508
- (item) => item.variant?.sku === plusMonthly?.sku
2509
- );
2510
- const plusAnnualInCart = cart?.lineItems.find(
2511
- (item) => item.variant?.sku === plusAnnual?.sku
2512
- );
2513
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
2514
- await removeCartLines2({
2515
- lineIds: [plusMonthlyInCart.id]
2516
- });
2517
- } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
2518
- await removeCartLines2({
2519
- lineIds: [plusAnnualInCart.id]
2520
- });
2521
- }
2522
- }, [
2523
- cart?.lineItems,
2524
- selectedPlusMemberMode,
2525
- plusMonthly?.sku,
2526
- plusAnnual?.sku,
2527
- removeCartLines2
2528
- ]);
2529
- return handler;
2530
- };
2531
- var usePlusMemberDeliveryCodes = ({
2532
- deliveryData
2533
- }) => {
2534
- return react.useMemo(
2535
- () => deliveryData?.deliveryCustomData?.discount_code,
2536
- [deliveryData]
2875
+ `
2537
2876
  );
2538
- };
2539
- var usePlusMemberItemCustomAttributes = ({
2540
- deliveryData
2541
- }) => {
2542
- const { deliveryCustomData } = deliveryData || {};
2543
- return react.useMemo(() => {
2544
- const itemCustomAttributes = [];
2545
- if (deliveryCustomData?.is_presale) {
2546
- itemCustomAttributes.push({
2547
- key: "_is_presale",
2548
- value: "true"
2549
- });
2550
- }
2551
- return itemCustomAttributes;
2552
- }, [deliveryCustomData]);
2553
- };
2554
- var usePlusMemberCheckoutCustomAttributes = ({
2555
- deliveryData,
2556
- product,
2557
- variant,
2558
- customer,
2559
- isShowShippingBenefits
2560
- }) => {
2561
- const { deliveryCustomData } = deliveryData || {};
2562
- const { profile } = usePlusMemberContext();
2563
- const userType = react.useMemo(() => {
2564
- const customerInfo = customer;
2565
- if (!customerInfo) {
2566
- return "new_user_unlogin";
2567
- }
2568
- if (customer) {
2569
- const { orders = {} } = customer;
2570
- const edgesLength = orders?.edges?.length;
2571
- if (edgesLength === 1) {
2572
- return "old_user_orders_once";
2573
- } else if (edgesLength && edgesLength > 1) {
2574
- return "old_user_orders_twice";
2575
- }
2576
- }
2577
- return "new_user_login";
2578
- }, [customer]);
2579
- return react.useMemo(() => {
2580
- const checkoutCustomAttributes = [
2581
- {
2582
- key: "_token",
2583
- value: profile?.token || ""
2584
- },
2585
- {
2586
- key: "_last_url",
2587
- value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2588
- },
2589
- {
2590
- key: "_user_type",
2591
- value: userType
2592
- }
2593
- ];
2594
- if (profile) {
2595
- checkoutCustomAttributes.push({
2596
- key: "_login_user",
2597
- value: "1"
2598
- });
2599
- }
2600
- if (deliveryCustomData) {
2601
- checkoutCustomAttributes.push({
2602
- key: "_checkout_delivery_custom",
2603
- value: JSON.stringify({
2604
- ...deliveryCustomData,
2605
- is_prime: profile?.isPlus
2606
- })
2607
- });
2608
- }
2609
- if (variant?.metafields?.presell) {
2610
- checkoutCustomAttributes.push({
2611
- key: "_presale",
2612
- value: "true"
2613
- });
2614
- }
2615
- if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2616
- checkoutCustomAttributes.push({
2617
- key: "_hide_shipping",
2618
- value: "true"
2619
- });
2620
- }
2621
- return checkoutCustomAttributes;
2622
- }, [deliveryCustomData, product, profile, userType, variant, isShowShippingBenefits]);
2623
- };
2624
- function useAutoRemovePlusMemberInCart({
2625
- cart,
2626
- profile,
2627
- memberSetting
2628
- }) {
2629
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2630
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2631
- react.useEffect(() => {
2632
- if (!cart || !plus_monthly_product || !plus_annual_product) return;
2633
- const removePlusProduct = async (productType) => {
2634
- if (!productType) return;
2635
- const product = cart.lineItems?.find(
2636
- (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
2637
- );
2638
- if (product) {
2639
- await removeCartLines2({
2640
- lineIds: [product.id]
2641
- });
2642
- }
2643
- };
2644
- if (profile?.isMonthlyPlus) {
2645
- removePlusProduct(plus_monthly_product);
2646
- }
2647
- if (profile?.isAnnualPlus) {
2648
- removePlusProduct(plus_annual_product);
2649
- }
2650
- }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2651
- }
2652
- function useAddPlusMemberProductsToCart({
2653
- cart,
2654
- profile
2655
- }) {
2656
- const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
2657
- const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2658
- memberSetting: plusMemberMetafields,
2659
- cart
2660
- });
2661
- const plusMemberProduct = react.useMemo(() => {
2662
- if (!selectedPlusMemberProduct || selectedPlusMemberMode === "free" /* FREE */) {
2663
- return void 0;
2664
- }
2665
- if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2666
- return void 0;
2667
- }
2668
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2669
- return void 0;
2670
- }
2671
- if (profile.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2672
- return void 0;
2673
- }
2674
- if (!profile.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2675
- return void 0;
2877
+ const variables = {};
2878
+ if (hasMetafields) {
2879
+ variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2880
+ }
2881
+ const data = await client.query(query, variables);
2882
+ if (!data || !data.shop) {
2883
+ return void 0;
2884
+ }
2885
+ const shop = data.shop;
2886
+ const metafields = shop.metafields?.reduce((acc, mf) => {
2887
+ if (mf && mf.key) {
2888
+ acc[mf.key] = mf.value;
2676
2889
  }
2677
- return selectedPlusMemberProduct;
2678
- }, [
2679
- selectedPlusMemberMode,
2680
- selectedPlusMemberProduct?.variant,
2681
- selectedPlusMemberProduct?.product,
2682
- hasMonthlyPlus,
2683
- hasAnnualPlus
2684
- ]);
2685
- return plusMemberProduct;
2890
+ return acc;
2891
+ }, {});
2892
+ return {
2893
+ name: shop.name,
2894
+ description: shop.description,
2895
+ primaryDomain: shop.primaryDomain,
2896
+ brand: shop.brand ? {
2897
+ logo: shop.brand.logo,
2898
+ colors: shop.brand.colors ? {
2899
+ primary: shop.brand.colors.primary?.background,
2900
+ secondary: shop.brand.colors.secondary?.background
2901
+ } : void 0
2902
+ } : void 0,
2903
+ metafields
2904
+ };
2686
2905
  }
2687
- var PlusMemberProvider = ({
2688
- variant,
2689
- product,
2690
- memberSetting,
2691
- initialSelectedPlusMemberMode = "free",
2692
- profile,
2693
- locale,
2694
- children
2695
- }) => {
2696
- const [zipCode, setZipCode] = react.useState("");
2697
- const [showTip, setShowTip] = react.useState(false);
2698
- const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
2699
- initialSelectedPlusMemberMode
2700
- );
2701
- const [selectedShippingMethod, setSelectedShippingMethod] = react.useState();
2702
- const [allowNextDayDelivery, setAllowNextDayDelivery] = react.useState(false);
2703
- const [allowThirdDayDelivery, setAllowThirdDayDelivery] = react.useState(false);
2704
- const [showAreaCheckModal, setShowAreaCheckModal] = react.useState(false);
2705
- const [showMoreShippingMethod, setShowMoreShippingMethod] = react.useState(false);
2706
- const [showPlusMemberBenefit, setShowPlusMemberBenefit] = react.useState(false);
2707
- const [deleteMarginBottom, setDeleteMarginBottom] = react.useState(false);
2708
- const shippingMethodsContext = useShippingMethods({
2709
- variant,
2710
- plusMemberMetafields: memberSetting,
2711
- selectedPlusMemberMode});
2712
- const plusMemberHandles = react.useMemo(() => {
2713
- return [
2714
- memberSetting?.plus_monthly_product?.handle,
2715
- memberSetting?.plus_annual_product?.handle
2716
- ].filter(Boolean);
2717
- }, [memberSetting]);
2718
- const { data: plusMemberProducts = [] } = useProductsByHandles({
2719
- handles: plusMemberHandles
2720
- });
2721
- const selectedPlusMemberProduct = react.useMemo(() => {
2722
- if (selectedPlusMemberMode === "free" /* FREE */) {
2723
- return null;
2724
- }
2725
- const handle = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.handle : memberSetting?.plus_annual_product?.handle;
2726
- const sku = selectedPlusMemberMode === "monthly" /* MONTHLY */ ? memberSetting?.plus_monthly_product?.sku : memberSetting?.plus_annual_product?.sku;
2727
- const product2 = plusMemberProducts?.find((p) => p.handle === handle);
2728
- const variant2 = product2?.variants?.find((v) => v.sku === sku);
2729
- return product2 && variant2 ? { product: product2, variant: variant2 } : null;
2730
- }, [plusMemberProducts, memberSetting, selectedPlusMemberMode]);
2731
- return /* @__PURE__ */ jsxRuntime.jsx(
2732
- PlusMemberContext.Provider,
2733
- {
2734
- value: {
2735
- variant,
2736
- zipCode,
2737
- setZipCode,
2738
- allowNextDayDelivery,
2739
- setAllowNextDayDelivery,
2740
- allowThirdDayDelivery,
2741
- setAllowThirdDayDelivery,
2742
- plusMemberMetafields: memberSetting,
2743
- selectedPlusMemberMode,
2744
- setSelectedPlusMemberMode,
2745
- showAreaCheckModal,
2746
- setShowAreaCheckModal,
2747
- selectedShippingMethod,
2748
- setSelectedShippingMethod,
2749
- shippingMethodsContext,
2750
- showTip,
2751
- setShowTip,
2752
- showMoreShippingMethod,
2753
- setShowMoreShippingMethod,
2754
- selectedPlusMemberProduct,
2755
- plusMemberProducts,
2756
- product,
2757
- showPlusMemberBenefit,
2758
- setShowPlusMemberBenefit,
2759
- deleteMarginBottom,
2760
- setDeleteMarginBottom,
2761
- profile,
2762
- locale
2763
- },
2764
- children
2765
- }
2906
+ function useSite(options = {}) {
2907
+ const { client, locale } = useShopify();
2908
+ const { metafieldIdentifiers, ...swrOptions } = options;
2909
+ return useSWR__default.default(
2910
+ ["site", locale, metafieldIdentifiers],
2911
+ () => getSiteInfo(client, locale, metafieldIdentifiers),
2912
+ swrOptions
2766
2913
  );
2767
- };
2914
+ }
2768
2915
  function useIntersection(targetRef, options) {
2769
2916
  const {
2770
2917
  callback,
@@ -2951,6 +3098,7 @@ exports.CUSTOMER_ATTRIBUTE_KEY = CUSTOMER_ATTRIBUTE_KEY;
2951
3098
  exports.CUSTOMER_SCRIPT_GIFT_KEY = CUSTOMER_SCRIPT_GIFT_KEY;
2952
3099
  exports.DeliveryPlusType = DeliveryPlusType;
2953
3100
  exports.MAIN_PRODUCT_CODE = MAIN_PRODUCT_CODE;
3101
+ exports.MEMBER_PRICE_ATTRIBUTE_KEY = MEMBER_PRICE_ATTRIBUTE_KEY;
2954
3102
  exports.OrderBasePriceType = OrderBasePriceType;
2955
3103
  exports.OrderDiscountType = OrderDiscountType;
2956
3104
  exports.PLUS_MEMBER_TYPE = PLUS_MEMBER_TYPE;
@@ -2963,9 +3111,6 @@ exports.RuleType = RuleType;
2963
3111
  exports.SCRIPT_CODE_AMOUNT_KEY = SCRIPT_CODE_AMOUNT_KEY;
2964
3112
  exports.ShippingMethodMode = ShippingMethodMode;
2965
3113
  exports.SpendMoneyType = SpendMoneyType;
2966
- exports.atobID = atobID;
2967
- exports.btoaID = btoaID;
2968
- exports.checkAttributesUpdateNeeded = checkAttributesUpdateNeeded;
2969
3114
  exports.clearGeoLocationCache = clearGeoLocationCache;
2970
3115
  exports.createMockCartFromLines = createMockCartFromLines;
2971
3116
  exports.currencyCodeMapping = currencyCodeMapping;
@@ -2973,15 +3118,18 @@ exports.defaultSWRMutationConfiguration = defaultSWRMutationConfiguration;
2973
3118
  exports.formatFunctionAutoFreeGift = formatFunctionAutoFreeGift;
2974
3119
  exports.formatScriptAutoFreeGift = formatScriptAutoFreeGift;
2975
3120
  exports.getCachedGeoLocation = getCachedGeoLocation;
3121
+ exports.getCartAttributes = getCartAttributes;
2976
3122
  exports.getDiscountEnvAttributeValue = getDiscountEnvAttributeValue;
2977
3123
  exports.getMatchedMainProductSubTotal = getMatchedMainProductSubTotal;
2978
3124
  exports.getQuery = getQuery;
2979
3125
  exports.getReferralAttributes = getReferralAttributes;
3126
+ exports.getUserType = getUserType;
3127
+ exports.hasPlusMemberInCart = hasPlusMemberInCart;
3128
+ exports.hasPlusMemberInLines = hasPlusMemberInLines;
2980
3129
  exports.normalizeAddToCartLines = normalizeAddToCartLines;
2981
3130
  exports.preCheck = preCheck;
2982
3131
  exports.safeParse = safeParse;
2983
3132
  exports.useAddCartLines = useAddCartLines;
2984
- exports.useAddPlusMemberProductsToCart = useAddPlusMemberProductsToCart;
2985
3133
  exports.useAddToCart = useAddToCart;
2986
3134
  exports.useAllBlogs = useAllBlogs;
2987
3135
  exports.useAllCollections = useAllCollections;
@@ -2991,6 +3139,7 @@ exports.useArticle = useArticle;
2991
3139
  exports.useArticles = useArticles;
2992
3140
  exports.useArticlesInBlog = useArticlesInBlog;
2993
3141
  exports.useAutoRemovePlusMemberInCart = useAutoRemovePlusMemberInCart;
3142
+ exports.useAvailableDeliveryCoupon = useAvailableDeliveryCoupon;
2994
3143
  exports.useBlog = useBlog;
2995
3144
  exports.useBuyNow = useBuyNow;
2996
3145
  exports.useCalcAutoFreeGift = useCalcAutoFreeGift;
@@ -3004,13 +3153,12 @@ exports.useCreateCart = useCreateCart;
3004
3153
  exports.useExposure = useExposure;
3005
3154
  exports.useGeoLocation = useGeoLocation;
3006
3155
  exports.useHasPlusMemberInCart = useHasPlusMemberInCart;
3156
+ exports.useHasPlusMemberInLines = useHasPlusMemberInLines;
3007
3157
  exports.useIntersection = useIntersection;
3008
- exports.usePlusAnnualProductVariant = usePlusAnnualProductVariant;
3009
3158
  exports.usePlusMemberCheckoutCustomAttributes = usePlusMemberCheckoutCustomAttributes;
3010
3159
  exports.usePlusMemberContext = usePlusMemberContext;
3011
- exports.usePlusMemberDeliveryCodes = usePlusMemberDeliveryCodes;
3012
- exports.usePlusMemberItemCustomAttributes = usePlusMemberItemCustomAttributes;
3013
- exports.usePlusMonthlyProductVariant = usePlusMonthlyProductVariant;
3160
+ exports.usePlusMemberNeedAddToCart = usePlusMemberNeedAddToCart;
3161
+ exports.usePlusMemberVariants = usePlusMemberVariants;
3014
3162
  exports.usePrice = usePrice;
3015
3163
  exports.useProduct = useProduct;
3016
3164
  exports.useProductUrl = useProductUrl;
@@ -3021,7 +3169,6 @@ exports.useReplaceCartPlusMember = useReplaceCartPlusMember;
3021
3169
  exports.useScriptAutoFreeGift = useScriptAutoFreeGift;
3022
3170
  exports.useSearch = useSearch;
3023
3171
  exports.useSelectedOptions = useSelectedOptions;
3024
- exports.useShippingMethodAvailableCheck = useShippingMethodAvailableCheck;
3025
3172
  exports.useShippingMethods = useShippingMethods;
3026
3173
  exports.useSite = useSite;
3027
3174
  exports.useUpdateCartAttributes = useUpdateCartAttributes;