@anker-in/shopify-react 0.1.1-beta.9 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/index.d.mts +18 -3
- package/dist/adapters/index.d.ts +18 -3
- package/dist/adapters/index.js +15 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/index.mjs +15 -1
- package/dist/adapters/index.mjs.map +1 -1
- package/dist/hooks/index.d.mts +1984 -9
- package/dist/hooks/index.d.ts +1984 -9
- package/dist/hooks/index.js +1733 -1652
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +1725 -1643
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1827 -1710
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1812 -1677
- package/dist/index.mjs.map +1 -1
- package/dist/provider/index.d.mts +29 -15
- package/dist/provider/index.d.ts +29 -15
- package/dist/provider/index.js +403 -325
- package/dist/provider/index.js.map +1 -1
- package/dist/provider/index.mjs +403 -325
- package/dist/provider/index.mjs.map +1 -1
- package/dist/{types-CICUnw0v.d.mts → types-CMMWxyUF.d.mts} +12 -58
- package/dist/{types-CICUnw0v.d.ts → types-CMMWxyUF.d.ts} +12 -58
- package/dist/{types-BLMoxbOk.d.mts → types-SKDHauqk.d.mts} +14 -9
- package/dist/{types-BLMoxbOk.d.ts → types-SKDHauqk.d.ts} +14 -9
- package/package.json +5 -5
- package/dist/index-DMLI1Lh0.d.ts +0 -1982
- package/dist/index-DyExTsmO.d.mts +0 -1982
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ var shopifySdk = require('@anker-in/shopify-sdk');
|
|
|
5
5
|
var Cookies5 = require('js-cookie');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
var Decimal2 = require('decimal.js');
|
|
8
|
+
var shopifyCore = require('@anker-in/shopify-core');
|
|
8
9
|
var useSWR = require('swr');
|
|
9
10
|
var useSWRMutation = require('swr/mutation');
|
|
10
11
|
var ahooks = require('ahooks');
|
|
@@ -53,6 +54,20 @@ var browserCartCookieAdapter = {
|
|
|
53
54
|
Cookies5__default.default.remove(getCartCookieName(locale));
|
|
54
55
|
}
|
|
55
56
|
};
|
|
57
|
+
|
|
58
|
+
// src/adapters/browser-performance.ts
|
|
59
|
+
var BrowserPerformanceAdapter = class {
|
|
60
|
+
/**
|
|
61
|
+
* Start tracking a performance event
|
|
62
|
+
*/
|
|
63
|
+
addToCartStart() {
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* End tracking a performance event
|
|
67
|
+
*/
|
|
68
|
+
addToCartEnd() {
|
|
69
|
+
}
|
|
70
|
+
};
|
|
56
71
|
function ShopifyProvider({
|
|
57
72
|
config,
|
|
58
73
|
locale,
|
|
@@ -61,7 +76,8 @@ function ShopifyProvider({
|
|
|
61
76
|
cartCookieAdapter = browserCartCookieAdapter,
|
|
62
77
|
routerAdapter,
|
|
63
78
|
userAdapter,
|
|
64
|
-
children
|
|
79
|
+
children,
|
|
80
|
+
performanceAdapter
|
|
65
81
|
}) {
|
|
66
82
|
const client = react.useMemo(() => {
|
|
67
83
|
return shopifySdk.createShopifyClient(config, locale);
|
|
@@ -75,7 +91,8 @@ function ShopifyProvider({
|
|
|
75
91
|
cookieAdapter,
|
|
76
92
|
cartCookieAdapter,
|
|
77
93
|
routerAdapter,
|
|
78
|
-
userAdapter
|
|
94
|
+
userAdapter,
|
|
95
|
+
performanceAdapter
|
|
79
96
|
};
|
|
80
97
|
}, [
|
|
81
98
|
client,
|
|
@@ -85,6 +102,7 @@ function ShopifyProvider({
|
|
|
85
102
|
cookieAdapter,
|
|
86
103
|
cartCookieAdapter,
|
|
87
104
|
routerAdapter,
|
|
105
|
+
performanceAdapter,
|
|
88
106
|
userAdapter
|
|
89
107
|
]);
|
|
90
108
|
return /* @__PURE__ */ jsxRuntime.jsx(ShopifyContext.Provider, { value, children });
|
|
@@ -140,6 +158,7 @@ var CUSTOMER_ATTRIBUTE_KEY = "_discounts_function_env";
|
|
|
140
158
|
var CUSTOMER_SCRIPT_GIFT_KEY = "_giveaway_gradient_gifts";
|
|
141
159
|
var CODE_AMOUNT_KEY = "_sku_code_money";
|
|
142
160
|
var SCRIPT_CODE_AMOUNT_KEY = "_code_money";
|
|
161
|
+
var MEMBER_PRICE_ATTRIBUTE_KEY = "_member_price";
|
|
143
162
|
var MAIN_PRODUCT_CODE = ["WS24", "WSTD", "WS7D", "WSCP", "WSPE", "WSPD"];
|
|
144
163
|
|
|
145
164
|
// src/hooks/cart/utils/normalize-add-to-cart-lines.ts
|
|
@@ -148,9 +167,10 @@ function normalizeAddToCartLines(lines) {
|
|
|
148
167
|
const variant = line.variant;
|
|
149
168
|
const product = variant.product;
|
|
150
169
|
const quantity = line.quantity || 1;
|
|
151
|
-
const
|
|
152
|
-
const
|
|
153
|
-
const
|
|
170
|
+
const originalPrice = variant.price?.amount ? Number(variant.price.amount) : 0;
|
|
171
|
+
const finalPrice = variant.finalPrice?.amount === void 0 ? originalPrice : Number(variant.finalPrice?.amount);
|
|
172
|
+
const subtotalAmount = originalPrice * quantity;
|
|
173
|
+
const totalAmount = finalPrice * quantity;
|
|
154
174
|
return {
|
|
155
175
|
id: `temp-line-${index}-${variant.id}`,
|
|
156
176
|
// Temporary ID for pre-cart lines
|
|
@@ -164,7 +184,7 @@ function normalizeAddToCartLines(lines) {
|
|
|
164
184
|
customAttributes: line.attributes || [],
|
|
165
185
|
variant: {
|
|
166
186
|
id: variant.id,
|
|
167
|
-
price,
|
|
187
|
+
price: finalPrice,
|
|
168
188
|
listPrice: variant.compareAtPrice?.amount ? Number(variant.compareAtPrice.amount) : 0,
|
|
169
189
|
sku: variant.sku || "",
|
|
170
190
|
name: variant.title || "",
|
|
@@ -195,12 +215,13 @@ function createMockCartFromLines(lines, existingCart) {
|
|
|
195
215
|
const normalizedLines = normalizeAddToCartLines(lines);
|
|
196
216
|
const subtotalPrice = normalizedLines.reduce((sum, line) => sum + line.subtotalAmount, 0);
|
|
197
217
|
const totalPrice = normalizedLines.reduce((sum, line) => sum + line.totalAmount, 0);
|
|
218
|
+
const currency = lines[0]?.variant?.price?.currencyCode;
|
|
198
219
|
return {
|
|
199
220
|
id: existingCart?.id || "temp-cart-id",
|
|
200
221
|
customerId: existingCart?.customerId,
|
|
201
222
|
email: existingCart?.email,
|
|
202
223
|
createdAt: existingCart?.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
203
|
-
currency: existingCart?.currency || { code:
|
|
224
|
+
currency: existingCart?.currency || { code: currency },
|
|
204
225
|
taxesIncluded: existingCart?.taxesIncluded,
|
|
205
226
|
lineItems: normalizedLines,
|
|
206
227
|
totalLineItemsDiscount: 0,
|
|
@@ -234,22 +255,12 @@ var getQuery = () => {
|
|
|
234
255
|
}
|
|
235
256
|
return theRequest;
|
|
236
257
|
};
|
|
237
|
-
function atobID(id) {
|
|
238
|
-
if (id && typeof id === "string" && id.includes("/")) {
|
|
239
|
-
return id.split("/").pop()?.split("?")?.shift();
|
|
240
|
-
} else {
|
|
241
|
-
return id;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
function btoaID(id, type = "ProductVariant") {
|
|
245
|
-
return `gid://shopify/${type}/${id}`;
|
|
246
|
-
}
|
|
247
258
|
var getMatchedMainProductSubTotal = (cartData, variant_list, main_product) => {
|
|
248
259
|
const isAllStoreVariant = main_product?.all_store_variant ?? false;
|
|
249
260
|
const matchedList = cartData?.lineItems?.filter((line) => {
|
|
250
261
|
const { is_gift } = getDiscountEnvAttributeValue(line.customAttributes);
|
|
251
262
|
return isAllStoreVariant ? !is_gift : variant_list?.find((item) => {
|
|
252
|
-
return !is_gift && atobID(line.variantId) === item;
|
|
263
|
+
return !is_gift && shopifyCore.atobID(line.variantId) === item;
|
|
253
264
|
});
|
|
254
265
|
});
|
|
255
266
|
return matchedList?.reduce((acc, line) => {
|
|
@@ -267,14 +278,6 @@ var getDiscountEnvAttributeValue = (attributes = []) => {
|
|
|
267
278
|
const attr = attributes.find((attr2) => attr2.key === CUSTOMER_ATTRIBUTE_KEY);
|
|
268
279
|
return safeParse(attr?.value ?? "") ?? {};
|
|
269
280
|
};
|
|
270
|
-
var checkAttributesUpdateNeeded = (oldAttributes, newAttributes, customAttributesNeedRemove) => {
|
|
271
|
-
return oldAttributes.some((attr) => {
|
|
272
|
-
const newAttr = newAttributes.find((newAttr2) => newAttr2.key === attr.key);
|
|
273
|
-
return newAttr ? newAttr.value !== attr.value : true;
|
|
274
|
-
}) || newAttributes.some((attr) => !oldAttributes.some((oldAttr) => oldAttr.key === attr.key)) || customAttributesNeedRemove.some(
|
|
275
|
-
(removeAttr) => oldAttributes.some((oldAttr) => oldAttr.key === removeAttr.key)
|
|
276
|
-
);
|
|
277
|
-
};
|
|
278
281
|
var containsAll = (source, requiredItems = []) => {
|
|
279
282
|
if (!requiredItems?.length) return true;
|
|
280
283
|
const sourceSet = new Set(source);
|
|
@@ -475,43 +478,29 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
|
|
|
475
478
|
}
|
|
476
479
|
return { activeCampaign: null, subtotal: 0 };
|
|
477
480
|
}, [autoFreeGiftConfig, effectiveCart, tags, dealsType]);
|
|
478
|
-
const {
|
|
481
|
+
const { qualifyingTier, nextTierGoal, actualThreshold, currentCurrency } = react.useMemo(() => {
|
|
479
482
|
if (!activeCampaign || !activeCampaign.rule_result?.spend_get_reward?.gift_product) {
|
|
480
|
-
return {
|
|
483
|
+
return { qualifyingTier: null, nextTierGoal: null, actualThreshold: 0, currentCurrency: "" };
|
|
481
484
|
}
|
|
482
485
|
const giftTiers = activeCampaign.rule_result.spend_get_reward.gift_product;
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
tier
|
|
490
|
-
itemsToAdd: qualifyingTier.reward_list?.map((reward) => {
|
|
491
|
-
const giftProduct = reward?.variant_list?.[0];
|
|
492
|
-
if (!giftProduct) return null;
|
|
493
|
-
return {
|
|
494
|
-
variant: {
|
|
495
|
-
id: btoaID(giftProduct.variant_id),
|
|
496
|
-
handle: giftProduct.handle,
|
|
497
|
-
sku: giftProduct.sku
|
|
498
|
-
},
|
|
499
|
-
quantity: reward?.get_unit || 1,
|
|
500
|
-
attributes: [
|
|
501
|
-
{
|
|
502
|
-
key: CUSTOMER_ATTRIBUTE_KEY,
|
|
503
|
-
value: JSON.stringify({
|
|
504
|
-
is_gift: true,
|
|
505
|
-
rule_id: activeCampaign.rule_id,
|
|
506
|
-
spend_sum_money: qualifyingTier.spend_sum_money
|
|
507
|
-
})
|
|
508
|
-
}
|
|
509
|
-
]
|
|
510
|
-
};
|
|
511
|
-
}).filter((item) => item !== null)
|
|
486
|
+
const currentCurrency2 = effectiveCart?.currency?.code || "";
|
|
487
|
+
console.log("currentCurrency useCalcAutoFreeGift", effectiveCart, currentCurrency2);
|
|
488
|
+
const getThresholdAmount = (tier) => {
|
|
489
|
+
if (tier.spend_sum_money_multi_markets?.[currentCurrency2]?.value) {
|
|
490
|
+
return Number(tier.spend_sum_money_multi_markets[currentCurrency2].value);
|
|
491
|
+
}
|
|
492
|
+
return Number(tier.spend_sum_money || 0);
|
|
512
493
|
};
|
|
513
|
-
|
|
514
|
-
|
|
494
|
+
const qualifyingTier2 = [...giftTiers].sort((a, b) => getThresholdAmount(b) - getThresholdAmount(a)).find((tier) => subtotal >= getThresholdAmount(tier));
|
|
495
|
+
const nextGoal = giftTiers.find((tier) => subtotal < getThresholdAmount(tier));
|
|
496
|
+
const actualThreshold2 = qualifyingTier2 ? getThresholdAmount(qualifyingTier2) : 0;
|
|
497
|
+
return {
|
|
498
|
+
qualifyingTier: qualifyingTier2,
|
|
499
|
+
nextTierGoal: nextGoal || null,
|
|
500
|
+
actualThreshold: actualThreshold2,
|
|
501
|
+
currentCurrency: currentCurrency2
|
|
502
|
+
};
|
|
503
|
+
}, [activeCampaign, subtotal, effectiveCart]);
|
|
515
504
|
const giftHandles = react.useMemo(() => {
|
|
516
505
|
const giftVariant = autoFreeGiftConfig.map(
|
|
517
506
|
(item) => item.rule_result?.spend_get_reward?.gift_product?.map(
|
|
@@ -527,24 +516,82 @@ var useCalcAutoFreeGift = (cart, autoFreeGiftConfig, customer, lines) => {
|
|
|
527
516
|
}
|
|
528
517
|
return true;
|
|
529
518
|
}, [giftHandles]);
|
|
530
|
-
const { data: giftProductsResult } = useSWR__default.default(
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
519
|
+
const { data: giftProductsResult } = useSWR__default.default(
|
|
520
|
+
shouldFetch ? giftHandles : null,
|
|
521
|
+
async () => {
|
|
522
|
+
const res = await shopifySdk.getProductsByHandles(client, {
|
|
523
|
+
handles: giftHandles,
|
|
524
|
+
locale
|
|
525
|
+
});
|
|
526
|
+
const result = Array.isArray(res) ? res : [];
|
|
527
|
+
giftProductsCache.current = {
|
|
528
|
+
data: result,
|
|
529
|
+
giftHandles: [...giftHandles]
|
|
530
|
+
};
|
|
531
|
+
return result;
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
revalidateOnFocus: false
|
|
535
|
+
}
|
|
536
|
+
);
|
|
542
537
|
const finalGiftProductsResult = react.useMemo(() => {
|
|
543
538
|
if (giftProductsCache.current && !shouldFetch) {
|
|
544
539
|
return giftProductsCache.current.data || void 0;
|
|
545
540
|
}
|
|
546
541
|
return giftProductsResult;
|
|
547
542
|
}, [giftProductsResult, shouldFetch]);
|
|
543
|
+
const qualifyingGift = react.useMemo(() => {
|
|
544
|
+
if (!qualifyingTier || !activeCampaign) {
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
const itemsToAdd = qualifyingTier.reward_list?.map((reward) => {
|
|
548
|
+
if (!reward.variant_list || reward.variant_list.length === 0) {
|
|
549
|
+
return null;
|
|
550
|
+
}
|
|
551
|
+
let selectedGiftProduct = null;
|
|
552
|
+
for (const giftVariant of reward.variant_list) {
|
|
553
|
+
const productInfo = finalGiftProductsResult?.find(
|
|
554
|
+
(p) => p.handle === giftVariant.handle
|
|
555
|
+
);
|
|
556
|
+
if (productInfo) {
|
|
557
|
+
const variantInfo = productInfo.variants?.find((v) => v.sku === giftVariant.sku);
|
|
558
|
+
if (variantInfo?.availableForSale) {
|
|
559
|
+
selectedGiftProduct = giftVariant;
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
if (!selectedGiftProduct) {
|
|
565
|
+
selectedGiftProduct = reward.variant_list[0];
|
|
566
|
+
}
|
|
567
|
+
return {
|
|
568
|
+
variant: {
|
|
569
|
+
id: shopifyCore.btoaID(selectedGiftProduct.variant_id),
|
|
570
|
+
handle: selectedGiftProduct.handle,
|
|
571
|
+
sku: selectedGiftProduct.sku
|
|
572
|
+
},
|
|
573
|
+
quantity: reward?.get_unit || 1,
|
|
574
|
+
attributes: [
|
|
575
|
+
{
|
|
576
|
+
key: CUSTOMER_ATTRIBUTE_KEY,
|
|
577
|
+
value: JSON.stringify({
|
|
578
|
+
is_gift: true,
|
|
579
|
+
rule_id: activeCampaign.rule_id,
|
|
580
|
+
spend_sum_money: actualThreshold,
|
|
581
|
+
// 使用实际的门槛金额(多币种支持)
|
|
582
|
+
currency_code: currentCurrency
|
|
583
|
+
// 记录当前币种
|
|
584
|
+
})
|
|
585
|
+
}
|
|
586
|
+
]
|
|
587
|
+
};
|
|
588
|
+
}).filter((item) => item !== null);
|
|
589
|
+
const formattedGift = {
|
|
590
|
+
tier: qualifyingTier,
|
|
591
|
+
itemsToAdd
|
|
592
|
+
};
|
|
593
|
+
return formattedGift;
|
|
594
|
+
}, [qualifyingTier, activeCampaign, finalGiftProductsResult, actualThreshold, currentCurrency]);
|
|
548
595
|
return {
|
|
549
596
|
qualifyingGift,
|
|
550
597
|
nextTierGoal,
|
|
@@ -558,7 +605,8 @@ var useScriptAutoFreeGift = ({
|
|
|
558
605
|
_giveaway,
|
|
559
606
|
cart,
|
|
560
607
|
locale: providedLocale,
|
|
561
|
-
lines
|
|
608
|
+
lines,
|
|
609
|
+
profile
|
|
562
610
|
}) => {
|
|
563
611
|
const { client, locale: contextLocale } = useShopify();
|
|
564
612
|
const locale = providedLocale || contextLocale;
|
|
@@ -582,8 +630,9 @@ var useScriptAutoFreeGift = ({
|
|
|
582
630
|
const utmCampaign = Cookies5__default.default.get("utm_campaign") || query?.utm_campaign;
|
|
583
631
|
if (campaign.activityAvailableQuery && !utmCampaign?.includes(campaign.activityAvailableQuery))
|
|
584
632
|
return false;
|
|
633
|
+
if (campaign.requireLogin && !profile?.email) return false;
|
|
585
634
|
return true;
|
|
586
|
-
}, [campaign]);
|
|
635
|
+
}, [campaign, profile]);
|
|
587
636
|
const [upgrade_multiple, upgrade_value] = react.useMemo(() => {
|
|
588
637
|
let upgrade_multiple2 = 1;
|
|
589
638
|
let upgrade_value2 = 0;
|
|
@@ -591,12 +640,14 @@ var useScriptAutoFreeGift = ({
|
|
|
591
640
|
upgrade_multiple2 = 1.2;
|
|
592
641
|
upgrade_value2 = 40;
|
|
593
642
|
}
|
|
594
|
-
effectiveCart?.lineItems?.forEach(
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
643
|
+
effectiveCart?.lineItems?.forEach(
|
|
644
|
+
({ customAttributes }) => {
|
|
645
|
+
customAttributes?.forEach(({ key, value }) => {
|
|
646
|
+
if (key === "_amount_upgrade_multiple") upgrade_multiple2 = Number(value) || 1;
|
|
647
|
+
if (key === "_amount_upgrade_value") upgrade_value2 = Number(value) || 0;
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
);
|
|
600
651
|
return [upgrade_multiple2, upgrade_value2];
|
|
601
652
|
}, [effectiveCart?.lineItems, points_subscribe]);
|
|
602
653
|
const breakpoints = react.useMemo(() => {
|
|
@@ -661,18 +712,24 @@ var useScriptAutoFreeGift = ({
|
|
|
661
712
|
const nextLevel = levelIndex > 0 ? sortedLevels[levelIndex - 1] ?? null : null;
|
|
662
713
|
return [currentLevel, nextLevel];
|
|
663
714
|
}, [breakpoints, involvedSubTotal, involvedLines.length]);
|
|
664
|
-
const { data: giftProductsResult } = useSWR__default.default(
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
715
|
+
const { data: giftProductsResult } = useSWR__default.default(
|
|
716
|
+
shouldFetch ? giftHandles : null,
|
|
717
|
+
async () => {
|
|
718
|
+
const res = await shopifySdk.getProductsByHandles(client, {
|
|
719
|
+
handles: giftHandles,
|
|
720
|
+
locale
|
|
721
|
+
});
|
|
722
|
+
const result = Array.isArray(res) ? res : [];
|
|
723
|
+
giftProductsCache.current = {
|
|
724
|
+
data: result,
|
|
725
|
+
giftHandles: [...giftHandles]
|
|
726
|
+
};
|
|
727
|
+
return result;
|
|
728
|
+
},
|
|
729
|
+
{
|
|
730
|
+
revalidateOnFocus: false
|
|
731
|
+
}
|
|
732
|
+
);
|
|
676
733
|
const finalGiftProductsResult = react.useMemo(() => {
|
|
677
734
|
if (giftProductsCache.current && !shouldFetch) {
|
|
678
735
|
return giftProductsCache.current.data || void 0;
|
|
@@ -704,7 +761,20 @@ var useScriptAutoFreeGift = ({
|
|
|
704
761
|
giftProductsResult: finalGiftProductsResult
|
|
705
762
|
};
|
|
706
763
|
};
|
|
707
|
-
|
|
764
|
+
|
|
765
|
+
// src/hooks/cart/utils/cart-attributes.ts
|
|
766
|
+
var checkAttributesUpdateNeeded = (oldAttributes, newAttributes, customAttributesNeedRemove) => {
|
|
767
|
+
return newAttributes.some((attr) => !oldAttributes.some((oldAttr) => oldAttr.key === attr.key)) || oldAttributes.some((attr) => {
|
|
768
|
+
const newAttr = newAttributes.find((newAttr2) => newAttr2.key === attr.key);
|
|
769
|
+
return newAttr ? newAttr.value !== attr.value : true;
|
|
770
|
+
}) || customAttributesNeedRemove.some(
|
|
771
|
+
(removeAttr) => oldAttributes.some((oldAttr) => oldAttr.key === removeAttr.key)
|
|
772
|
+
);
|
|
773
|
+
};
|
|
774
|
+
function useCreateCart({
|
|
775
|
+
updateCookie = false,
|
|
776
|
+
options
|
|
777
|
+
}) {
|
|
708
778
|
const { client, locale, cartCookieAdapter } = useShopify();
|
|
709
779
|
const { mutateCart, metafieldIdentifiers } = useCartContext();
|
|
710
780
|
const createNewCart = react.useCallback(
|
|
@@ -712,7 +782,8 @@ function useCreateCart(options) {
|
|
|
712
782
|
let newCart = await shopifySdk.createCart(client, {
|
|
713
783
|
...arg,
|
|
714
784
|
metafieldIdentifiers,
|
|
715
|
-
cookieAdapter: cartCookieAdapter
|
|
785
|
+
cookieAdapter: cartCookieAdapter,
|
|
786
|
+
updateCookie
|
|
716
787
|
});
|
|
717
788
|
if (newCart) {
|
|
718
789
|
const unApplicableCodes = newCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
|
|
@@ -739,11 +810,23 @@ function useAddCartLines(options) {
|
|
|
739
810
|
const { mutateCart, metafieldIdentifiers } = useCartContext();
|
|
740
811
|
const addLines = react.useCallback(
|
|
741
812
|
async (_key, { arg }) => {
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
813
|
+
const { cartId, lines } = arg;
|
|
814
|
+
const id = cartId || cartCookieAdapter?.getCartId(locale);
|
|
815
|
+
let updatedCart;
|
|
816
|
+
if (!id) {
|
|
817
|
+
updatedCart = await shopifySdk.createCart(client, {
|
|
818
|
+
lines,
|
|
819
|
+
metafieldIdentifiers,
|
|
820
|
+
cookieAdapter: cartCookieAdapter
|
|
821
|
+
});
|
|
822
|
+
} else {
|
|
823
|
+
updatedCart = await shopifySdk.addCartLines(client, {
|
|
824
|
+
cartId: id,
|
|
825
|
+
lines,
|
|
826
|
+
metafieldIdentifiers,
|
|
827
|
+
cookieAdapter: cartCookieAdapter
|
|
828
|
+
});
|
|
829
|
+
}
|
|
747
830
|
if (updatedCart) {
|
|
748
831
|
const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
|
|
749
832
|
if (unApplicableCodes.length > 0) {
|
|
@@ -790,7 +873,7 @@ var trackAddToCartGA = ({
|
|
|
790
873
|
const currencyCode = variant.product?.price?.currencyCode;
|
|
791
874
|
const totalPrice = lineItems?.reduce(
|
|
792
875
|
(prev, { variant: variant2 }) => prev.plus(
|
|
793
|
-
variant2?.finalPrice?.amount
|
|
876
|
+
variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
|
|
794
877
|
),
|
|
795
878
|
new Decimal2__default.default(0)
|
|
796
879
|
).toNumber();
|
|
@@ -825,7 +908,7 @@ var trackBeginCheckoutGA = ({
|
|
|
825
908
|
}
|
|
826
909
|
const totalPrice = lineItems?.reduce(
|
|
827
910
|
(prev, { variant }) => prev.plus(
|
|
828
|
-
variant?.finalPrice?.amount
|
|
911
|
+
variant?.finalPrice?.amount === void 0 ? Number(variant?.price?.amount) || 0 : Number(variant?.finalPrice?.amount) || 0
|
|
829
912
|
),
|
|
830
913
|
new Decimal2__default.default(0)
|
|
831
914
|
).toNumber();
|
|
@@ -858,10 +941,10 @@ var trackBuyNowGA = ({
|
|
|
858
941
|
return;
|
|
859
942
|
}
|
|
860
943
|
const { variant } = lineItems[0];
|
|
861
|
-
const currencyCode = variant.price?.currencyCode;
|
|
944
|
+
const currencyCode = variant.product?.price?.currencyCode || variant.price?.currencyCode;
|
|
862
945
|
const totalPrice = lineItems?.reduce(
|
|
863
946
|
(prev, { variant: variant2 }) => prev.plus(
|
|
864
|
-
variant2?.finalPrice?.amount
|
|
947
|
+
variant2?.finalPrice?.amount === void 0 ? Number(variant2?.price?.amount) || 0 : Number(variant2?.finalPrice?.amount) || 0
|
|
865
948
|
),
|
|
866
949
|
new Decimal2__default.default(0)
|
|
867
950
|
).toNumber();
|
|
@@ -935,7 +1018,7 @@ function useApplyCartCodes(options) {
|
|
|
935
1018
|
if (!discountCodes?.length) {
|
|
936
1019
|
throw new Error("Invalid input used for this operation: Miss discountCode");
|
|
937
1020
|
}
|
|
938
|
-
const cartId = providedCartId
|
|
1021
|
+
const cartId = providedCartId || cart?.id;
|
|
939
1022
|
if (!cartId) {
|
|
940
1023
|
return void 0;
|
|
941
1024
|
}
|
|
@@ -948,12 +1031,18 @@ function useApplyCartCodes(options) {
|
|
|
948
1031
|
cookieAdapter: cartCookieAdapter,
|
|
949
1032
|
metafieldIdentifiers
|
|
950
1033
|
});
|
|
1034
|
+
const unApplicableCodes = discountCodes.filter(
|
|
1035
|
+
(code) => updatedCart?.discountCodes?.find((item) => item.code === code && !item.applicable)
|
|
1036
|
+
);
|
|
1037
|
+
if (unApplicableCodes.length) {
|
|
1038
|
+
throw new Error(`${unApplicableCodes.join(", ")} is not applicable to the cart`);
|
|
1039
|
+
}
|
|
951
1040
|
if (updatedCart) {
|
|
952
1041
|
mutateCart(updatedCart);
|
|
953
1042
|
}
|
|
954
1043
|
return updatedCart;
|
|
955
1044
|
},
|
|
956
|
-
[client, locale, cartCookieAdapter, mutateCart, cart]
|
|
1045
|
+
[client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
|
|
957
1046
|
);
|
|
958
1047
|
return useSWRMutation__default.default("apply-codes", applyCodes, options);
|
|
959
1048
|
}
|
|
@@ -963,7 +1052,7 @@ function useRemoveCartCodes(options) {
|
|
|
963
1052
|
const removeCodes = react.useCallback(
|
|
964
1053
|
async (_key, { arg }) => {
|
|
965
1054
|
const { cartId: providedCartId, discountCodes } = arg;
|
|
966
|
-
const cartId = providedCartId
|
|
1055
|
+
const cartId = providedCartId || cart?.id;
|
|
967
1056
|
const codes = cart?.discountCodes?.filter((code) => !!code.applicable) || [];
|
|
968
1057
|
const leftCodes = codes.filter((code) => discountCodes?.length ? !discountCodes.includes(code.code) : code.code).map((code) => code.code);
|
|
969
1058
|
const updatedCart = await shopifySdk.updateCartCodes(client, {
|
|
@@ -977,225 +1066,96 @@ function useRemoveCartCodes(options) {
|
|
|
977
1066
|
}
|
|
978
1067
|
return updatedCart;
|
|
979
1068
|
},
|
|
980
|
-
[client, locale, cartCookieAdapter, mutateCart, cart]
|
|
1069
|
+
[client, locale, cartCookieAdapter, mutateCart, cart, metafieldIdentifiers]
|
|
981
1070
|
);
|
|
982
1071
|
return useSWRMutation__default.default("remove-codes", removeCodes, options);
|
|
983
1072
|
}
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
const
|
|
989
|
-
|
|
990
|
-
const { trigger: removeInvalidCodes } = useRemoveCartCodes();
|
|
991
|
-
const { trigger: addCartLines2 } = useAddCartLines();
|
|
992
|
-
const addToCart = react.useCallback(
|
|
993
|
-
async (_key, { arg }) => {
|
|
994
|
-
const {
|
|
995
|
-
lineItems,
|
|
996
|
-
cartId: providedCartId,
|
|
997
|
-
discountCodes,
|
|
998
|
-
gtmParams = {},
|
|
999
|
-
buyerIdentity,
|
|
1000
|
-
needCreateCart = false,
|
|
1001
|
-
onCodesInvalid,
|
|
1002
|
-
replaceExistingCodes
|
|
1003
|
-
} = arg;
|
|
1004
|
-
if (!lineItems || lineItems.length === 0) {
|
|
1005
|
-
return;
|
|
1006
|
-
}
|
|
1007
|
-
const lines = lineItems.map((item) => ({
|
|
1008
|
-
merchandiseId: item.variant?.id || "",
|
|
1009
|
-
quantity: item.quantity || 1,
|
|
1010
|
-
attributes: item.attributes,
|
|
1011
|
-
sellingPlanId: item.sellingPlanId
|
|
1012
|
-
})).filter((item) => item.merchandiseId && item.quantity);
|
|
1013
|
-
if (lines.length === 0) {
|
|
1014
|
-
return;
|
|
1015
|
-
}
|
|
1016
|
-
const cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
|
|
1017
|
-
let resultCart = await addCartLines2({
|
|
1018
|
-
cartId,
|
|
1019
|
-
lines,
|
|
1020
|
-
buyerIdentity
|
|
1021
|
-
});
|
|
1022
|
-
if (!resultCart) {
|
|
1023
|
-
return void 0;
|
|
1024
|
-
}
|
|
1025
|
-
console.log("npm addCartLines resultCart", resultCart);
|
|
1026
|
-
if (resultCart.discountCodes && resultCart.discountCodes.length > 0) {
|
|
1027
|
-
const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
|
|
1028
|
-
if (unapplicableCodes.length > 0) {
|
|
1029
|
-
if (onCodesInvalid) {
|
|
1030
|
-
const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
|
|
1031
|
-
if (handledCart) {
|
|
1032
|
-
resultCart = handledCart;
|
|
1033
|
-
}
|
|
1034
|
-
} else {
|
|
1035
|
-
await removeInvalidCodes({
|
|
1036
|
-
discountCodes: unapplicableCodes
|
|
1037
|
-
});
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
if (discountCodes && discountCodes.length > 0) {
|
|
1042
|
-
applyCartCodes({
|
|
1043
|
-
replaceExistingCodes,
|
|
1044
|
-
discountCodes
|
|
1045
|
-
});
|
|
1046
|
-
}
|
|
1047
|
-
if (withTrack) {
|
|
1048
|
-
trackAddToCartGA({
|
|
1049
|
-
lineItems,
|
|
1050
|
-
gtmParams: { ...gtmParams, brand: config.getBrand() }
|
|
1051
|
-
});
|
|
1052
|
-
trackAddToCartFBQ({ lineItems });
|
|
1053
|
-
}
|
|
1054
|
-
return resultCart;
|
|
1055
|
-
},
|
|
1056
|
-
[client, locale, cartCookieAdapter, userAdapter, cart, withTrack]
|
|
1073
|
+
var initSameLinesAttributes = ({
|
|
1074
|
+
cart,
|
|
1075
|
+
line
|
|
1076
|
+
}) => {
|
|
1077
|
+
const sameLineInCart = cart?.lineItems.find(
|
|
1078
|
+
(lineInCart) => lineInCart.variant.sku === line.variant?.sku && lineInCart.product?.handle === line.variant?.product?.handle
|
|
1057
1079
|
);
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
function useUpdateCartLines(options) {
|
|
1061
|
-
const { client, locale, cartCookieAdapter } = useShopify();
|
|
1062
|
-
const { mutateCart, metafieldIdentifiers } = useCartContext();
|
|
1063
|
-
const updateLines = react.useCallback(
|
|
1064
|
-
async (_key, { arg }) => {
|
|
1065
|
-
const updatedCart = await shopifySdk.updateCartLines(client, {
|
|
1066
|
-
...arg,
|
|
1067
|
-
metafieldIdentifiers,
|
|
1068
|
-
cookieAdapter: cartCookieAdapter
|
|
1069
|
-
});
|
|
1070
|
-
if (updatedCart) {
|
|
1071
|
-
mutateCart(updatedCart);
|
|
1072
|
-
}
|
|
1073
|
-
return updatedCart;
|
|
1074
|
-
},
|
|
1075
|
-
[client, locale, cartCookieAdapter, mutateCart]
|
|
1080
|
+
const codeAmountAttribute = sameLineInCart?.customAttributes?.find(
|
|
1081
|
+
(attr) => attr.key === CODE_AMOUNT_KEY
|
|
1076
1082
|
);
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1083
|
+
const scriptCodeAmountAttribute = sameLineInCart?.customAttributes?.find(
|
|
1084
|
+
(attr) => attr.key === SCRIPT_CODE_AMOUNT_KEY
|
|
1085
|
+
);
|
|
1086
|
+
let functionAttribute = null;
|
|
1087
|
+
try {
|
|
1088
|
+
functionAttribute = sameLineInCart?.customAttributes?.find(
|
|
1089
|
+
(attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY && JSON.parse(attr.value)?.discounted_amount
|
|
1090
|
+
);
|
|
1091
|
+
} catch (error) {
|
|
1092
|
+
}
|
|
1093
|
+
if (codeAmountAttribute || functionAttribute || scriptCodeAmountAttribute) {
|
|
1094
|
+
return {
|
|
1095
|
+
...line,
|
|
1096
|
+
attributes: [
|
|
1097
|
+
...line.attributes || [],
|
|
1098
|
+
codeAmountAttribute,
|
|
1099
|
+
functionAttribute,
|
|
1100
|
+
scriptCodeAmountAttribute
|
|
1101
|
+
].filter(Boolean)
|
|
1102
|
+
};
|
|
1103
|
+
}
|
|
1104
|
+
return line;
|
|
1105
|
+
};
|
|
1106
|
+
var initDiscountAttributes = ({ line }) => {
|
|
1107
|
+
let itemAttributes = line.attributes || [];
|
|
1108
|
+
const functionEnvAttribute = itemAttributes.find((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY);
|
|
1109
|
+
if (!functionEnvAttribute) {
|
|
1110
|
+
itemAttributes = itemAttributes.concat([
|
|
1111
|
+
{
|
|
1112
|
+
key: CUSTOMER_ATTRIBUTE_KEY,
|
|
1113
|
+
value: JSON.stringify({
|
|
1114
|
+
is_gift: false,
|
|
1115
|
+
discounted_amount: line.variant?.finalPrice?.amount === void 0 ? Number(line.variant?.price?.amount) * (line.quantity || 1) : Number(line.variant?.finalPrice?.amount) * (line.quantity || 1)
|
|
1116
|
+
})
|
|
1111
1117
|
}
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1118
|
+
]);
|
|
1119
|
+
}
|
|
1120
|
+
const memberPriceAttribute = itemAttributes.find(
|
|
1121
|
+
(attr) => attr.key === MEMBER_PRICE_ATTRIBUTE_KEY
|
|
1115
1122
|
);
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
const updatedCart = await shopifySdk.updateCartAttributes(client, {
|
|
1123
|
-
...arg,
|
|
1124
|
-
metafieldIdentifiers,
|
|
1125
|
-
cookieAdapter: cartCookieAdapter
|
|
1126
|
-
});
|
|
1127
|
-
console.log("useUpdateCartAttributes updatedCart", updatedCart);
|
|
1128
|
-
if (updatedCart) {
|
|
1129
|
-
mutate(updatedCart);
|
|
1123
|
+
const coupon = line.coupon;
|
|
1124
|
+
if (!memberPriceAttribute && coupon) {
|
|
1125
|
+
itemAttributes = itemAttributes.concat([
|
|
1126
|
+
{
|
|
1127
|
+
key: MEMBER_PRICE_ATTRIBUTE_KEY,
|
|
1128
|
+
value: JSON.stringify({ code: coupon.code })
|
|
1130
1129
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1130
|
+
]);
|
|
1131
|
+
}
|
|
1132
|
+
const couponDiscountAttribute = itemAttributes.find(
|
|
1133
|
+
(attr) => attr.key === CODE_AMOUNT_KEY || attr.key === SCRIPT_CODE_AMOUNT_KEY
|
|
1134
1134
|
);
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
discountCodes,
|
|
1145
|
-
gtmParams = {},
|
|
1146
|
-
buyerIdentity,
|
|
1147
|
-
fbqTrackConfig,
|
|
1148
|
-
customAttributes,
|
|
1149
|
-
metafieldIdentifiers,
|
|
1150
|
-
redirectToCheckout
|
|
1151
|
-
} = arg;
|
|
1152
|
-
if (!lineItems || lineItems.length === 0) {
|
|
1153
|
-
return;
|
|
1154
|
-
}
|
|
1155
|
-
const lines = lineItems.map((item) => ({
|
|
1156
|
-
merchandiseId: item.variant?.id || "",
|
|
1157
|
-
quantity: item.quantity || 1,
|
|
1158
|
-
attributes: item.attributes,
|
|
1159
|
-
sellingPlanId: item.sellingPlanId
|
|
1160
|
-
})).filter((item) => item.merchandiseId && item.quantity);
|
|
1161
|
-
if (lines.length === 0) {
|
|
1162
|
-
return;
|
|
1163
|
-
}
|
|
1164
|
-
const resultCart = await shopifySdk.createCart(client, {
|
|
1165
|
-
lines,
|
|
1166
|
-
metafieldIdentifiers,
|
|
1167
|
-
cookieAdapter: cartCookieAdapter,
|
|
1168
|
-
buyerIdentity,
|
|
1169
|
-
discountCodes,
|
|
1170
|
-
customAttributes
|
|
1171
|
-
});
|
|
1172
|
-
if (!resultCart) {
|
|
1173
|
-
throw new Error("Failed to create cart for buy now");
|
|
1174
|
-
}
|
|
1175
|
-
if (withTrack && resultCart.lineItems) {
|
|
1176
|
-
trackBuyNowGA({
|
|
1177
|
-
lineItems,
|
|
1178
|
-
gtmParams: { ...gtmParams, brand: config.getBrand() }
|
|
1179
|
-
});
|
|
1180
|
-
if (fbqTrackConfig) {
|
|
1181
|
-
trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
if (redirectToCheckout) {
|
|
1185
|
-
if (resultCart.url) {
|
|
1186
|
-
if (typeof window !== "undefined") {
|
|
1187
|
-
window.location.href = resultCart.url;
|
|
1188
|
-
}
|
|
1189
|
-
} else {
|
|
1190
|
-
throw new Error("Failed to get checkout URL");
|
|
1191
|
-
}
|
|
1135
|
+
if (!couponDiscountAttribute && coupon && Number(coupon?.amount) > 0) {
|
|
1136
|
+
itemAttributes = itemAttributes.concat([
|
|
1137
|
+
{
|
|
1138
|
+
key: CODE_AMOUNT_KEY,
|
|
1139
|
+
value: new Decimal2__default.default(coupon.amount).times(line.quantity || 1).toString()
|
|
1140
|
+
},
|
|
1141
|
+
{
|
|
1142
|
+
key: SCRIPT_CODE_AMOUNT_KEY,
|
|
1143
|
+
value: new Decimal2__default.default(coupon.amount).times(line.quantity || 1).toString()
|
|
1192
1144
|
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1145
|
+
]);
|
|
1146
|
+
}
|
|
1147
|
+
return { ...line, attributes: itemAttributes };
|
|
1148
|
+
};
|
|
1149
|
+
var getLinesWithAttributes = ({
|
|
1150
|
+
cart,
|
|
1151
|
+
lineItems
|
|
1152
|
+
}) => {
|
|
1153
|
+
return lineItems.map((line) => {
|
|
1154
|
+
const sameLine = initSameLinesAttributes({ cart, line });
|
|
1155
|
+
const functionLine = initDiscountAttributes({ line: sameLine });
|
|
1156
|
+
return functionLine;
|
|
1157
|
+
});
|
|
1158
|
+
};
|
|
1199
1159
|
function useCalcGiftsFromLines({
|
|
1200
1160
|
lines,
|
|
1201
1161
|
customer,
|
|
@@ -1212,30 +1172,55 @@ function useCalcGiftsFromLines({
|
|
|
1212
1172
|
lines
|
|
1213
1173
|
});
|
|
1214
1174
|
const allGiftLines = react.useMemo(() => {
|
|
1215
|
-
const functionGiftLines = functionGift.qualifyingGift?.itemsToAdd || []
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1175
|
+
const functionGiftLines = (functionGift.qualifyingGift?.itemsToAdd || []).map((item) => {
|
|
1176
|
+
const product = functionGift.giftProductsResult?.find(
|
|
1177
|
+
(product2) => product2.handle === item.variant.handle
|
|
1178
|
+
);
|
|
1179
|
+
const variants = product?.variants;
|
|
1180
|
+
const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.variant.sku) : void 0;
|
|
1181
|
+
if (!variant) {
|
|
1182
|
+
console.warn(
|
|
1183
|
+
`Function gift: Variant not found for handle=${item.variant.handle}, sku=${item.variant.sku}`
|
|
1184
|
+
);
|
|
1185
|
+
return null;
|
|
1186
|
+
}
|
|
1187
|
+
return {
|
|
1188
|
+
variant: {
|
|
1189
|
+
...variant,
|
|
1190
|
+
product
|
|
1191
|
+
},
|
|
1192
|
+
quantity: item.quantity ?? 1,
|
|
1193
|
+
attributes: item.attributes
|
|
1194
|
+
};
|
|
1195
|
+
}).filter((item) => item !== null);
|
|
1196
|
+
const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((item) => {
|
|
1197
|
+
const product = scriptGift.giftProductsResult?.find(
|
|
1198
|
+
(product2) => product2.handle === item.handle
|
|
1219
1199
|
);
|
|
1220
|
-
const
|
|
1200
|
+
const variants = product?.variants;
|
|
1201
|
+
const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.sku) : void 0;
|
|
1202
|
+
if (!variant) {
|
|
1203
|
+
console.warn(`Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`);
|
|
1204
|
+
return null;
|
|
1205
|
+
}
|
|
1221
1206
|
return {
|
|
1222
1207
|
variant: {
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
sku: product.sku
|
|
1208
|
+
...variant,
|
|
1209
|
+
product
|
|
1226
1210
|
},
|
|
1227
1211
|
quantity: 1,
|
|
1228
1212
|
attributes: [
|
|
1229
1213
|
{
|
|
1230
1214
|
key: scriptGiveawayKey,
|
|
1231
|
-
value:
|
|
1215
|
+
value: scriptGiveawayKey
|
|
1232
1216
|
}
|
|
1233
1217
|
]
|
|
1234
1218
|
};
|
|
1235
|
-
}).filter((item) => item
|
|
1219
|
+
}).filter((item) => item !== null) : [];
|
|
1236
1220
|
return [...functionGiftLines, ...scriptGiftLines];
|
|
1237
1221
|
}, [
|
|
1238
1222
|
functionGift.qualifyingGift,
|
|
1223
|
+
functionGift.giftProductsResult,
|
|
1239
1224
|
scriptGift.freeGiftLevel,
|
|
1240
1225
|
scriptGift.giftProductsResult,
|
|
1241
1226
|
scriptGiveawayKey
|
|
@@ -1270,7 +1255,7 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
|
|
|
1270
1255
|
const isCustomerLoading = react.useMemo(() => !customer ? true : false, [customer]);
|
|
1271
1256
|
const dealsType = "";
|
|
1272
1257
|
const { activeCampaign, subtotal } = react.useMemo(() => {
|
|
1273
|
-
for (const campaign of orderDiscountConfig) {
|
|
1258
|
+
for (const campaign of orderDiscountConfig || []) {
|
|
1274
1259
|
const { rule_conditions = [], result_detail } = campaign;
|
|
1275
1260
|
const { main_product, order_discount_conf } = result_detail || {};
|
|
1276
1261
|
const isPreCheckPassed = preCheck(rule_conditions, tags, []);
|
|
@@ -1300,9 +1285,12 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
|
|
|
1300
1285
|
discountAmount: 0
|
|
1301
1286
|
};
|
|
1302
1287
|
}
|
|
1303
|
-
const
|
|
1304
|
-
|
|
1305
|
-
const
|
|
1288
|
+
const currentCurrency = cart?.currency?.code || "";
|
|
1289
|
+
console.log("currentCurrency", cart, currentCurrency);
|
|
1290
|
+
const orderDiscountConf = activeCampaign.result_detail.order_discount_conf;
|
|
1291
|
+
const tieredDiscounts = orderDiscountConf.tiered_discounts_markets?.[currentCurrency] || orderDiscountConf.tiered_discounts;
|
|
1292
|
+
const qualifyingTier = [...tieredDiscounts].sort((a, b) => Number(b.amount) - Number(a.amount)).find((tier) => subtotal >= Number(tier.amount));
|
|
1293
|
+
const nextGoal = [...tieredDiscounts].sort((a, b) => Number(a.amount) - Number(b.amount)).find((tier) => subtotal < Number(tier.amount));
|
|
1306
1294
|
if (!qualifyingTier) {
|
|
1307
1295
|
return {
|
|
1308
1296
|
qualifyingDiscount: null,
|
|
@@ -1339,43 +1327,10 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
|
|
|
1339
1327
|
isLoading: isCustomerLoading
|
|
1340
1328
|
};
|
|
1341
1329
|
};
|
|
1342
|
-
function useHasPlusMemberInCart({
|
|
1343
|
-
memberSetting,
|
|
1344
|
-
cart
|
|
1345
|
-
}) {
|
|
1346
|
-
const { plus_monthly_product, plus_annual_product } = memberSetting || {};
|
|
1347
|
-
return react.useMemo(() => {
|
|
1348
|
-
if (!cart?.lineItems) {
|
|
1349
|
-
return {
|
|
1350
|
-
hasPlusMember: false,
|
|
1351
|
-
hasMonthlyPlus: false,
|
|
1352
|
-
hasAnnualPlus: false
|
|
1353
|
-
};
|
|
1354
|
-
}
|
|
1355
|
-
const monthlyPlusItem = cart.lineItems.find(
|
|
1356
|
-
(item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
|
|
1357
|
-
);
|
|
1358
|
-
const annualPlusItem = cart.lineItems.find(
|
|
1359
|
-
(item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
|
|
1360
|
-
);
|
|
1361
|
-
const hasMonthlyPlus = !!monthlyPlusItem;
|
|
1362
|
-
const hasAnnualPlus = !!annualPlusItem;
|
|
1363
|
-
const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
|
|
1364
|
-
return {
|
|
1365
|
-
hasPlusMember,
|
|
1366
|
-
hasMonthlyPlus,
|
|
1367
|
-
hasAnnualPlus,
|
|
1368
|
-
monthlyPlusItem,
|
|
1369
|
-
annualPlusItem
|
|
1370
|
-
};
|
|
1371
|
-
}, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
// src/hooks/cart/feature/use-cart-attributes.ts
|
|
1375
1330
|
var getReferralAttributes = () => {
|
|
1376
|
-
const inviteCode = Cookies5__default.default.get("
|
|
1377
|
-
const playModeId = Cookies5__default.default.get("playModeId");
|
|
1378
|
-
const popup = Cookies5__default.default.get("_popup");
|
|
1331
|
+
const inviteCode = shopifySdk.getLocalStorage("inviteCode") || Cookies5__default.default.get("inviteCode");
|
|
1332
|
+
const playModeId = shopifySdk.getLocalStorage("playModeId") || Cookies5__default.default.get("playModeId");
|
|
1333
|
+
const popup = shopifySdk.getLocalStorage("_popup") || Cookies5__default.default.get("_popup");
|
|
1379
1334
|
if (inviteCode && playModeId) {
|
|
1380
1335
|
return popup ? [
|
|
1381
1336
|
{ key: "_invite_code", value: inviteCode ? inviteCode : "" },
|
|
@@ -1388,121 +1343,130 @@ var getReferralAttributes = () => {
|
|
|
1388
1343
|
}
|
|
1389
1344
|
return [];
|
|
1390
1345
|
};
|
|
1346
|
+
var getUserType = (customer) => {
|
|
1347
|
+
let userInfo = Cookies5__default.default.get("userInfo");
|
|
1348
|
+
if (userInfo) {
|
|
1349
|
+
userInfo = JSON.parse(userInfo);
|
|
1350
|
+
let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
|
|
1351
|
+
userInfo.setId = arr[arr.length - 1];
|
|
1352
|
+
}
|
|
1353
|
+
const customerInfo = userInfo || customer;
|
|
1354
|
+
if (!customerInfo) {
|
|
1355
|
+
return "new_user_unlogin";
|
|
1356
|
+
}
|
|
1357
|
+
if (customer) {
|
|
1358
|
+
const { orders = {} } = customer;
|
|
1359
|
+
if (orders?.edges?.length === 1) {
|
|
1360
|
+
return "old_user_orders_once";
|
|
1361
|
+
} else if (orders?.edges?.length > 1) {
|
|
1362
|
+
return "old_user_orders_twice";
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
return "new_user_login";
|
|
1366
|
+
};
|
|
1367
|
+
function getCartAttributes({
|
|
1368
|
+
profile,
|
|
1369
|
+
customer,
|
|
1370
|
+
cart,
|
|
1371
|
+
memberType,
|
|
1372
|
+
currentUrl = ""
|
|
1373
|
+
}) {
|
|
1374
|
+
const userType = getUserType(customer);
|
|
1375
|
+
const memberAttributes = [
|
|
1376
|
+
{
|
|
1377
|
+
key: "_token",
|
|
1378
|
+
value: profile?.token
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
key: "_member_type",
|
|
1382
|
+
value: memberType ?? String(profile?.memberType ?? 0)
|
|
1383
|
+
},
|
|
1384
|
+
{
|
|
1385
|
+
key: "_user_type",
|
|
1386
|
+
value: userType
|
|
1387
|
+
},
|
|
1388
|
+
{
|
|
1389
|
+
key: "_is_login",
|
|
1390
|
+
value: profile?.token ? "true" : "false"
|
|
1391
|
+
}
|
|
1392
|
+
];
|
|
1393
|
+
if (profile?.token) {
|
|
1394
|
+
memberAttributes.push({
|
|
1395
|
+
key: "_login_user",
|
|
1396
|
+
value: "1"
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
|
|
1400
|
+
const functionAttributes = [
|
|
1401
|
+
{
|
|
1402
|
+
key: CUSTOMER_ATTRIBUTE_KEY,
|
|
1403
|
+
value: JSON.stringify({
|
|
1404
|
+
discount_code: discountCodes,
|
|
1405
|
+
user_tags: customer?.tags || []
|
|
1406
|
+
})
|
|
1407
|
+
}
|
|
1408
|
+
];
|
|
1409
|
+
const presellAttributes = [
|
|
1410
|
+
{
|
|
1411
|
+
key: "_presale",
|
|
1412
|
+
value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
|
|
1413
|
+
}
|
|
1414
|
+
];
|
|
1415
|
+
const weightAttributes = [
|
|
1416
|
+
{
|
|
1417
|
+
key: "_weight",
|
|
1418
|
+
value: cart?.lineItems.reduce((acc, item) => {
|
|
1419
|
+
return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
|
|
1420
|
+
}, 0).toString()
|
|
1421
|
+
},
|
|
1422
|
+
{
|
|
1423
|
+
key: "_app_source_name",
|
|
1424
|
+
value: "dtc"
|
|
1425
|
+
}
|
|
1426
|
+
];
|
|
1427
|
+
const trackingAttributes = [
|
|
1428
|
+
{
|
|
1429
|
+
key: "utm_params",
|
|
1430
|
+
value: currentUrl
|
|
1431
|
+
}
|
|
1432
|
+
];
|
|
1433
|
+
const commonAttributes = [
|
|
1434
|
+
...memberAttributes,
|
|
1435
|
+
...functionAttributes,
|
|
1436
|
+
...presellAttributes,
|
|
1437
|
+
...weightAttributes,
|
|
1438
|
+
...trackingAttributes,
|
|
1439
|
+
...getReferralAttributes()
|
|
1440
|
+
].filter((item) => item?.value);
|
|
1441
|
+
const extraAttributesInCart = cart?.customAttributes?.filter(
|
|
1442
|
+
(item) => !commonAttributes.some((attr) => attr.key === item.key)
|
|
1443
|
+
) || [];
|
|
1444
|
+
return [...commonAttributes, ...extraAttributesInCart].filter((item) => item?.value);
|
|
1445
|
+
}
|
|
1391
1446
|
var useCartAttributes = ({
|
|
1392
1447
|
profile,
|
|
1393
1448
|
customer,
|
|
1394
1449
|
cart,
|
|
1395
|
-
|
|
1450
|
+
memberType
|
|
1396
1451
|
}) => {
|
|
1397
1452
|
const [currentUrl, setCurrentUrl] = react.useState("");
|
|
1398
|
-
const { hasPlusMember } = useHasPlusMemberInCart({
|
|
1399
|
-
memberSetting,
|
|
1400
|
-
cart
|
|
1401
|
-
});
|
|
1402
1453
|
react.useEffect(() => {
|
|
1403
1454
|
setCurrentUrl(window.location.href);
|
|
1404
1455
|
}, []);
|
|
1405
|
-
const
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
return "new_user_unlogin";
|
|
1415
|
-
}
|
|
1416
|
-
if (customer) {
|
|
1417
|
-
const { orders = {} } = customer;
|
|
1418
|
-
if (orders?.edges?.length === 1) {
|
|
1419
|
-
return "old_user_orders_once";
|
|
1420
|
-
} else if (orders?.edges?.length > 1) {
|
|
1421
|
-
return "old_user_orders_twice";
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
return "new_user_login";
|
|
1425
|
-
}, [customer]);
|
|
1426
|
-
const memberAttributes = react.useMemo(() => {
|
|
1427
|
-
return [
|
|
1428
|
-
{
|
|
1429
|
-
key: "_token",
|
|
1430
|
-
value: profile?.token
|
|
1431
|
-
//是否登录
|
|
1432
|
-
},
|
|
1433
|
-
{
|
|
1434
|
-
key: "_member_type",
|
|
1435
|
-
value: hasPlusMember ? "2" : profile?.memberType
|
|
1436
|
-
//:0(游客),1(普通会员),2(付费会员)
|
|
1437
|
-
},
|
|
1438
|
-
{
|
|
1439
|
-
key: "_user_type",
|
|
1440
|
-
value: userType
|
|
1441
|
-
// n
|
|
1442
|
-
},
|
|
1443
|
-
{
|
|
1444
|
-
key: "_is_login",
|
|
1445
|
-
value: profile?.token ? "true" : "false"
|
|
1446
|
-
}
|
|
1447
|
-
];
|
|
1448
|
-
}, [profile?.memberType, profile?.token, userType, hasPlusMember]);
|
|
1449
|
-
const functionAttributes = react.useMemo(() => {
|
|
1450
|
-
const hasFunctionEnvAttribute = cart?.lineItems.some(
|
|
1451
|
-
(item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
|
|
1452
|
-
);
|
|
1453
|
-
const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
|
|
1454
|
-
return hasFunctionEnvAttribute ? [
|
|
1455
|
-
{
|
|
1456
|
-
key: "_discounts_function_env",
|
|
1457
|
-
value: JSON.stringify({
|
|
1458
|
-
discount_code: discountCodes,
|
|
1459
|
-
user_tags: customer?.tags || []
|
|
1460
|
-
})
|
|
1461
|
-
}
|
|
1462
|
-
] : [];
|
|
1463
|
-
}, [cart]);
|
|
1464
|
-
const presellAttributes = react.useMemo(() => {
|
|
1465
|
-
return [
|
|
1466
|
-
{
|
|
1467
|
-
key: "_presale",
|
|
1468
|
-
value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
|
|
1469
|
-
}
|
|
1470
|
-
];
|
|
1471
|
-
}, [cart]);
|
|
1472
|
-
const weightAttributes = react.useMemo(() => {
|
|
1473
|
-
return [
|
|
1474
|
-
{
|
|
1475
|
-
key: "_weight",
|
|
1476
|
-
value: cart?.lineItems.reduce((acc, item) => {
|
|
1477
|
-
return new Decimal2__default.default(acc).plus(item.variant.weight ?? 0).toNumber();
|
|
1478
|
-
}, 0).toString()
|
|
1479
|
-
},
|
|
1480
|
-
{
|
|
1481
|
-
key: "_app_source_name",
|
|
1482
|
-
value: "dtc"
|
|
1483
|
-
}
|
|
1484
|
-
];
|
|
1485
|
-
}, [cart]);
|
|
1486
|
-
const trackingAttributes = react.useMemo(() => {
|
|
1487
|
-
return [
|
|
1488
|
-
{
|
|
1489
|
-
key: "utm_params",
|
|
1490
|
-
value: currentUrl
|
|
1491
|
-
}
|
|
1492
|
-
];
|
|
1493
|
-
}, [currentUrl]);
|
|
1456
|
+
const attributes = react.useMemo(() => {
|
|
1457
|
+
return getCartAttributes({
|
|
1458
|
+
profile,
|
|
1459
|
+
customer,
|
|
1460
|
+
cart,
|
|
1461
|
+
memberType,
|
|
1462
|
+
currentUrl
|
|
1463
|
+
});
|
|
1464
|
+
}, [profile, customer, cart, memberType, currentUrl]);
|
|
1494
1465
|
return react.useMemo(
|
|
1495
1466
|
() => ({
|
|
1496
|
-
attributes
|
|
1497
|
-
...memberAttributes,
|
|
1498
|
-
...functionAttributes,
|
|
1499
|
-
...presellAttributes,
|
|
1500
|
-
...weightAttributes,
|
|
1501
|
-
...trackingAttributes,
|
|
1502
|
-
...getReferralAttributes()
|
|
1503
|
-
].filter((item) => item?.value)
|
|
1467
|
+
attributes
|
|
1504
1468
|
}),
|
|
1505
|
-
[
|
|
1469
|
+
[attributes]
|
|
1506
1470
|
);
|
|
1507
1471
|
};
|
|
1508
1472
|
var DEFAULT_MIN = 1;
|
|
@@ -1565,7 +1529,7 @@ var useUpdateLineCodeAmountAttributes = ({
|
|
|
1565
1529
|
);
|
|
1566
1530
|
const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
|
|
1567
1531
|
const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
|
|
1568
|
-
if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute) {
|
|
1532
|
+
if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
|
|
1569
1533
|
attrNeedUpdate.push({
|
|
1570
1534
|
key: CUSTOMER_ATTRIBUTE_KEY,
|
|
1571
1535
|
value: JSON.stringify({
|
|
@@ -1604,29 +1568,22 @@ var useUpdateLineCodeAmountAttributes = ({
|
|
|
1604
1568
|
}).filter(
|
|
1605
1569
|
({ attrNeedUpdate, attrNeedDelete }) => attrNeedUpdate.length || attrNeedDelete.length
|
|
1606
1570
|
).map(({ line, attrNeedUpdate, attrNeedDelete }) => {
|
|
1571
|
+
let lineId = line.id;
|
|
1572
|
+
let attributes = line.customAttributes || [];
|
|
1573
|
+
if (attrNeedDelete.length) {
|
|
1574
|
+
attributes = attributes.filter(
|
|
1575
|
+
(attr) => !attrNeedDelete.includes(attr.key)
|
|
1576
|
+
);
|
|
1577
|
+
}
|
|
1607
1578
|
if (attrNeedUpdate.length) {
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
...line.customAttributes?.filter(
|
|
1612
|
-
(attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
|
|
1613
|
-
) || [],
|
|
1614
|
-
...attrNeedUpdate
|
|
1615
|
-
]
|
|
1616
|
-
};
|
|
1617
|
-
} else if (attrNeedDelete.length) {
|
|
1618
|
-
return {
|
|
1619
|
-
id: line.id,
|
|
1620
|
-
attributes: line.customAttributes?.filter(
|
|
1621
|
-
(attr) => !attrNeedDelete.includes(attr.key)
|
|
1622
|
-
) || []
|
|
1623
|
-
};
|
|
1624
|
-
} else {
|
|
1625
|
-
return {
|
|
1626
|
-
id: line.id,
|
|
1627
|
-
attributes: line.customAttributes || []
|
|
1628
|
-
};
|
|
1579
|
+
attributes = attributes.filter(
|
|
1580
|
+
(attr) => !attrNeedUpdate.some((updateAttr) => updateAttr.key === attr.key)
|
|
1581
|
+
).concat(attrNeedUpdate);
|
|
1629
1582
|
}
|
|
1583
|
+
return {
|
|
1584
|
+
id: lineId,
|
|
1585
|
+
attributes
|
|
1586
|
+
};
|
|
1630
1587
|
}),
|
|
1631
1588
|
[cart?.lineItems, mainProductDiscountCodes]
|
|
1632
1589
|
);
|
|
@@ -1661,45 +1618,61 @@ var useUpdateLineCodeAmountAttributes = ({
|
|
|
1661
1618
|
}, [loading, setLoadingState]);
|
|
1662
1619
|
};
|
|
1663
1620
|
|
|
1664
|
-
// src/hooks/
|
|
1665
|
-
var
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
}
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1621
|
+
// src/hooks/member/plus/types.ts
|
|
1622
|
+
var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
|
|
1623
|
+
PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
|
|
1624
|
+
PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
|
|
1625
|
+
PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
|
|
1626
|
+
return PLUS_MEMBER_TYPE2;
|
|
1627
|
+
})(PLUS_MEMBER_TYPE || {});
|
|
1628
|
+
var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
|
|
1629
|
+
PlusMemberMode2["MONTHLY"] = "monthly";
|
|
1630
|
+
PlusMemberMode2["ANNUAL"] = "annual";
|
|
1631
|
+
return PlusMemberMode2;
|
|
1632
|
+
})(PlusMemberMode || {});
|
|
1633
|
+
var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
|
|
1634
|
+
DeliveryPlusType2["FREE"] = "free";
|
|
1635
|
+
DeliveryPlusType2["MONTHLY"] = "monthly";
|
|
1636
|
+
DeliveryPlusType2["ANNUAL"] = "annual";
|
|
1637
|
+
return DeliveryPlusType2;
|
|
1638
|
+
})(DeliveryPlusType || {});
|
|
1639
|
+
var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
|
|
1640
|
+
ShippingMethodMode2["FREE"] = "free";
|
|
1641
|
+
ShippingMethodMode2["TDD"] = "tdd";
|
|
1642
|
+
ShippingMethodMode2["NDD"] = "ndd";
|
|
1643
|
+
return ShippingMethodMode2;
|
|
1644
|
+
})(ShippingMethodMode || {});
|
|
1645
|
+
var createInitialValue = () => ({
|
|
1646
|
+
plusMemberMetafields: {},
|
|
1647
|
+
selectedPlusMemberMode: "free",
|
|
1648
|
+
setSelectedPlusMemberMode: () => {
|
|
1649
|
+
},
|
|
1650
|
+
selectedShippingMethod: void 0,
|
|
1651
|
+
setSelectedShippingMethod: () => {
|
|
1652
|
+
},
|
|
1653
|
+
showMoreShippingMethod: false,
|
|
1654
|
+
setShowMoreShippingMethod: () => {
|
|
1655
|
+
},
|
|
1656
|
+
variant: {},
|
|
1657
|
+
product: {},
|
|
1658
|
+
shippingMethodsContext: {
|
|
1659
|
+
freeShippingMethods: [],
|
|
1660
|
+
paymentShippingMethods: [],
|
|
1661
|
+
nddOverweight: false,
|
|
1662
|
+
tddOverweight: false,
|
|
1663
|
+
nddCoupon: void 0,
|
|
1664
|
+
tddCoupon: void 0,
|
|
1665
|
+
isLoadingCoupon: false
|
|
1666
|
+
},
|
|
1667
|
+
selectedPlusMemberVariant: void 0,
|
|
1668
|
+
showPlusMemberBenefit: false,
|
|
1669
|
+
setShowPlusMemberBenefit: () => {
|
|
1670
|
+
},
|
|
1671
|
+
profile: void 0
|
|
1672
|
+
});
|
|
1673
|
+
var PlusMemberContext = react.createContext(createInitialValue());
|
|
1674
|
+
function usePlusMemberContext() {
|
|
1675
|
+
return react.useContext(PlusMemberContext);
|
|
1703
1676
|
}
|
|
1704
1677
|
function useProductsByHandles(options = {}) {
|
|
1705
1678
|
const { client, locale } = useShopify();
|
|
@@ -1719,1213 +1692,1349 @@ function useProductsByHandles(options = {}) {
|
|
|
1719
1692
|
metafieldIdentifiers
|
|
1720
1693
|
});
|
|
1721
1694
|
},
|
|
1722
|
-
|
|
1723
|
-
revalidateOnFocus: false
|
|
1695
|
+
{
|
|
1696
|
+
revalidateOnFocus: false,
|
|
1697
|
+
...swrOptions
|
|
1724
1698
|
}
|
|
1725
1699
|
);
|
|
1726
1700
|
}
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
function getVariantFromSelectedOptions(product, selectedOptions) {
|
|
1732
|
-
return product.variants.find((variant) => {
|
|
1733
|
-
return variant.selectedOptions.every((option) => {
|
|
1734
|
-
return selectedOptions[option.name] === option.value;
|
|
1735
|
-
});
|
|
1736
|
-
});
|
|
1737
|
-
}
|
|
1738
|
-
function useVariant({
|
|
1739
|
-
product,
|
|
1740
|
-
selectedOptions
|
|
1701
|
+
|
|
1702
|
+
// src/hooks/member/plus/use-plus-member-variants.ts
|
|
1703
|
+
function usePlusMemberVariants({
|
|
1704
|
+
memberSetting
|
|
1741
1705
|
}) {
|
|
1742
|
-
const
|
|
1743
|
-
|
|
1744
|
-
)
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
}
|
|
1750
|
-
const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
|
|
1751
|
-
if (newVariant && newVariant.id !== variant?.id) {
|
|
1752
|
-
setVariant(newVariant);
|
|
1753
|
-
} else if (!newVariant) {
|
|
1754
|
-
setVariant(getFirstAvailableVariant(product));
|
|
1755
|
-
}
|
|
1756
|
-
}, [selectedOptions, product, variant?.id]);
|
|
1757
|
-
return variant;
|
|
1758
|
-
}
|
|
1759
|
-
var FAKE_PRICE = 999999999e-2;
|
|
1760
|
-
function formatPrice({
|
|
1761
|
-
amount,
|
|
1762
|
-
currencyCode,
|
|
1763
|
-
locale,
|
|
1764
|
-
maximumFractionDigits,
|
|
1765
|
-
minimumFractionDigits,
|
|
1766
|
-
removeTrailingZeros
|
|
1767
|
-
}) {
|
|
1768
|
-
const formatter = new Intl.NumberFormat(locale, {
|
|
1769
|
-
style: "currency",
|
|
1770
|
-
currency: currencyCode,
|
|
1771
|
-
maximumFractionDigits: maximumFractionDigits ?? 2,
|
|
1772
|
-
minimumFractionDigits: minimumFractionDigits ?? 2
|
|
1706
|
+
const plusMonthly = memberSetting?.plus_monthly_product;
|
|
1707
|
+
const plusAnnual = memberSetting?.plus_annual_product;
|
|
1708
|
+
const plusMemberHandles = react.useMemo(() => {
|
|
1709
|
+
return [plusMonthly?.handle, plusAnnual?.handle].filter(Boolean);
|
|
1710
|
+
}, [plusMonthly?.handle, plusAnnual?.handle]);
|
|
1711
|
+
const { data: plusMemberProducts = [] } = useProductsByHandles({
|
|
1712
|
+
handles: plusMemberHandles
|
|
1773
1713
|
});
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
}
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
minimumFractionDigits,
|
|
1787
|
-
removeTrailingZeros
|
|
1788
|
-
}) {
|
|
1714
|
+
const monthlyProduct = react.useMemo(() => {
|
|
1715
|
+
return plusMemberProducts?.find((item) => item?.handle === plusMonthly?.handle);
|
|
1716
|
+
}, [plusMemberProducts, plusMonthly]);
|
|
1717
|
+
const annualProduct = react.useMemo(() => {
|
|
1718
|
+
return plusMemberProducts?.find((item) => item?.handle === plusAnnual?.handle);
|
|
1719
|
+
}, [plusMemberProducts, plusAnnual]);
|
|
1720
|
+
const monthlyVariant = react.useMemo(() => {
|
|
1721
|
+
return monthlyProduct?.variants?.find((item) => item.sku === plusMonthly?.sku);
|
|
1722
|
+
}, [monthlyProduct, plusMonthly]);
|
|
1723
|
+
const annualVariant = react.useMemo(() => {
|
|
1724
|
+
return annualProduct?.variants?.find((item) => item.sku === plusAnnual?.sku);
|
|
1725
|
+
}, [annualProduct, plusAnnual]);
|
|
1789
1726
|
return {
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
}
|
|
1798
|
-
basePrice: formatPrice({
|
|
1799
|
-
amount: baseAmount,
|
|
1800
|
-
currencyCode,
|
|
1801
|
-
locale,
|
|
1802
|
-
maximumFractionDigits,
|
|
1803
|
-
minimumFractionDigits,
|
|
1804
|
-
removeTrailingZeros
|
|
1805
|
-
})
|
|
1727
|
+
monthlyVariant: monthlyVariant ? {
|
|
1728
|
+
...monthlyVariant,
|
|
1729
|
+
product: monthlyProduct
|
|
1730
|
+
} : void 0,
|
|
1731
|
+
annualVariant: annualVariant ? {
|
|
1732
|
+
...annualVariant,
|
|
1733
|
+
product: annualProduct
|
|
1734
|
+
} : void 0
|
|
1806
1735
|
};
|
|
1807
1736
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
removeTrailingZeros
|
|
1816
|
-
}) {
|
|
1817
|
-
const { locale } = useShopify();
|
|
1818
|
-
const value = react.useMemo(() => {
|
|
1819
|
-
if (typeof amount !== "number" || !currencyCode) {
|
|
1820
|
-
return "";
|
|
1821
|
-
}
|
|
1822
|
-
if (soldOutDescription && amount >= FAKE_PRICE) {
|
|
1823
|
-
return soldOutDescription;
|
|
1737
|
+
var useAvailableDeliveryCoupon = ({
|
|
1738
|
+
profile
|
|
1739
|
+
}) => {
|
|
1740
|
+
const { data: availableDeliveryCoupon, isLoading } = useSWR__default.default(
|
|
1741
|
+
profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
|
|
1742
|
+
async ([apiPath]) => {
|
|
1743
|
+
return fetch(apiPath).then((res) => res.json());
|
|
1824
1744
|
}
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1745
|
+
);
|
|
1746
|
+
console.log("availableDeliveryCoupon", availableDeliveryCoupon);
|
|
1747
|
+
const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
|
|
1748
|
+
return {
|
|
1749
|
+
nddCoupon,
|
|
1750
|
+
tddCoupon,
|
|
1751
|
+
isLoading
|
|
1752
|
+
};
|
|
1753
|
+
};
|
|
1754
|
+
|
|
1755
|
+
// src/hooks/member/plus/use-shipping-methods.ts
|
|
1756
|
+
function useShippingMethods(options) {
|
|
1757
|
+
const { variant, plusMemberMetafields, selectedPlusMemberMode, profile } = options;
|
|
1758
|
+
const isPlus = profile?.isPlus || false;
|
|
1759
|
+
const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
|
|
1760
|
+
const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
|
|
1761
|
+
const nddOverweight = react.useMemo(() => {
|
|
1762
|
+
return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
|
|
1763
|
+
}, [shippingMethod?.overWeight_ndd, variant?.weight]);
|
|
1764
|
+
const tddOverweight = react.useMemo(() => {
|
|
1765
|
+
return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
|
|
1766
|
+
}, [shippingMethod?.overWeight_tdd, variant?.weight]);
|
|
1767
|
+
const paymentShippingMethods = react.useMemo(() => {
|
|
1768
|
+
const weight = variant?.weight || 0;
|
|
1769
|
+
const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
|
|
1770
|
+
const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
|
|
1771
|
+
return __mode !== "free" /* FREE */ && !__plus && fitWeight;
|
|
1772
|
+
}) || [];
|
|
1773
|
+
return methods.map((method) => {
|
|
1774
|
+
let disabled = false;
|
|
1775
|
+
const selectedFreeMember = selectedPlusMemberMode === "free";
|
|
1776
|
+
if (method.__mode === "ndd" /* NDD */) {
|
|
1777
|
+
disabled = selectedFreeMember || nddOverweight;
|
|
1778
|
+
} else if (method.__mode === "tdd" /* TDD */) {
|
|
1779
|
+
disabled = selectedFreeMember || tddOverweight;
|
|
1780
|
+
}
|
|
1781
|
+
return {
|
|
1782
|
+
...method,
|
|
1783
|
+
id: method.__mode + method.__code,
|
|
1784
|
+
useCoupon: false,
|
|
1785
|
+
subtitle: plus_shipping?.directly || "",
|
|
1786
|
+
disabled
|
|
1787
|
+
};
|
|
1840
1788
|
});
|
|
1841
1789
|
}, [
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
soldOutDescription,
|
|
1849
|
-
removeTrailingZeros
|
|
1790
|
+
nddOverweight,
|
|
1791
|
+
plus_shipping?.directly,
|
|
1792
|
+
plus_shipping?.shipping_methods,
|
|
1793
|
+
selectedPlusMemberMode,
|
|
1794
|
+
tddOverweight,
|
|
1795
|
+
variant?.weight
|
|
1850
1796
|
]);
|
|
1851
|
-
const
|
|
1852
|
-
const
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
}
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
const [options, setOptions] = react.useState({});
|
|
1873
|
-
react.useEffect(() => {
|
|
1874
|
-
if (!product || !product.variants.length) {
|
|
1875
|
-
setOptions({});
|
|
1876
|
-
return;
|
|
1877
|
-
}
|
|
1878
|
-
let variant = product.variants[0];
|
|
1879
|
-
if (typeof window !== "undefined") {
|
|
1880
|
-
const searchParams = new URLSearchParams(window.location.search);
|
|
1881
|
-
const variantIdParam = searchParams.get("variant");
|
|
1882
|
-
if (variantIdParam) {
|
|
1883
|
-
const foundVariant = product.variants.find((v) => {
|
|
1884
|
-
if (sku) return v.sku === sku;
|
|
1885
|
-
return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
|
|
1886
|
-
});
|
|
1887
|
-
if (foundVariant) {
|
|
1888
|
-
variant = foundVariant;
|
|
1889
|
-
}
|
|
1797
|
+
const nddPrice = react.useMemo(() => {
|
|
1798
|
+
const weight = variant?.weight || 0;
|
|
1799
|
+
const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
|
|
1800
|
+
const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
|
|
1801
|
+
return __mode === "ndd" && fitWeight;
|
|
1802
|
+
});
|
|
1803
|
+
return nddMethod?.price || 0;
|
|
1804
|
+
}, [variant?.weight, paymentShippingMethods]);
|
|
1805
|
+
const tddPrice = react.useMemo(() => {
|
|
1806
|
+
const weight = variant?.weight || 0;
|
|
1807
|
+
const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
|
|
1808
|
+
const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
|
|
1809
|
+
return __mode === "tdd" && fitWeight;
|
|
1810
|
+
});
|
|
1811
|
+
return tddMethod?.price || 0;
|
|
1812
|
+
}, [variant?.weight, paymentShippingMethods]);
|
|
1813
|
+
const freeShippingMethods = react.useMemo(() => {
|
|
1814
|
+
const weight = variant?.weight || 0;
|
|
1815
|
+
let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
|
|
1816
|
+
if (__mode === "free" /* FREE */) {
|
|
1817
|
+
return true;
|
|
1890
1818
|
}
|
|
1819
|
+
if (isPlus) {
|
|
1820
|
+
const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
|
|
1821
|
+
const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
|
|
1822
|
+
return hasCoupon && fitWeight && !__plus;
|
|
1823
|
+
} else {
|
|
1824
|
+
return __plus;
|
|
1825
|
+
}
|
|
1826
|
+
}) || [];
|
|
1827
|
+
if (isPlus) {
|
|
1828
|
+
methods = methods.sort((a, b) => {
|
|
1829
|
+
if (b.__mode === "free" /* FREE */) return -1;
|
|
1830
|
+
return 0;
|
|
1831
|
+
});
|
|
1891
1832
|
}
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
}
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
const queryParams = new URLSearchParams();
|
|
1913
|
-
if (variant?.id) {
|
|
1914
|
-
const variantId = decodeShopifyId2(variant.id);
|
|
1915
|
-
if (variantId) {
|
|
1916
|
-
queryParams.set("variant", variantId);
|
|
1833
|
+
return methods.map((method) => {
|
|
1834
|
+
let price = 0;
|
|
1835
|
+
let coupon;
|
|
1836
|
+
let disabled;
|
|
1837
|
+
if (method.__mode !== "free" /* FREE */) {
|
|
1838
|
+
switch (method.__mode) {
|
|
1839
|
+
case "tdd":
|
|
1840
|
+
price = tddPrice;
|
|
1841
|
+
coupon = tddCoupon || nddCoupon;
|
|
1842
|
+
break;
|
|
1843
|
+
case "ndd":
|
|
1844
|
+
price = nddPrice;
|
|
1845
|
+
coupon = nddCoupon;
|
|
1846
|
+
break;
|
|
1847
|
+
}
|
|
1848
|
+
disabled = selectedPlusMemberMode === "free";
|
|
1849
|
+
if (method.__mode === "ndd" /* NDD */) {
|
|
1850
|
+
disabled = disabled || nddOverweight;
|
|
1851
|
+
} else if (method.__mode === "tdd" /* TDD */) {
|
|
1852
|
+
disabled = disabled || tddOverweight;
|
|
1917
1853
|
}
|
|
1918
1854
|
}
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1855
|
+
return {
|
|
1856
|
+
...method,
|
|
1857
|
+
id: method.__mode + method.__code,
|
|
1858
|
+
useCoupon: true,
|
|
1859
|
+
disabled,
|
|
1860
|
+
coupon,
|
|
1861
|
+
price
|
|
1862
|
+
};
|
|
1863
|
+
});
|
|
1864
|
+
}, [
|
|
1865
|
+
variant?.weight,
|
|
1866
|
+
plus_shipping?.shipping_methods,
|
|
1867
|
+
isPlus,
|
|
1868
|
+
nddCoupon,
|
|
1869
|
+
tddCoupon,
|
|
1870
|
+
selectedPlusMemberMode,
|
|
1871
|
+
tddPrice,
|
|
1872
|
+
nddPrice,
|
|
1873
|
+
nddOverweight,
|
|
1874
|
+
tddOverweight
|
|
1875
|
+
]);
|
|
1876
|
+
return {
|
|
1877
|
+
freeShippingMethods,
|
|
1878
|
+
paymentShippingMethods,
|
|
1879
|
+
nddOverweight,
|
|
1880
|
+
tddOverweight,
|
|
1881
|
+
nddCoupon,
|
|
1882
|
+
tddCoupon,
|
|
1883
|
+
isLoadingCoupon: isLoading
|
|
1884
|
+
};
|
|
1885
|
+
}
|
|
1886
|
+
var useReplaceCartPlusMember = () => {
|
|
1887
|
+
const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
|
|
1888
|
+
const { trigger: removeCartLines2 } = useRemoveCartLines();
|
|
1889
|
+
const { cart } = useCartContext();
|
|
1890
|
+
const plusMonthly = plusMemberMetafields?.plus_monthly_product;
|
|
1891
|
+
const plusAnnual = plusMemberMetafields?.plus_annual_product;
|
|
1892
|
+
const handler = react.useCallback(async () => {
|
|
1893
|
+
const plusMonthlyInCart = cart?.lineItems.find(
|
|
1894
|
+
(item) => item.variant?.sku === plusMonthly?.sku
|
|
1895
|
+
);
|
|
1896
|
+
const plusAnnualInCart = cart?.lineItems.find(
|
|
1897
|
+
(item) => item.variant?.sku === plusAnnual?.sku
|
|
1898
|
+
);
|
|
1899
|
+
if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
|
|
1900
|
+
await removeCartLines2({
|
|
1901
|
+
lineIds: [plusMonthlyInCart.id]
|
|
1902
|
+
});
|
|
1903
|
+
} else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
|
|
1904
|
+
await removeCartLines2({
|
|
1905
|
+
lineIds: [plusAnnualInCart.id]
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1908
|
+
}, [
|
|
1909
|
+
cart?.lineItems,
|
|
1910
|
+
selectedPlusMemberMode,
|
|
1911
|
+
plusMonthly?.sku,
|
|
1912
|
+
plusAnnual?.sku,
|
|
1913
|
+
removeCartLines2
|
|
1914
|
+
]);
|
|
1915
|
+
return handler;
|
|
1916
|
+
};
|
|
1917
|
+
var usePlusMemberCheckoutCustomAttributes = ({
|
|
1918
|
+
disableShipping = false,
|
|
1919
|
+
isPresaleContains = false
|
|
1920
|
+
}) => {
|
|
1921
|
+
const { profile, selectedShippingMethod, selectedPlusMemberMode } = usePlusMemberContext();
|
|
1922
|
+
return react.useMemo(() => {
|
|
1923
|
+
const checkoutCustomAttributes = [
|
|
1924
|
+
{
|
|
1925
|
+
key: "_last_url",
|
|
1926
|
+
value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
|
|
1928
1927
|
}
|
|
1929
|
-
|
|
1928
|
+
];
|
|
1929
|
+
checkoutCustomAttributes.push({
|
|
1930
|
+
key: "_checkout_delivery_custom",
|
|
1931
|
+
value: JSON.stringify({
|
|
1932
|
+
allow_nextday_delivery: true,
|
|
1933
|
+
allow_thirdday_delivery: true,
|
|
1934
|
+
selected_delivery_option: {
|
|
1935
|
+
code: selectedShippingMethod?.__code,
|
|
1936
|
+
mode: selectedShippingMethod?.__mode
|
|
1937
|
+
},
|
|
1938
|
+
is_presale: isPresaleContains,
|
|
1939
|
+
discount_code: selectedShippingMethod?.coupon ? [selectedShippingMethod.coupon] : [],
|
|
1940
|
+
plus_type: profile?.isPlus ? "free" /* FREE */ : selectedPlusMemberMode,
|
|
1941
|
+
is_prime: profile?.isPlus
|
|
1942
|
+
})
|
|
1943
|
+
});
|
|
1944
|
+
if (disableShipping) {
|
|
1945
|
+
checkoutCustomAttributes.push({
|
|
1946
|
+
key: "_hide_shipping",
|
|
1947
|
+
value: "true"
|
|
1948
|
+
});
|
|
1949
|
+
}
|
|
1950
|
+
return checkoutCustomAttributes;
|
|
1951
|
+
}, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
|
|
1952
|
+
};
|
|
1953
|
+
function useRemoveCartLines(options) {
|
|
1954
|
+
const { client, locale, cartCookieAdapter } = useShopify();
|
|
1955
|
+
const { mutateCart, metafieldIdentifiers } = useCartContext();
|
|
1956
|
+
const removeLines = react.useCallback(
|
|
1957
|
+
async (_key, { arg }) => {
|
|
1958
|
+
const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
|
|
1959
|
+
let updatedCart = await shopifySdk.removeCartLines(client, {
|
|
1960
|
+
cartId,
|
|
1961
|
+
lineIds,
|
|
1962
|
+
metafieldIdentifiers,
|
|
1963
|
+
cookieAdapter: cartCookieAdapter
|
|
1964
|
+
});
|
|
1965
|
+
if (updatedCart && autoRemoveInvalidCodes) {
|
|
1966
|
+
const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
|
|
1967
|
+
if (unApplicableCodes.length > 0) {
|
|
1968
|
+
if (onCodesRemoved) {
|
|
1969
|
+
const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
|
|
1970
|
+
if (handledCart) {
|
|
1971
|
+
updatedCart = handledCart;
|
|
1972
|
+
}
|
|
1973
|
+
} else {
|
|
1974
|
+
updatedCart = await shopifySdk.updateCartCodes(client, {
|
|
1975
|
+
cartId: updatedCart.id,
|
|
1976
|
+
discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
|
|
1977
|
+
metafieldIdentifiers,
|
|
1978
|
+
cookieAdapter: cartCookieAdapter
|
|
1979
|
+
}) || updatedCart;
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
if (updatedCart) {
|
|
1984
|
+
mutateCart(updatedCart);
|
|
1985
|
+
}
|
|
1986
|
+
return updatedCart;
|
|
1930
1987
|
},
|
|
1931
|
-
[
|
|
1988
|
+
[client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
|
|
1932
1989
|
);
|
|
1990
|
+
return useSWRMutation__default.default("remove-cart-lines", removeLines, options);
|
|
1933
1991
|
}
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
}
|
|
1942
|
-
|
|
1992
|
+
|
|
1993
|
+
// src/hooks/member/plus/use-auto-remove-plus-member-in-cart.ts
|
|
1994
|
+
function useAutoRemovePlusMemberInCart({
|
|
1995
|
+
cart,
|
|
1996
|
+
profile,
|
|
1997
|
+
memberSetting
|
|
1998
|
+
}) {
|
|
1999
|
+
const { plus_monthly_product, plus_annual_product } = memberSetting || {};
|
|
2000
|
+
const { trigger: removeCartLines2 } = useRemoveCartLines();
|
|
1943
2001
|
react.useEffect(() => {
|
|
1944
|
-
if (!
|
|
1945
|
-
|
|
2002
|
+
if (!cart || !plus_monthly_product || !plus_annual_product) return;
|
|
2003
|
+
const removePlusProduct = async (productType) => {
|
|
2004
|
+
if (!productType) return;
|
|
2005
|
+
const product = cart.lineItems?.find(
|
|
2006
|
+
(item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
|
|
2007
|
+
);
|
|
2008
|
+
if (product) {
|
|
2009
|
+
await removeCartLines2({
|
|
2010
|
+
lineIds: [product.id]
|
|
2011
|
+
});
|
|
2012
|
+
}
|
|
2013
|
+
};
|
|
2014
|
+
if (profile?.isMonthlyPlus) {
|
|
2015
|
+
removePlusProduct(plus_monthly_product);
|
|
1946
2016
|
}
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
const newVariantId = decodeShopifyId3(variant.id);
|
|
1950
|
-
if (newVariantId && currentVariantId !== newVariantId) {
|
|
1951
|
-
searchParams.set("variant", newVariantId);
|
|
1952
|
-
const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
|
|
1953
|
-
window.history.replaceState({}, "", newUrl);
|
|
2017
|
+
if (profile?.isAnnualPlus) {
|
|
2018
|
+
removePlusProduct(plus_annual_product);
|
|
1954
2019
|
}
|
|
1955
|
-
}, [
|
|
2020
|
+
}, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
|
|
1956
2021
|
}
|
|
1957
|
-
function
|
|
1958
|
-
|
|
1959
|
-
|
|
2022
|
+
function hasPlusMemberInCart({
|
|
2023
|
+
memberSetting,
|
|
2024
|
+
cart
|
|
1960
2025
|
}) {
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
});
|
|
1969
|
-
if (variantMedia.length > 0) {
|
|
1970
|
-
const otherMedia = product.media.filter((media) => {
|
|
1971
|
-
if (media.mediaContentType === "IMAGE" && media.previewImage) {
|
|
1972
|
-
return media.previewImage.url !== variantMediaId;
|
|
1973
|
-
}
|
|
1974
|
-
return true;
|
|
1975
|
-
});
|
|
1976
|
-
return [...variantMedia, ...otherMedia];
|
|
1977
|
-
}
|
|
2026
|
+
const { plus_monthly_product, plus_annual_product } = memberSetting || {};
|
|
2027
|
+
if (!cart?.lineItems) {
|
|
2028
|
+
return {
|
|
2029
|
+
hasPlusMember: false,
|
|
2030
|
+
hasMonthlyPlus: false,
|
|
2031
|
+
hasAnnualPlus: false
|
|
2032
|
+
};
|
|
1978
2033
|
}
|
|
1979
|
-
|
|
2034
|
+
const monthlyPlusItem = cart.lineItems.find(
|
|
2035
|
+
(item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
|
|
2036
|
+
);
|
|
2037
|
+
const annualPlusItem = cart.lineItems.find(
|
|
2038
|
+
(item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
|
|
2039
|
+
);
|
|
2040
|
+
const hasMonthlyPlus = !!monthlyPlusItem;
|
|
2041
|
+
const hasAnnualPlus = !!annualPlusItem;
|
|
2042
|
+
const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
|
|
2043
|
+
return {
|
|
2044
|
+
hasPlusMember,
|
|
2045
|
+
hasMonthlyPlus,
|
|
2046
|
+
hasAnnualPlus,
|
|
2047
|
+
monthlyPlusItem,
|
|
2048
|
+
annualPlusItem
|
|
2049
|
+
};
|
|
1980
2050
|
}
|
|
1981
|
-
function
|
|
1982
|
-
|
|
1983
|
-
|
|
2051
|
+
function useHasPlusMemberInCart({
|
|
2052
|
+
memberSetting,
|
|
2053
|
+
cart
|
|
1984
2054
|
}) {
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2055
|
+
return react.useMemo(
|
|
2056
|
+
() => hasPlusMemberInCart({
|
|
2057
|
+
memberSetting,
|
|
2058
|
+
cart
|
|
2059
|
+
}),
|
|
2060
|
+
[memberSetting, cart]
|
|
2061
|
+
);
|
|
2062
|
+
}
|
|
2063
|
+
function hasPlusMemberInLines({
|
|
2064
|
+
memberSetting,
|
|
2065
|
+
lines
|
|
2066
|
+
}) {
|
|
2067
|
+
const { plus_monthly_product, plus_annual_product } = memberSetting || {};
|
|
2068
|
+
if (!lines || lines.length === 0) {
|
|
2069
|
+
return {
|
|
2070
|
+
hasPlusMember: false,
|
|
2071
|
+
hasMonthlyPlus: false,
|
|
2072
|
+
hasAnnualPlus: false
|
|
2073
|
+
};
|
|
2074
|
+
}
|
|
2075
|
+
const monthlyPlusLine = lines.find((line) => {
|
|
2076
|
+
const variantHandle = line.variant?.product?.handle;
|
|
2077
|
+
const variantSku = line.variant?.sku;
|
|
2078
|
+
return variantHandle === plus_monthly_product?.handle && variantSku === plus_monthly_product?.sku;
|
|
2079
|
+
});
|
|
2080
|
+
const annualPlusLine = lines.find((line) => {
|
|
2081
|
+
const variantHandle = line.variant?.product?.handle;
|
|
2082
|
+
const variantSku = line.variant?.sku;
|
|
2083
|
+
return variantHandle === plus_annual_product?.handle && variantSku === plus_annual_product?.sku;
|
|
2084
|
+
});
|
|
2085
|
+
const hasMonthlyPlus = !!monthlyPlusLine;
|
|
2086
|
+
const hasAnnualPlus = !!annualPlusLine;
|
|
2087
|
+
const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
|
|
2004
2088
|
return {
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2089
|
+
hasPlusMember,
|
|
2090
|
+
hasMonthlyPlus,
|
|
2091
|
+
hasAnnualPlus,
|
|
2092
|
+
monthlyPlusLine,
|
|
2093
|
+
annualPlusLine
|
|
2008
2094
|
};
|
|
2009
2095
|
}
|
|
2010
|
-
function
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
() =>
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
metafieldIdentifiers
|
|
2096
|
+
function useHasPlusMemberInLines({
|
|
2097
|
+
memberSetting,
|
|
2098
|
+
lines
|
|
2099
|
+
}) {
|
|
2100
|
+
return react.useMemo(
|
|
2101
|
+
() => hasPlusMemberInLines({
|
|
2102
|
+
memberSetting,
|
|
2103
|
+
lines
|
|
2019
2104
|
}),
|
|
2020
|
-
|
|
2105
|
+
[memberSetting, lines]
|
|
2021
2106
|
);
|
|
2022
2107
|
}
|
|
2023
|
-
function
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
}
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
}
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
metafieldIdentifiers
|
|
2052
|
-
}),
|
|
2053
|
-
swrOptions
|
|
2054
|
-
);
|
|
2108
|
+
function usePlusMemberNeedAddToCart({
|
|
2109
|
+
cart,
|
|
2110
|
+
profile
|
|
2111
|
+
}) {
|
|
2112
|
+
const { selectedPlusMemberMode, selectedPlusMemberVariant, plusMemberMetafields } = usePlusMemberContext();
|
|
2113
|
+
const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
|
|
2114
|
+
memberSetting: plusMemberMetafields,
|
|
2115
|
+
cart
|
|
2116
|
+
});
|
|
2117
|
+
const plusMemberVariant = react.useMemo(() => {
|
|
2118
|
+
if (!selectedPlusMemberVariant || selectedPlusMemberMode === "free" /* FREE */) {
|
|
2119
|
+
return void 0;
|
|
2120
|
+
}
|
|
2121
|
+
if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
|
|
2122
|
+
return void 0;
|
|
2123
|
+
}
|
|
2124
|
+
if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
|
|
2125
|
+
return void 0;
|
|
2126
|
+
}
|
|
2127
|
+
if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
|
|
2128
|
+
return void 0;
|
|
2129
|
+
}
|
|
2130
|
+
if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
|
|
2131
|
+
return void 0;
|
|
2132
|
+
}
|
|
2133
|
+
return selectedPlusMemberVariant;
|
|
2134
|
+
}, [selectedPlusMemberMode, selectedPlusMemberVariant, hasMonthlyPlus, hasAnnualPlus]);
|
|
2135
|
+
return plusMemberVariant;
|
|
2055
2136
|
}
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2137
|
+
var PlusMemberProvider = ({
|
|
2138
|
+
variant,
|
|
2139
|
+
product,
|
|
2140
|
+
memberSetting,
|
|
2141
|
+
initialSelectedPlusMemberMode = "free",
|
|
2142
|
+
profile,
|
|
2143
|
+
children
|
|
2144
|
+
}) => {
|
|
2145
|
+
const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
|
|
2146
|
+
initialSelectedPlusMemberMode
|
|
2063
2147
|
);
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
const
|
|
2067
|
-
const
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2148
|
+
const [selectedShippingMethod, setSelectedShippingMethod] = react.useState();
|
|
2149
|
+
const [showMoreShippingMethod, setShowMoreShippingMethod] = react.useState(false);
|
|
2150
|
+
const [showPlusMemberBenefit, setShowPlusMemberBenefit] = react.useState(false);
|
|
2151
|
+
const shippingMethodsContext = useShippingMethods({
|
|
2152
|
+
variant,
|
|
2153
|
+
plusMemberMetafields: memberSetting,
|
|
2154
|
+
selectedPlusMemberMode,
|
|
2155
|
+
profile
|
|
2156
|
+
});
|
|
2157
|
+
const { monthlyVariant, annualVariant } = usePlusMemberVariants({
|
|
2158
|
+
memberSetting
|
|
2159
|
+
});
|
|
2160
|
+
const selectedPlusMemberVariant = react.useMemo(() => {
|
|
2161
|
+
if (selectedPlusMemberMode === "free" /* FREE */) {
|
|
2162
|
+
return void 0;
|
|
2163
|
+
}
|
|
2164
|
+
return selectedPlusMemberMode === "monthly" /* MONTHLY */ ? monthlyVariant : annualVariant;
|
|
2165
|
+
}, [monthlyVariant, annualVariant, selectedPlusMemberMode]);
|
|
2166
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2167
|
+
PlusMemberContext.Provider,
|
|
2168
|
+
{
|
|
2169
|
+
value: {
|
|
2170
|
+
variant,
|
|
2171
|
+
plusMemberMetafields: memberSetting,
|
|
2172
|
+
selectedPlusMemberMode,
|
|
2173
|
+
setSelectedPlusMemberMode,
|
|
2174
|
+
selectedShippingMethod,
|
|
2175
|
+
setSelectedShippingMethod,
|
|
2176
|
+
shippingMethodsContext,
|
|
2177
|
+
showMoreShippingMethod,
|
|
2178
|
+
setShowMoreShippingMethod,
|
|
2179
|
+
selectedPlusMemberVariant,
|
|
2180
|
+
product,
|
|
2181
|
+
showPlusMemberBenefit,
|
|
2182
|
+
setShowPlusMemberBenefit,
|
|
2183
|
+
profile
|
|
2184
|
+
},
|
|
2185
|
+
children
|
|
2186
|
+
}
|
|
2077
2187
|
);
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2188
|
+
};
|
|
2189
|
+
|
|
2190
|
+
// src/hooks/cart/use-add-to-cart.ts
|
|
2191
|
+
function useAddToCart({ withTrack = true } = {}, swrOptions) {
|
|
2192
|
+
const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
|
|
2193
|
+
const { cart, addCustomAttributes, memberSetting, profile, customer } = useCartContext();
|
|
2194
|
+
const { trigger: applyCartCodes } = useApplyCartCodes();
|
|
2195
|
+
const { trigger: removeInvalidCodes } = useRemoveCartCodes();
|
|
2196
|
+
const { trigger: addCartLines2 } = useAddCartLines();
|
|
2197
|
+
const { trigger: createCart4 } = useCreateCart({
|
|
2198
|
+
updateCookie: true
|
|
2199
|
+
});
|
|
2200
|
+
const { hasPlusMember } = useHasPlusMemberInCart({
|
|
2201
|
+
memberSetting,
|
|
2202
|
+
cart
|
|
2203
|
+
});
|
|
2204
|
+
const { attributes: cartAttributes } = useCartAttributes({
|
|
2205
|
+
profile,
|
|
2206
|
+
customer,
|
|
2207
|
+
cart,
|
|
2208
|
+
memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
|
|
2209
|
+
});
|
|
2210
|
+
const addToCart = react.useCallback(
|
|
2211
|
+
async (_key, { arg }) => {
|
|
2212
|
+
const {
|
|
2213
|
+
lineItems,
|
|
2214
|
+
cartId: providedCartId,
|
|
2215
|
+
discountCodes,
|
|
2216
|
+
gtmParams = {},
|
|
2217
|
+
buyerIdentity,
|
|
2218
|
+
needCreateCart = false,
|
|
2219
|
+
onCodesInvalid,
|
|
2220
|
+
replaceExistingCodes,
|
|
2221
|
+
customAttributes
|
|
2222
|
+
} = arg;
|
|
2223
|
+
if (!lineItems || lineItems.length === 0) {
|
|
2224
|
+
return;
|
|
2225
|
+
}
|
|
2226
|
+
performanceAdapter?.addToCartStart();
|
|
2227
|
+
const linesWithFunctionAttributes = getLinesWithAttributes({ cart, lineItems });
|
|
2228
|
+
const lines = linesWithFunctionAttributes.map((item) => ({
|
|
2229
|
+
merchandiseId: item.variant?.id || "",
|
|
2230
|
+
quantity: item.quantity || 1,
|
|
2231
|
+
attributes: item.attributes,
|
|
2232
|
+
sellingPlanId: item.sellingPlanId
|
|
2233
|
+
})).filter((item) => item.merchandiseId && item.quantity);
|
|
2234
|
+
if (lines.length === 0) {
|
|
2235
|
+
return;
|
|
2236
|
+
}
|
|
2237
|
+
let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
|
|
2238
|
+
let resultCart = null;
|
|
2239
|
+
if (!cartId) {
|
|
2240
|
+
resultCart = await createCart4({
|
|
2241
|
+
lines,
|
|
2242
|
+
buyerIdentity,
|
|
2243
|
+
discountCodes,
|
|
2244
|
+
customAttributes: [...cartAttributes, ...customAttributes || []]
|
|
2245
|
+
// 初次加购时,就把所有 cart attributes 带上
|
|
2246
|
+
});
|
|
2247
|
+
} else {
|
|
2248
|
+
resultCart = await addCartLines2({
|
|
2249
|
+
cartId,
|
|
2250
|
+
lines
|
|
2251
|
+
});
|
|
2252
|
+
console.log("npm addCartLines resultCart", resultCart);
|
|
2253
|
+
if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
|
|
2254
|
+
const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
|
|
2255
|
+
if (unapplicableCodes.length > 0) {
|
|
2256
|
+
if (onCodesInvalid) {
|
|
2257
|
+
const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
|
|
2258
|
+
if (handledCart) {
|
|
2259
|
+
resultCart = handledCart;
|
|
2260
|
+
}
|
|
2261
|
+
} else {
|
|
2262
|
+
await removeInvalidCodes({
|
|
2263
|
+
discountCodes: unapplicableCodes
|
|
2264
|
+
});
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
if (resultCart && discountCodes && discountCodes.length > 0) {
|
|
2269
|
+
applyCartCodes({
|
|
2270
|
+
replaceExistingCodes,
|
|
2271
|
+
discountCodes
|
|
2272
|
+
});
|
|
2273
|
+
}
|
|
2274
|
+
if (customAttributes && customAttributes.length > 0) {
|
|
2275
|
+
addCustomAttributes(customAttributes);
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
if (withTrack) {
|
|
2279
|
+
trackAddToCartGA({
|
|
2280
|
+
lineItems,
|
|
2281
|
+
gtmParams: { ...gtmParams, brand: config.getBrand() }
|
|
2282
|
+
});
|
|
2283
|
+
trackAddToCartFBQ({ lineItems });
|
|
2284
|
+
}
|
|
2285
|
+
performanceAdapter?.addToCartEnd();
|
|
2286
|
+
return resultCart;
|
|
2287
|
+
},
|
|
2288
|
+
[
|
|
2289
|
+
client,
|
|
2087
2290
|
locale,
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2291
|
+
cartCookieAdapter,
|
|
2292
|
+
userAdapter,
|
|
2293
|
+
cart,
|
|
2294
|
+
withTrack,
|
|
2295
|
+
performanceAdapter,
|
|
2296
|
+
createCart4,
|
|
2297
|
+
addCartLines2,
|
|
2298
|
+
applyCartCodes,
|
|
2299
|
+
removeInvalidCodes,
|
|
2300
|
+
addCustomAttributes,
|
|
2301
|
+
config
|
|
2302
|
+
]
|
|
2091
2303
|
);
|
|
2304
|
+
return useSWRMutation__default.default("add-to-cart", addToCart, swrOptions);
|
|
2092
2305
|
}
|
|
2093
|
-
function
|
|
2094
|
-
const { client, locale } = useShopify();
|
|
2095
|
-
const {
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2306
|
+
function useUpdateCartLines(options) {
|
|
2307
|
+
const { client, locale, cartCookieAdapter } = useShopify();
|
|
2308
|
+
const { mutateCart, metafieldIdentifiers } = useCartContext();
|
|
2309
|
+
const updateLines = react.useCallback(
|
|
2310
|
+
async (_key, { arg }) => {
|
|
2311
|
+
const updatedCart = await shopifySdk.updateCartLines(client, {
|
|
2312
|
+
...arg,
|
|
2313
|
+
metafieldIdentifiers,
|
|
2314
|
+
cookieAdapter: cartCookieAdapter
|
|
2315
|
+
});
|
|
2316
|
+
if (updatedCart) {
|
|
2317
|
+
mutateCart(updatedCart);
|
|
2318
|
+
}
|
|
2319
|
+
console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
|
|
2320
|
+
return updatedCart;
|
|
2321
|
+
},
|
|
2322
|
+
[client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
|
|
2107
2323
|
);
|
|
2324
|
+
return useSWRMutation__default.default("update-cart-lines", updateLines, options);
|
|
2108
2325
|
}
|
|
2109
|
-
function
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2326
|
+
function useUpdateCartAttributes({
|
|
2327
|
+
mutate,
|
|
2328
|
+
metafieldIdentifiers,
|
|
2329
|
+
disabled = false,
|
|
2330
|
+
swrOptions
|
|
2331
|
+
}) {
|
|
2332
|
+
const { client, locale, cartCookieAdapter } = useShopify();
|
|
2333
|
+
const updateAttributes = react.useCallback(
|
|
2334
|
+
async (_key, { arg }) => {
|
|
2335
|
+
if (disabled) {
|
|
2336
|
+
return void 0;
|
|
2337
|
+
}
|
|
2338
|
+
const updatedCart = await shopifySdk.updateCartAttributes(client, {
|
|
2339
|
+
...arg,
|
|
2340
|
+
metafieldIdentifiers,
|
|
2341
|
+
cookieAdapter: cartCookieAdapter
|
|
2342
|
+
});
|
|
2343
|
+
if (updatedCart) {
|
|
2344
|
+
mutate(updatedCart);
|
|
2345
|
+
}
|
|
2346
|
+
return updatedCart;
|
|
2347
|
+
},
|
|
2348
|
+
[client, locale, cartCookieAdapter, mutate, metafieldIdentifiers, disabled]
|
|
2123
2349
|
);
|
|
2350
|
+
return useSWRMutation__default.default("update-cart-attributes", updateAttributes, swrOptions);
|
|
2124
2351
|
}
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
const
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2352
|
+
function useBuyNow({ withTrack = true } = {}, swrOptions) {
|
|
2353
|
+
const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
|
|
2354
|
+
const { profile, customer, memberSetting } = useCartContext();
|
|
2355
|
+
const isLoggedIn = userAdapter?.isLoggedIn || false;
|
|
2356
|
+
const buyNow = react.useCallback(
|
|
2357
|
+
async (_key, { arg }) => {
|
|
2358
|
+
const {
|
|
2359
|
+
lineItems,
|
|
2360
|
+
discountCodes,
|
|
2361
|
+
gtmParams = {},
|
|
2362
|
+
buyerIdentity,
|
|
2363
|
+
fbqTrackConfig,
|
|
2364
|
+
customAttributes,
|
|
2365
|
+
metafieldIdentifiers,
|
|
2366
|
+
redirectToCheckout = true
|
|
2367
|
+
} = arg;
|
|
2368
|
+
if (!lineItems || lineItems.length === 0) {
|
|
2369
|
+
return;
|
|
2370
|
+
}
|
|
2371
|
+
const { hasPlusMember } = hasPlusMemberInLines({
|
|
2372
|
+
memberSetting,
|
|
2373
|
+
lines: lineItems
|
|
2374
|
+
});
|
|
2375
|
+
const memberType = hasPlusMember ? "2" : String(profile?.memberType ?? 0);
|
|
2376
|
+
const cartAttributes = getCartAttributes({
|
|
2377
|
+
profile,
|
|
2378
|
+
customer,
|
|
2379
|
+
memberType,
|
|
2380
|
+
currentUrl: window.location.href
|
|
2381
|
+
});
|
|
2382
|
+
const linesWithFunctionAttributes = getLinesWithAttributes({
|
|
2383
|
+
lineItems
|
|
2384
|
+
});
|
|
2385
|
+
const lines = linesWithFunctionAttributes.map((item) => ({
|
|
2386
|
+
merchandiseId: item.variant?.id || "",
|
|
2387
|
+
quantity: item.quantity || 1,
|
|
2388
|
+
attributes: item.attributes,
|
|
2389
|
+
sellingPlanId: item.sellingPlanId
|
|
2390
|
+
})).filter((item) => item.merchandiseId);
|
|
2391
|
+
if (lines.length === 0) {
|
|
2392
|
+
return;
|
|
2393
|
+
}
|
|
2394
|
+
const resultCart = await shopifySdk.createCart(client, {
|
|
2395
|
+
lines,
|
|
2396
|
+
metafieldIdentifiers,
|
|
2397
|
+
cookieAdapter: cartCookieAdapter,
|
|
2398
|
+
buyerIdentity,
|
|
2399
|
+
discountCodes,
|
|
2400
|
+
customAttributes: [...cartAttributes, ...customAttributes || []]
|
|
2401
|
+
});
|
|
2402
|
+
if (!resultCart) {
|
|
2403
|
+
throw new Error("Failed to create cart for buy now");
|
|
2404
|
+
}
|
|
2405
|
+
if (withTrack && resultCart.lineItems) {
|
|
2406
|
+
trackBuyNowGA({
|
|
2407
|
+
lineItems,
|
|
2408
|
+
gtmParams: { ...gtmParams, brand: config.getBrand() }
|
|
2409
|
+
});
|
|
2410
|
+
if (fbqTrackConfig) {
|
|
2411
|
+
trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
|
|
2167
2412
|
}
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2413
|
+
}
|
|
2414
|
+
if (redirectToCheckout) {
|
|
2415
|
+
if (resultCart.url) {
|
|
2416
|
+
if (typeof window !== "undefined") {
|
|
2417
|
+
window.location.href = resultCart.url;
|
|
2418
|
+
}
|
|
2419
|
+
} else {
|
|
2420
|
+
throw new Error("Failed to get checkout URL");
|
|
2171
2421
|
}
|
|
2172
2422
|
}
|
|
2173
|
-
|
|
2174
|
-
|
|
2423
|
+
return resultCart;
|
|
2424
|
+
},
|
|
2425
|
+
[client, locale, isLoggedIn, cartCookieAdapter, withTrack, customer, profile, memberSetting]
|
|
2175
2426
|
);
|
|
2176
|
-
|
|
2177
|
-
query: searchQuery,
|
|
2178
|
-
first,
|
|
2179
|
-
types
|
|
2180
|
-
});
|
|
2181
|
-
if (!data || !data.search) {
|
|
2182
|
-
return void 0;
|
|
2183
|
-
}
|
|
2184
|
-
const items = data.search.edges?.map((edge) => {
|
|
2185
|
-
const node = edge.node;
|
|
2186
|
-
const item = {
|
|
2187
|
-
type: node.__typename.toUpperCase(),
|
|
2188
|
-
id: node.id,
|
|
2189
|
-
handle: node.handle,
|
|
2190
|
-
title: node.title
|
|
2191
|
-
};
|
|
2192
|
-
if (node.__typename === "Product") {
|
|
2193
|
-
item.description = node.description;
|
|
2194
|
-
item.image = node.featuredImage ? {
|
|
2195
|
-
url: node.featuredImage.url,
|
|
2196
|
-
altText: node.featuredImage.altText
|
|
2197
|
-
} : void 0;
|
|
2198
|
-
} else if (node.__typename === "Article") {
|
|
2199
|
-
item.description = node.excerpt;
|
|
2200
|
-
item.image = node.image ? {
|
|
2201
|
-
url: node.image.url,
|
|
2202
|
-
altText: node.image.altText
|
|
2203
|
-
} : void 0;
|
|
2204
|
-
}
|
|
2205
|
-
return item;
|
|
2206
|
-
}) || [];
|
|
2207
|
-
return {
|
|
2208
|
-
items,
|
|
2209
|
-
totalCount: data.search.totalCount || 0,
|
|
2210
|
-
pageInfo: data.search.pageInfo
|
|
2211
|
-
};
|
|
2427
|
+
return useSWRMutation__default.default("buy-now", buyNow, swrOptions);
|
|
2212
2428
|
}
|
|
2213
|
-
|
|
2429
|
+
|
|
2430
|
+
// src/hooks/cart/types/price-discount.ts
|
|
2431
|
+
var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
|
|
2432
|
+
PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
|
|
2433
|
+
PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
|
|
2434
|
+
return PriceDiscountType2;
|
|
2435
|
+
})(PriceDiscountType || {});
|
|
2436
|
+
var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
|
|
2437
|
+
PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
|
|
2438
|
+
PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
|
|
2439
|
+
return PriceBasePriceType2;
|
|
2440
|
+
})(PriceBasePriceType || {});
|
|
2441
|
+
function useProduct(options = {}) {
|
|
2214
2442
|
const { client, locale } = useShopify();
|
|
2215
|
-
const {
|
|
2443
|
+
const { handle, metafieldIdentifiers, ...swrOptions } = options;
|
|
2216
2444
|
return useSWR__default.default(
|
|
2217
|
-
|
|
2218
|
-
() =>
|
|
2445
|
+
handle ? ["product", locale, handle, metafieldIdentifiers] : null,
|
|
2446
|
+
() => shopifySdk.getProduct(client, {
|
|
2447
|
+
handle,
|
|
2448
|
+
locale,
|
|
2449
|
+
metafieldIdentifiers
|
|
2450
|
+
}),
|
|
2219
2451
|
swrOptions
|
|
2220
2452
|
);
|
|
2221
2453
|
}
|
|
2222
|
-
|
|
2223
|
-
const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
|
|
2224
|
-
const query = (
|
|
2225
|
-
/* GraphQL */
|
|
2226
|
-
`
|
|
2227
|
-
query getSiteInfo(
|
|
2228
|
-
${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
|
|
2229
|
-
) @inContext(language: $language) {
|
|
2230
|
-
shop {
|
|
2231
|
-
name
|
|
2232
|
-
description
|
|
2233
|
-
primaryDomain {
|
|
2234
|
-
url
|
|
2235
|
-
host
|
|
2236
|
-
}
|
|
2237
|
-
brand {
|
|
2238
|
-
logo {
|
|
2239
|
-
image {
|
|
2240
|
-
url
|
|
2241
|
-
}
|
|
2242
|
-
}
|
|
2243
|
-
colors {
|
|
2244
|
-
primary {
|
|
2245
|
-
background
|
|
2246
|
-
}
|
|
2247
|
-
secondary {
|
|
2248
|
-
background
|
|
2249
|
-
}
|
|
2250
|
-
}
|
|
2251
|
-
}
|
|
2252
|
-
${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
|
|
2253
|
-
}
|
|
2254
|
-
}
|
|
2255
|
-
`
|
|
2256
|
-
);
|
|
2257
|
-
const variables = {};
|
|
2258
|
-
if (hasMetafields) {
|
|
2259
|
-
variables.shopMetafieldIdentifiers = metafieldIdentifiers;
|
|
2260
|
-
}
|
|
2261
|
-
const data = await client.query(query, variables);
|
|
2262
|
-
if (!data || !data.shop) {
|
|
2263
|
-
return void 0;
|
|
2264
|
-
}
|
|
2265
|
-
const shop = data.shop;
|
|
2266
|
-
const metafields = shop.metafields?.reduce((acc, mf) => {
|
|
2267
|
-
if (mf && mf.key) {
|
|
2268
|
-
acc[mf.key] = mf.value;
|
|
2269
|
-
}
|
|
2270
|
-
return acc;
|
|
2271
|
-
}, {});
|
|
2272
|
-
return {
|
|
2273
|
-
name: shop.name,
|
|
2274
|
-
description: shop.description,
|
|
2275
|
-
primaryDomain: shop.primaryDomain,
|
|
2276
|
-
brand: shop.brand ? {
|
|
2277
|
-
logo: shop.brand.logo,
|
|
2278
|
-
colors: shop.brand.colors ? {
|
|
2279
|
-
primary: shop.brand.colors.primary?.background,
|
|
2280
|
-
secondary: shop.brand.colors.secondary?.background
|
|
2281
|
-
} : void 0
|
|
2282
|
-
} : void 0,
|
|
2283
|
-
metafields
|
|
2284
|
-
};
|
|
2285
|
-
}
|
|
2286
|
-
function useSite(options = {}) {
|
|
2454
|
+
function useAllProducts(options = {}) {
|
|
2287
2455
|
const { client, locale } = useShopify();
|
|
2288
|
-
const { metafieldIdentifiers, ...swrOptions } = options;
|
|
2456
|
+
const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
|
|
2289
2457
|
return useSWR__default.default(
|
|
2290
|
-
["
|
|
2291
|
-
() =>
|
|
2458
|
+
["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
|
|
2459
|
+
() => shopifySdk.getAllProducts(client, {
|
|
2460
|
+
locale,
|
|
2461
|
+
first,
|
|
2462
|
+
query,
|
|
2463
|
+
sortKey,
|
|
2464
|
+
reverse,
|
|
2465
|
+
metafieldIdentifiers
|
|
2466
|
+
}),
|
|
2292
2467
|
swrOptions
|
|
2293
2468
|
);
|
|
2294
2469
|
}
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
|
|
2299
|
-
PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
|
|
2300
|
-
PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
|
|
2301
|
-
return PLUS_MEMBER_TYPE2;
|
|
2302
|
-
})(PLUS_MEMBER_TYPE || {});
|
|
2303
|
-
var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
|
|
2304
|
-
PlusMemberMode2["MONTHLY"] = "monthly";
|
|
2305
|
-
PlusMemberMode2["ANNUAL"] = "annual";
|
|
2306
|
-
return PlusMemberMode2;
|
|
2307
|
-
})(PlusMemberMode || {});
|
|
2308
|
-
var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
|
|
2309
|
-
DeliveryPlusType2["FREE"] = "free";
|
|
2310
|
-
DeliveryPlusType2["MONTHLY"] = "monthly";
|
|
2311
|
-
DeliveryPlusType2["ANNUAL"] = "annual";
|
|
2312
|
-
return DeliveryPlusType2;
|
|
2313
|
-
})(DeliveryPlusType || {});
|
|
2314
|
-
var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
|
|
2315
|
-
ShippingMethodMode2["FREE"] = "free";
|
|
2316
|
-
ShippingMethodMode2["TDD"] = "tdd";
|
|
2317
|
-
ShippingMethodMode2["NDD"] = "ndd";
|
|
2318
|
-
return ShippingMethodMode2;
|
|
2319
|
-
})(ShippingMethodMode || {});
|
|
2320
|
-
var createInitialValue = () => ({
|
|
2321
|
-
zipCode: "",
|
|
2322
|
-
plusMemberMetafields: {},
|
|
2323
|
-
setZipCode: () => {
|
|
2324
|
-
},
|
|
2325
|
-
allowNextDayDelivery: false,
|
|
2326
|
-
setAllowNextDayDelivery: () => {
|
|
2327
|
-
},
|
|
2328
|
-
allowThirdDayDelivery: false,
|
|
2329
|
-
setAllowThirdDayDelivery: () => {
|
|
2330
|
-
},
|
|
2331
|
-
selectedPlusMemberMode: "free",
|
|
2332
|
-
setSelectedPlusMemberMode: () => {
|
|
2333
|
-
},
|
|
2334
|
-
showAreaCheckModal: false,
|
|
2335
|
-
setShowAreaCheckModal: () => {
|
|
2336
|
-
},
|
|
2337
|
-
selectedShippingMethod: void 0,
|
|
2338
|
-
setSelectedShippingMethod: () => {
|
|
2339
|
-
},
|
|
2340
|
-
showTip: false,
|
|
2341
|
-
setShowTip: () => {
|
|
2342
|
-
},
|
|
2343
|
-
showMoreShippingMethod: false,
|
|
2344
|
-
setShowMoreShippingMethod: () => {
|
|
2345
|
-
},
|
|
2346
|
-
variant: {},
|
|
2347
|
-
product: {},
|
|
2348
|
-
shippingMethodsContext: {
|
|
2349
|
-
freeShippingMethods: [],
|
|
2350
|
-
paymentShippingMethods: [],
|
|
2351
|
-
nddOverweight: false,
|
|
2352
|
-
tddOverweight: false
|
|
2353
|
-
},
|
|
2354
|
-
selectedPlusMemberProduct: null,
|
|
2355
|
-
plusMemberProducts: [],
|
|
2356
|
-
showPlusMemberBenefit: false,
|
|
2357
|
-
setShowPlusMemberBenefit: () => {
|
|
2358
|
-
},
|
|
2359
|
-
deleteMarginBottom: false,
|
|
2360
|
-
setDeleteMarginBottom: () => {
|
|
2361
|
-
},
|
|
2362
|
-
profile: void 0,
|
|
2363
|
-
locale: void 0
|
|
2364
|
-
});
|
|
2365
|
-
var PlusMemberContext = react.createContext(createInitialValue());
|
|
2366
|
-
function usePlusMemberContext() {
|
|
2367
|
-
return react.useContext(PlusMemberContext);
|
|
2470
|
+
function getFirstAvailableVariant(product) {
|
|
2471
|
+
const availableVariant = product.variants.find((v) => v.availableForSale);
|
|
2472
|
+
return availableVariant || product.variants[0];
|
|
2368
2473
|
}
|
|
2369
|
-
function
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
);
|
|
2376
|
-
const productVariant = product?.variants?.find(
|
|
2377
|
-
(item) => item.sku === plusMonthly?.sku
|
|
2378
|
-
);
|
|
2379
|
-
return productVariant;
|
|
2380
|
-
}, [plusMemberProducts, plusMonthly]);
|
|
2381
|
-
return plusMonthlyProductVariant;
|
|
2474
|
+
function getVariantFromSelectedOptions(product, selectedOptions) {
|
|
2475
|
+
return product.variants.find((variant) => {
|
|
2476
|
+
return variant.selectedOptions.every((option) => {
|
|
2477
|
+
return selectedOptions[option.name] === option.value;
|
|
2478
|
+
});
|
|
2479
|
+
});
|
|
2382
2480
|
}
|
|
2383
|
-
function
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2481
|
+
function useVariant({
|
|
2482
|
+
product,
|
|
2483
|
+
selectedOptions
|
|
2484
|
+
}) {
|
|
2485
|
+
const [variant, setVariant] = react.useState(
|
|
2486
|
+
product ? getFirstAvailableVariant(product) : void 0
|
|
2487
|
+
);
|
|
2488
|
+
react.useEffect(() => {
|
|
2489
|
+
if (!product) {
|
|
2490
|
+
setVariant(void 0);
|
|
2491
|
+
return;
|
|
2492
|
+
}
|
|
2493
|
+
const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
|
|
2494
|
+
if (newVariant && newVariant.id !== variant?.id) {
|
|
2495
|
+
setVariant(newVariant);
|
|
2496
|
+
} else if (!newVariant) {
|
|
2497
|
+
setVariant(getFirstAvailableVariant(product));
|
|
2498
|
+
}
|
|
2499
|
+
}, [selectedOptions, product, variant?.id]);
|
|
2500
|
+
return variant;
|
|
2396
2501
|
}
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
const
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
const
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
|
|
2460
|
-
return __mode === "tdd" && fitWeight;
|
|
2461
|
-
}
|
|
2462
|
-
);
|
|
2463
|
-
return tddMethod?.price || 0;
|
|
2464
|
-
}, [variant?.weight, paymentShippingMethods]);
|
|
2465
|
-
const freeShippingMethods = react.useMemo(() => {
|
|
2466
|
-
const weight = variant?.weight || 0;
|
|
2467
|
-
let methods = plus_shipping?.shipping_methods?.filter(
|
|
2468
|
-
({ __mode, __plus, weight_low, weight_high }) => {
|
|
2469
|
-
if (__mode === "free" /* FREE */) {
|
|
2470
|
-
return true;
|
|
2471
|
-
}
|
|
2472
|
-
if (isPlus) {
|
|
2473
|
-
const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
|
|
2474
|
-
const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
|
|
2475
|
-
return hasCoupon && fitWeight && !__plus;
|
|
2476
|
-
} else {
|
|
2477
|
-
return __plus;
|
|
2478
|
-
}
|
|
2479
|
-
}
|
|
2480
|
-
) || [];
|
|
2481
|
-
if (isPlus) {
|
|
2482
|
-
methods = methods.sort((a, b) => {
|
|
2483
|
-
if (b.__mode === "free" /* FREE */) return -1;
|
|
2484
|
-
return 0;
|
|
2485
|
-
});
|
|
2502
|
+
var FAKE_PRICE = 999999999e-2;
|
|
2503
|
+
function formatPrice({
|
|
2504
|
+
amount,
|
|
2505
|
+
currencyCode,
|
|
2506
|
+
locale,
|
|
2507
|
+
maximumFractionDigits,
|
|
2508
|
+
minimumFractionDigits,
|
|
2509
|
+
removeTrailingZeros
|
|
2510
|
+
}) {
|
|
2511
|
+
const formatter = new Intl.NumberFormat(locale, {
|
|
2512
|
+
style: "currency",
|
|
2513
|
+
currency: currencyCode,
|
|
2514
|
+
maximumFractionDigits: maximumFractionDigits ?? 2,
|
|
2515
|
+
minimumFractionDigits: minimumFractionDigits ?? 2
|
|
2516
|
+
});
|
|
2517
|
+
let formatted = formatter.format(amount);
|
|
2518
|
+
if (removeTrailingZeros) {
|
|
2519
|
+
formatted = formatted.replace(/\.00$/, "");
|
|
2520
|
+
}
|
|
2521
|
+
return formatted;
|
|
2522
|
+
}
|
|
2523
|
+
function formatVariantPrice({
|
|
2524
|
+
amount,
|
|
2525
|
+
baseAmount,
|
|
2526
|
+
currencyCode,
|
|
2527
|
+
locale,
|
|
2528
|
+
maximumFractionDigits,
|
|
2529
|
+
minimumFractionDigits,
|
|
2530
|
+
removeTrailingZeros
|
|
2531
|
+
}) {
|
|
2532
|
+
return {
|
|
2533
|
+
price: formatPrice({
|
|
2534
|
+
amount,
|
|
2535
|
+
currencyCode,
|
|
2536
|
+
locale,
|
|
2537
|
+
maximumFractionDigits,
|
|
2538
|
+
minimumFractionDigits,
|
|
2539
|
+
removeTrailingZeros
|
|
2540
|
+
}),
|
|
2541
|
+
basePrice: formatPrice({
|
|
2542
|
+
amount: baseAmount,
|
|
2543
|
+
currencyCode,
|
|
2544
|
+
locale,
|
|
2545
|
+
maximumFractionDigits,
|
|
2546
|
+
minimumFractionDigits,
|
|
2547
|
+
removeTrailingZeros
|
|
2548
|
+
})
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
function usePrice({
|
|
2552
|
+
amount,
|
|
2553
|
+
baseAmount,
|
|
2554
|
+
currencyCode,
|
|
2555
|
+
soldOutDescription = "",
|
|
2556
|
+
maximumFractionDigits,
|
|
2557
|
+
minimumFractionDigits,
|
|
2558
|
+
removeTrailingZeros
|
|
2559
|
+
}) {
|
|
2560
|
+
const { locale } = useShopify();
|
|
2561
|
+
const value = react.useMemo(() => {
|
|
2562
|
+
if (typeof amount !== "number" || !currencyCode) {
|
|
2563
|
+
return "";
|
|
2486
2564
|
}
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
} else if (method.__mode === "tdd" /* TDD */) {
|
|
2506
|
-
disabled = disabled || tddOverweight;
|
|
2507
|
-
}
|
|
2508
|
-
}
|
|
2509
|
-
return {
|
|
2510
|
-
...method,
|
|
2511
|
-
id: method.__mode + method.__code,
|
|
2512
|
-
useCoupon: true,
|
|
2513
|
-
disabled,
|
|
2514
|
-
coupon,
|
|
2515
|
-
price
|
|
2516
|
-
};
|
|
2565
|
+
if (soldOutDescription && amount >= FAKE_PRICE) {
|
|
2566
|
+
return soldOutDescription;
|
|
2567
|
+
}
|
|
2568
|
+
return baseAmount ? formatVariantPrice({
|
|
2569
|
+
amount,
|
|
2570
|
+
baseAmount,
|
|
2571
|
+
currencyCode,
|
|
2572
|
+
locale,
|
|
2573
|
+
maximumFractionDigits,
|
|
2574
|
+
minimumFractionDigits,
|
|
2575
|
+
removeTrailingZeros
|
|
2576
|
+
}) : formatPrice({
|
|
2577
|
+
amount,
|
|
2578
|
+
currencyCode,
|
|
2579
|
+
locale,
|
|
2580
|
+
maximumFractionDigits,
|
|
2581
|
+
minimumFractionDigits,
|
|
2582
|
+
removeTrailingZeros
|
|
2517
2583
|
});
|
|
2518
2584
|
}, [
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
nddOverweight,
|
|
2528
|
-
tddOverweight
|
|
2585
|
+
amount,
|
|
2586
|
+
baseAmount,
|
|
2587
|
+
currencyCode,
|
|
2588
|
+
locale,
|
|
2589
|
+
maximumFractionDigits,
|
|
2590
|
+
minimumFractionDigits,
|
|
2591
|
+
soldOutDescription,
|
|
2592
|
+
removeTrailingZeros
|
|
2529
2593
|
]);
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
};
|
|
2594
|
+
const result = react.useMemo(() => {
|
|
2595
|
+
const free = Boolean(amount && amount <= 0);
|
|
2596
|
+
return typeof value === "string" ? { price: value, basePrice: value, free } : { ...value, free };
|
|
2597
|
+
}, [value, amount]);
|
|
2598
|
+
return result;
|
|
2536
2599
|
}
|
|
2537
|
-
function
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2600
|
+
function optionsConstructor(selectedOptions) {
|
|
2601
|
+
return selectedOptions.reduce((acc, option) => {
|
|
2602
|
+
acc[option.name] = option.value;
|
|
2603
|
+
return acc;
|
|
2604
|
+
}, {});
|
|
2605
|
+
}
|
|
2606
|
+
function decodeShopifyId(gid) {
|
|
2607
|
+
try {
|
|
2608
|
+
const base64 = gid.split("/").pop() || "";
|
|
2609
|
+
return atob(base64);
|
|
2610
|
+
} catch {
|
|
2611
|
+
return gid;
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
function useSelectedOptions(product, sku) {
|
|
2615
|
+
const [options, setOptions] = react.useState({});
|
|
2547
2616
|
react.useEffect(() => {
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
(
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
);
|
|
2564
|
-
if (!allowNextDayDelivery && !allowThirdDayDelivery) {
|
|
2565
|
-
setShowTip(true);
|
|
2566
|
-
setSelectedShippingMethod(standardShippingMethod);
|
|
2567
|
-
} else {
|
|
2568
|
-
if (selectedShippingMethod?.__mode === "ndd" /* NDD */ && !allowNextDayDelivery) {
|
|
2569
|
-
setShowTip(true);
|
|
2570
|
-
if (allowThirdDayDelivery) {
|
|
2571
|
-
if (selectedShippingMethod.useCoupon) {
|
|
2572
|
-
const method = freeTDD || freeShippingMethod;
|
|
2573
|
-
if (method) setSelectedShippingMethod(method);
|
|
2574
|
-
} else {
|
|
2575
|
-
const method = paymentTDD || freeShippingMethod;
|
|
2576
|
-
if (method) setSelectedShippingMethod(method);
|
|
2577
|
-
}
|
|
2578
|
-
} else {
|
|
2579
|
-
if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
|
|
2580
|
-
}
|
|
2581
|
-
} else if (
|
|
2582
|
-
// TDD 无法使用
|
|
2583
|
-
selectedShippingMethod?.__mode === "tdd" /* TDD */ && !allowThirdDayDelivery
|
|
2584
|
-
) {
|
|
2585
|
-
setShowTip(true);
|
|
2586
|
-
if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
|
|
2617
|
+
if (!product || !product.variants.length) {
|
|
2618
|
+
setOptions({});
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2621
|
+
let variant = product.variants[0];
|
|
2622
|
+
if (typeof window !== "undefined") {
|
|
2623
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
2624
|
+
const variantIdParam = searchParams.get("variant");
|
|
2625
|
+
if (variantIdParam) {
|
|
2626
|
+
const foundVariant = product.variants.find((v) => {
|
|
2627
|
+
if (sku) return v.sku === sku;
|
|
2628
|
+
return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
|
|
2629
|
+
});
|
|
2630
|
+
if (foundVariant) {
|
|
2631
|
+
variant = foundVariant;
|
|
2587
2632
|
}
|
|
2588
2633
|
}
|
|
2589
2634
|
}
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
zipCode,
|
|
2594
|
-
shippingMethodsContext,
|
|
2595
|
-
selectedShippingMethod,
|
|
2596
|
-
setSelectedShippingMethod,
|
|
2597
|
-
setShowTip
|
|
2598
|
-
]);
|
|
2599
|
-
}
|
|
2600
|
-
var useReplaceCartPlusMember = () => {
|
|
2601
|
-
const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
|
|
2602
|
-
const { trigger: removeCartLines2 } = useRemoveCartLines();
|
|
2603
|
-
const { cart } = useCartContext();
|
|
2604
|
-
const plusMonthly = plusMemberMetafields?.plus_monthly_product;
|
|
2605
|
-
const plusAnnual = plusMemberMetafields?.plus_annual_product;
|
|
2606
|
-
const handler = react.useCallback(async () => {
|
|
2607
|
-
const plusMonthlyInCart = cart?.lineItems.find(
|
|
2608
|
-
(item) => item.variant?.sku === plusMonthly?.sku
|
|
2609
|
-
);
|
|
2610
|
-
const plusAnnualInCart = cart?.lineItems.find(
|
|
2611
|
-
(item) => item.variant?.sku === plusAnnual?.sku
|
|
2612
|
-
);
|
|
2613
|
-
if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
|
|
2614
|
-
await removeCartLines2({
|
|
2615
|
-
lineIds: [plusMonthlyInCart.id]
|
|
2616
|
-
});
|
|
2617
|
-
} else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
|
|
2618
|
-
await removeCartLines2({
|
|
2619
|
-
lineIds: [plusAnnualInCart.id]
|
|
2620
|
-
});
|
|
2635
|
+
if (variant) {
|
|
2636
|
+
const newOptions = optionsConstructor(variant.selectedOptions);
|
|
2637
|
+
setOptions(newOptions);
|
|
2621
2638
|
}
|
|
2622
|
-
}, [
|
|
2623
|
-
|
|
2624
|
-
selectedPlusMemberMode,
|
|
2625
|
-
plusMonthly?.sku,
|
|
2626
|
-
plusAnnual?.sku,
|
|
2627
|
-
removeCartLines2
|
|
2628
|
-
]);
|
|
2629
|
-
return handler;
|
|
2630
|
-
};
|
|
2631
|
-
var usePlusMemberDeliveryCodes = ({
|
|
2632
|
-
deliveryData
|
|
2633
|
-
}) => {
|
|
2634
|
-
return react.useMemo(
|
|
2635
|
-
() => deliveryData?.deliveryCustomData?.discount_code,
|
|
2636
|
-
[deliveryData]
|
|
2637
|
-
);
|
|
2638
|
-
};
|
|
2639
|
-
function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
|
|
2640
|
-
const { client, locale, cartCookieAdapter } = useShopify();
|
|
2641
|
-
const updateDeliveryOptions = react.useCallback(
|
|
2642
|
-
async (_key, { arg }) => {
|
|
2643
|
-
const updatedCart = await shopifySdk.updateCartDeliveryOptions(client, {
|
|
2644
|
-
...arg,
|
|
2645
|
-
metafieldIdentifiers,
|
|
2646
|
-
cookieAdapter: cartCookieAdapter
|
|
2647
|
-
});
|
|
2648
|
-
console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
|
|
2649
|
-
if (updatedCart) {
|
|
2650
|
-
mutate(updatedCart);
|
|
2651
|
-
}
|
|
2652
|
-
return updatedCart;
|
|
2653
|
-
},
|
|
2654
|
-
[client, locale, cartCookieAdapter, mutate]
|
|
2655
|
-
);
|
|
2656
|
-
return useSWRMutation__default.default("update-cart-delivery-options", updateDeliveryOptions, options);
|
|
2639
|
+
}, [product, sku]);
|
|
2640
|
+
return [options, setOptions];
|
|
2657
2641
|
}
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2642
|
+
function decodeShopifyId2(gid) {
|
|
2643
|
+
try {
|
|
2644
|
+
const parts = gid.split("/");
|
|
2645
|
+
return parts[parts.length - 1] || gid;
|
|
2646
|
+
} catch {
|
|
2647
|
+
return gid;
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
function useProductUrl(otherQuery) {
|
|
2651
|
+
const { routerAdapter } = useShopify();
|
|
2652
|
+
return react.useCallback(
|
|
2653
|
+
({ product, variant }) => {
|
|
2654
|
+
if (!product) return "";
|
|
2655
|
+
const queryParams = new URLSearchParams();
|
|
2656
|
+
if (variant?.id) {
|
|
2657
|
+
const variantId = decodeShopifyId2(variant.id);
|
|
2658
|
+
if (variantId) {
|
|
2659
|
+
queryParams.set("variant", variantId);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
if (otherQuery) {
|
|
2663
|
+
Object.entries(otherQuery).forEach(([key, value]) => {
|
|
2664
|
+
queryParams.set(key, value);
|
|
2665
|
+
});
|
|
2666
|
+
}
|
|
2667
|
+
const queryString = queryParams.toString();
|
|
2668
|
+
const path = `/products/${product.handle}${queryString ? `?${queryString}` : ""}`;
|
|
2669
|
+
if (routerAdapter?.getLocalizedPath) {
|
|
2670
|
+
return routerAdapter.getLocalizedPath(path);
|
|
2686
2671
|
}
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2672
|
+
return path;
|
|
2673
|
+
},
|
|
2674
|
+
[routerAdapter, otherQuery]
|
|
2675
|
+
);
|
|
2676
|
+
}
|
|
2677
|
+
function decodeShopifyId3(gid) {
|
|
2678
|
+
try {
|
|
2679
|
+
const parts = gid.split("/");
|
|
2680
|
+
return parts[parts.length - 1] || gid;
|
|
2681
|
+
} catch {
|
|
2682
|
+
return gid;
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
function useUpdateVariantQuery(variant) {
|
|
2686
|
+
react.useEffect(() => {
|
|
2687
|
+
if (!variant || typeof window === "undefined") {
|
|
2688
|
+
return;
|
|
2695
2689
|
}
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
}
|
|
2703
|
-
const { deliveryCustomData } = deliveryData || {};
|
|
2704
|
-
return react.useMemo(() => {
|
|
2705
|
-
const itemCustomAttributes = [];
|
|
2706
|
-
if (deliveryCustomData?.is_presale) {
|
|
2707
|
-
itemCustomAttributes.push({
|
|
2708
|
-
key: "_is_presale",
|
|
2709
|
-
value: "true"
|
|
2710
|
-
});
|
|
2690
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
2691
|
+
const currentVariantId = searchParams.get("variant");
|
|
2692
|
+
const newVariantId = decodeShopifyId3(variant.id);
|
|
2693
|
+
if (newVariantId && currentVariantId !== newVariantId) {
|
|
2694
|
+
searchParams.set("variant", newVariantId);
|
|
2695
|
+
const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
|
|
2696
|
+
window.history.replaceState({}, "", newUrl);
|
|
2711
2697
|
}
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
var usePlusMemberCheckoutCustomAttributes = ({
|
|
2716
|
-
deliveryData,
|
|
2698
|
+
}, [variant]);
|
|
2699
|
+
}
|
|
2700
|
+
function getVariantMediaList({
|
|
2717
2701
|
product,
|
|
2718
|
-
variant
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
const customerInfo = customer;
|
|
2726
|
-
if (!customerInfo) {
|
|
2727
|
-
return "new_user_unlogin";
|
|
2728
|
-
}
|
|
2729
|
-
if (customer) {
|
|
2730
|
-
const { orders = {} } = customer;
|
|
2731
|
-
const edgesLength = orders?.edges?.length;
|
|
2732
|
-
if (edgesLength === 1) {
|
|
2733
|
-
return "old_user_orders_once";
|
|
2734
|
-
} else if (edgesLength && edgesLength > 1) {
|
|
2735
|
-
return "old_user_orders_twice";
|
|
2736
|
-
}
|
|
2737
|
-
}
|
|
2738
|
-
return "new_user_login";
|
|
2739
|
-
}, [customer]);
|
|
2740
|
-
return react.useMemo(() => {
|
|
2741
|
-
const checkoutCustomAttributes = [
|
|
2742
|
-
{
|
|
2743
|
-
key: "_token",
|
|
2744
|
-
value: profile?.token || ""
|
|
2745
|
-
},
|
|
2746
|
-
{
|
|
2747
|
-
key: "_last_url",
|
|
2748
|
-
value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
|
|
2749
|
-
},
|
|
2750
|
-
{
|
|
2751
|
-
key: "_user_type",
|
|
2752
|
-
value: userType
|
|
2702
|
+
variant
|
|
2703
|
+
}) {
|
|
2704
|
+
if (variant.image?.url) {
|
|
2705
|
+
const variantMediaId = variant.image.url;
|
|
2706
|
+
const variantMedia = product.media.filter((media) => {
|
|
2707
|
+
if (media.mediaContentType === "IMAGE" && media.previewImage) {
|
|
2708
|
+
return media.previewImage?.url === variantMediaId;
|
|
2753
2709
|
}
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
checkoutCustomAttributes.push({
|
|
2763
|
-
key: "_checkout_delivery_custom",
|
|
2764
|
-
value: JSON.stringify({
|
|
2765
|
-
...deliveryCustomData,
|
|
2766
|
-
is_prime: profile?.isPlus
|
|
2767
|
-
})
|
|
2768
|
-
});
|
|
2769
|
-
}
|
|
2770
|
-
if (variant?.metafields?.presell) {
|
|
2771
|
-
checkoutCustomAttributes.push({
|
|
2772
|
-
key: "_presale",
|
|
2773
|
-
value: "true"
|
|
2774
|
-
});
|
|
2775
|
-
}
|
|
2776
|
-
if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
|
|
2777
|
-
checkoutCustomAttributes.push({
|
|
2778
|
-
key: "_hide_shipping",
|
|
2779
|
-
value: "true"
|
|
2710
|
+
return false;
|
|
2711
|
+
});
|
|
2712
|
+
if (variantMedia.length > 0) {
|
|
2713
|
+
const otherMedia = product.media.filter((media) => {
|
|
2714
|
+
if (media.mediaContentType === "IMAGE" && media.previewImage) {
|
|
2715
|
+
return media.previewImage.url !== variantMediaId;
|
|
2716
|
+
}
|
|
2717
|
+
return true;
|
|
2780
2718
|
});
|
|
2719
|
+
return [...variantMedia, ...otherMedia];
|
|
2781
2720
|
}
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
}
|
|
2785
|
-
function
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
memberSetting
|
|
2721
|
+
}
|
|
2722
|
+
return product.media;
|
|
2723
|
+
}
|
|
2724
|
+
function useVariantMedia({
|
|
2725
|
+
product,
|
|
2726
|
+
variant
|
|
2789
2727
|
}) {
|
|
2790
|
-
const
|
|
2791
|
-
const
|
|
2728
|
+
const [imageList, setImageList] = react.useState([]);
|
|
2729
|
+
const [sceneList, setSceneList] = react.useState([]);
|
|
2730
|
+
const [videoList, setVideoList] = react.useState([]);
|
|
2792
2731
|
react.useEffect(() => {
|
|
2793
|
-
if (!
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2732
|
+
if (!product || !variant) {
|
|
2733
|
+
setImageList([]);
|
|
2734
|
+
setSceneList([]);
|
|
2735
|
+
setVideoList([]);
|
|
2736
|
+
return;
|
|
2737
|
+
}
|
|
2738
|
+
const mediaList = getVariantMediaList({ product, variant });
|
|
2739
|
+
const images = mediaList.filter((media) => media.mediaContentType === "IMAGE");
|
|
2740
|
+
const videos = mediaList.filter(
|
|
2741
|
+
(media) => media.mediaContentType === "VIDEO" || media.mediaContentType === "EXTERNAL_VIDEO"
|
|
2742
|
+
);
|
|
2743
|
+
setImageList(images.length > 0 && images[0] ? [images[0]] : []);
|
|
2744
|
+
setSceneList(images.length > 1 ? images.slice(1) : []);
|
|
2745
|
+
setVideoList(videos);
|
|
2746
|
+
}, [product, variant]);
|
|
2747
|
+
return {
|
|
2748
|
+
productList: imageList,
|
|
2749
|
+
sceneList,
|
|
2750
|
+
videoList
|
|
2751
|
+
};
|
|
2752
|
+
}
|
|
2753
|
+
function useCollection(options = {}) {
|
|
2754
|
+
const { client, locale } = useShopify();
|
|
2755
|
+
const { handle, metafieldIdentifiers, ...swrOptions } = options;
|
|
2756
|
+
return useSWR__default.default(
|
|
2757
|
+
handle ? ["collection", locale, handle, metafieldIdentifiers] : null,
|
|
2758
|
+
() => shopifySdk.getCollection(client, {
|
|
2759
|
+
handle,
|
|
2760
|
+
locale,
|
|
2761
|
+
metafieldIdentifiers
|
|
2762
|
+
}),
|
|
2763
|
+
swrOptions
|
|
2764
|
+
);
|
|
2765
|
+
}
|
|
2766
|
+
function useAllCollections(options = {}) {
|
|
2767
|
+
const { client, locale } = useShopify();
|
|
2768
|
+
const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
|
|
2769
|
+
return useSWR__default.default(
|
|
2770
|
+
["all-collections", locale, first, query, sortKey, reverse, metafieldIdentifiers],
|
|
2771
|
+
() => shopifySdk.getAllCollections(client, {
|
|
2772
|
+
locale,
|
|
2773
|
+
first,
|
|
2774
|
+
query,
|
|
2775
|
+
sortKey,
|
|
2776
|
+
reverse,
|
|
2777
|
+
metafieldIdentifiers
|
|
2778
|
+
}),
|
|
2779
|
+
swrOptions
|
|
2780
|
+
);
|
|
2781
|
+
}
|
|
2782
|
+
function useCollections(options = {}) {
|
|
2783
|
+
const { client, locale } = useShopify();
|
|
2784
|
+
const { first, after, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
|
|
2785
|
+
return useSWR__default.default(
|
|
2786
|
+
["collections", locale, first, after, query, sortKey, reverse, metafieldIdentifiers],
|
|
2787
|
+
() => shopifySdk.getCollections(client, {
|
|
2788
|
+
locale,
|
|
2789
|
+
first,
|
|
2790
|
+
after,
|
|
2791
|
+
query,
|
|
2792
|
+
sortKey,
|
|
2793
|
+
reverse,
|
|
2794
|
+
metafieldIdentifiers
|
|
2795
|
+
}),
|
|
2796
|
+
swrOptions
|
|
2797
|
+
);
|
|
2798
|
+
}
|
|
2799
|
+
function useBlog(options = {}) {
|
|
2800
|
+
const { client, locale } = useShopify();
|
|
2801
|
+
const { handle, metafieldIdentifiers, ...swrOptions } = options;
|
|
2802
|
+
return useSWR__default.default(
|
|
2803
|
+
handle ? ["blog", locale, handle, metafieldIdentifiers] : null,
|
|
2804
|
+
() => shopifySdk.getBlog(client, { handle, locale, metafieldIdentifiers }),
|
|
2805
|
+
swrOptions
|
|
2806
|
+
);
|
|
2807
|
+
}
|
|
2808
|
+
function useAllBlogs(options = {}) {
|
|
2809
|
+
const { client, locale } = useShopify();
|
|
2810
|
+
const { first, query, metafieldIdentifiers, ...swrOptions } = options;
|
|
2811
|
+
return useSWR__default.default(
|
|
2812
|
+
["all-blogs", locale, first, query, metafieldIdentifiers],
|
|
2813
|
+
() => shopifySdk.getAllBlogs(client, {
|
|
2814
|
+
locale,
|
|
2815
|
+
first,
|
|
2816
|
+
query,
|
|
2817
|
+
metafieldIdentifiers
|
|
2818
|
+
}),
|
|
2819
|
+
swrOptions
|
|
2820
|
+
);
|
|
2821
|
+
}
|
|
2822
|
+
function useArticle(options = {}) {
|
|
2823
|
+
const { client, locale } = useShopify();
|
|
2824
|
+
const { blogHandle, articleHandle, metafieldIdentifiers, ...swrOptions } = options;
|
|
2825
|
+
return useSWR__default.default(
|
|
2826
|
+
blogHandle && articleHandle ? ["article", locale, blogHandle, articleHandle, metafieldIdentifiers] : null,
|
|
2827
|
+
() => shopifySdk.getArticle(client, {
|
|
2828
|
+
blogHandle,
|
|
2829
|
+
articleHandle,
|
|
2830
|
+
locale,
|
|
2831
|
+
metafieldIdentifiers
|
|
2832
|
+
}),
|
|
2833
|
+
swrOptions
|
|
2834
|
+
);
|
|
2835
|
+
}
|
|
2836
|
+
function useArticles(options = {}) {
|
|
2837
|
+
const { client, locale } = useShopify();
|
|
2838
|
+
const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
|
|
2839
|
+
return useSWR__default.default(
|
|
2840
|
+
["articles", locale, first, query, sortKey, reverse, metafieldIdentifiers],
|
|
2841
|
+
() => shopifySdk.getArticles(client, {
|
|
2842
|
+
locale,
|
|
2843
|
+
first,
|
|
2844
|
+
query,
|
|
2845
|
+
sortKey,
|
|
2846
|
+
reverse,
|
|
2847
|
+
metafieldIdentifiers
|
|
2848
|
+
}),
|
|
2849
|
+
swrOptions
|
|
2850
|
+
);
|
|
2851
|
+
}
|
|
2852
|
+
function useArticlesInBlog(options = {}) {
|
|
2853
|
+
const { client, locale } = useShopify();
|
|
2854
|
+
const { blogHandle, first, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
|
|
2855
|
+
return useSWR__default.default(
|
|
2856
|
+
blogHandle ? ["articles-in-blog", locale, blogHandle, first, sortKey, reverse, metafieldIdentifiers] : null,
|
|
2857
|
+
() => shopifySdk.getArticlesInBlog(client, {
|
|
2858
|
+
blogHandle,
|
|
2859
|
+
locale,
|
|
2860
|
+
first,
|
|
2861
|
+
sortKey,
|
|
2862
|
+
reverse,
|
|
2863
|
+
metafieldIdentifiers
|
|
2864
|
+
}),
|
|
2865
|
+
swrOptions
|
|
2866
|
+
);
|
|
2867
|
+
}
|
|
2868
|
+
async function performSearch(client, locale, searchQuery, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"]) {
|
|
2869
|
+
if (!searchQuery) {
|
|
2870
|
+
return void 0;
|
|
2871
|
+
}
|
|
2872
|
+
const query = (
|
|
2873
|
+
/* GraphQL */
|
|
2874
|
+
`
|
|
2875
|
+
query search($query: String!, $first: Int!, $types: [SearchType!])
|
|
2876
|
+
@inContext(language: $language) {
|
|
2877
|
+
search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
|
|
2878
|
+
totalCount
|
|
2879
|
+
edges {
|
|
2880
|
+
node {
|
|
2881
|
+
... on Article {
|
|
2882
|
+
__typename
|
|
2883
|
+
id
|
|
2884
|
+
handle
|
|
2885
|
+
title
|
|
2886
|
+
excerpt
|
|
2887
|
+
image {
|
|
2888
|
+
url
|
|
2889
|
+
altText
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2892
|
+
... on Page {
|
|
2893
|
+
__typename
|
|
2894
|
+
id
|
|
2895
|
+
handle
|
|
2896
|
+
title
|
|
2897
|
+
}
|
|
2898
|
+
... on Product {
|
|
2899
|
+
__typename
|
|
2900
|
+
id
|
|
2901
|
+
handle
|
|
2902
|
+
title
|
|
2903
|
+
description
|
|
2904
|
+
featuredImage {
|
|
2905
|
+
url
|
|
2906
|
+
altText
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
pageInfo {
|
|
2912
|
+
hasNextPage
|
|
2913
|
+
endCursor
|
|
2914
|
+
}
|
|
2803
2915
|
}
|
|
2804
|
-
};
|
|
2805
|
-
if (profile?.isMonthlyPlus) {
|
|
2806
|
-
removePlusProduct(plus_monthly_product);
|
|
2807
|
-
}
|
|
2808
|
-
if (profile?.isAnnualPlus) {
|
|
2809
|
-
removePlusProduct(plus_annual_product);
|
|
2810
2916
|
}
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
const { selectedPlusMemberMode, selectedPlusMemberProduct, plusMemberMetafields } = usePlusMemberContext();
|
|
2818
|
-
const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
|
|
2819
|
-
memberSetting: plusMemberMetafields,
|
|
2820
|
-
cart
|
|
2917
|
+
`
|
|
2918
|
+
);
|
|
2919
|
+
const data = await client.query(query, {
|
|
2920
|
+
query: searchQuery,
|
|
2921
|
+
first,
|
|
2922
|
+
types
|
|
2821
2923
|
});
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2924
|
+
if (!data || !data.search) {
|
|
2925
|
+
return void 0;
|
|
2926
|
+
}
|
|
2927
|
+
const items = data.search.edges?.map((edge) => {
|
|
2928
|
+
const node = edge.node;
|
|
2929
|
+
const item = {
|
|
2930
|
+
type: node.__typename.toUpperCase(),
|
|
2931
|
+
id: node.id,
|
|
2932
|
+
handle: node.handle,
|
|
2933
|
+
title: node.title
|
|
2934
|
+
};
|
|
2935
|
+
if (node.__typename === "Product") {
|
|
2936
|
+
item.description = node.description;
|
|
2937
|
+
item.image = node.featuredImage ? {
|
|
2938
|
+
url: node.featuredImage.url,
|
|
2939
|
+
altText: node.featuredImage.altText
|
|
2940
|
+
} : void 0;
|
|
2941
|
+
} else if (node.__typename === "Article") {
|
|
2942
|
+
item.description = node.excerpt;
|
|
2943
|
+
item.image = node.image ? {
|
|
2944
|
+
url: node.image.url,
|
|
2945
|
+
altText: node.image.altText
|
|
2946
|
+
} : void 0;
|
|
2837
2947
|
}
|
|
2838
|
-
return
|
|
2839
|
-
}
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
]);
|
|
2846
|
-
return plusMemberProduct;
|
|
2948
|
+
return item;
|
|
2949
|
+
}) || [];
|
|
2950
|
+
return {
|
|
2951
|
+
items,
|
|
2952
|
+
totalCount: data.search.totalCount || 0,
|
|
2953
|
+
pageInfo: data.search.pageInfo
|
|
2954
|
+
};
|
|
2847
2955
|
}
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
children
|
|
2856
|
-
}) => {
|
|
2857
|
-
const [zipCode, setZipCode] = react.useState("");
|
|
2858
|
-
const [showTip, setShowTip] = react.useState(false);
|
|
2859
|
-
const [selectedPlusMemberMode, setSelectedPlusMemberMode] = react.useState(
|
|
2860
|
-
initialSelectedPlusMemberMode
|
|
2956
|
+
function useSearch(options = {}) {
|
|
2957
|
+
const { client, locale } = useShopify();
|
|
2958
|
+
const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
|
|
2959
|
+
return useSWR__default.default(
|
|
2960
|
+
query ? ["search", locale, query, first, types] : null,
|
|
2961
|
+
() => performSearch(client, locale, query, first, types),
|
|
2962
|
+
swrOptions
|
|
2861
2963
|
);
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
const
|
|
2865
|
-
const
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2964
|
+
}
|
|
2965
|
+
async function getSiteInfo(client, locale, metafieldIdentifiers) {
|
|
2966
|
+
const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
|
|
2967
|
+
const query = (
|
|
2968
|
+
/* GraphQL */
|
|
2969
|
+
`
|
|
2970
|
+
query getSiteInfo(
|
|
2971
|
+
${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
|
|
2972
|
+
) @inContext(language: $language) {
|
|
2973
|
+
shop {
|
|
2974
|
+
name
|
|
2975
|
+
description
|
|
2976
|
+
primaryDomain {
|
|
2977
|
+
url
|
|
2978
|
+
host
|
|
2979
|
+
}
|
|
2980
|
+
brand {
|
|
2981
|
+
logo {
|
|
2982
|
+
image {
|
|
2983
|
+
url
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
colors {
|
|
2987
|
+
primary {
|
|
2988
|
+
background
|
|
2989
|
+
}
|
|
2990
|
+
secondary {
|
|
2991
|
+
background
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
|
|
2996
|
+
}
|
|
2885
2997
|
}
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
}
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
setAllowNextDayDelivery,
|
|
2901
|
-
allowThirdDayDelivery,
|
|
2902
|
-
setAllowThirdDayDelivery,
|
|
2903
|
-
plusMemberMetafields: memberSetting,
|
|
2904
|
-
selectedPlusMemberMode,
|
|
2905
|
-
setSelectedPlusMemberMode,
|
|
2906
|
-
showAreaCheckModal,
|
|
2907
|
-
setShowAreaCheckModal,
|
|
2908
|
-
selectedShippingMethod,
|
|
2909
|
-
setSelectedShippingMethod,
|
|
2910
|
-
shippingMethodsContext,
|
|
2911
|
-
showTip,
|
|
2912
|
-
setShowTip,
|
|
2913
|
-
showMoreShippingMethod,
|
|
2914
|
-
setShowMoreShippingMethod,
|
|
2915
|
-
selectedPlusMemberProduct,
|
|
2916
|
-
plusMemberProducts,
|
|
2917
|
-
product,
|
|
2918
|
-
showPlusMemberBenefit,
|
|
2919
|
-
setShowPlusMemberBenefit,
|
|
2920
|
-
deleteMarginBottom,
|
|
2921
|
-
setDeleteMarginBottom,
|
|
2922
|
-
profile,
|
|
2923
|
-
locale
|
|
2924
|
-
},
|
|
2925
|
-
children
|
|
2998
|
+
`
|
|
2999
|
+
);
|
|
3000
|
+
const variables = {};
|
|
3001
|
+
if (hasMetafields) {
|
|
3002
|
+
variables.shopMetafieldIdentifiers = metafieldIdentifiers;
|
|
3003
|
+
}
|
|
3004
|
+
const data = await client.query(query, variables);
|
|
3005
|
+
if (!data || !data.shop) {
|
|
3006
|
+
return void 0;
|
|
3007
|
+
}
|
|
3008
|
+
const shop = data.shop;
|
|
3009
|
+
const metafields = shop.metafields?.reduce((acc, mf) => {
|
|
3010
|
+
if (mf && mf.key) {
|
|
3011
|
+
acc[mf.key] = mf.value;
|
|
2926
3012
|
}
|
|
3013
|
+
return acc;
|
|
3014
|
+
}, {});
|
|
3015
|
+
return {
|
|
3016
|
+
name: shop.name,
|
|
3017
|
+
description: shop.description,
|
|
3018
|
+
primaryDomain: shop.primaryDomain,
|
|
3019
|
+
brand: shop.brand ? {
|
|
3020
|
+
logo: shop.brand.logo,
|
|
3021
|
+
colors: shop.brand.colors ? {
|
|
3022
|
+
primary: shop.brand.colors.primary?.background,
|
|
3023
|
+
secondary: shop.brand.colors.secondary?.background
|
|
3024
|
+
} : void 0
|
|
3025
|
+
} : void 0,
|
|
3026
|
+
metafields
|
|
3027
|
+
};
|
|
3028
|
+
}
|
|
3029
|
+
function useSite(options = {}) {
|
|
3030
|
+
const { client, locale } = useShopify();
|
|
3031
|
+
const { metafieldIdentifiers, ...swrOptions } = options;
|
|
3032
|
+
return useSWR__default.default(
|
|
3033
|
+
["site", locale, metafieldIdentifiers],
|
|
3034
|
+
() => getSiteInfo(client, locale, metafieldIdentifiers),
|
|
3035
|
+
swrOptions
|
|
2927
3036
|
);
|
|
2928
|
-
}
|
|
3037
|
+
}
|
|
2929
3038
|
function useIntersection(targetRef, options) {
|
|
2930
3039
|
const {
|
|
2931
3040
|
callback,
|
|
@@ -3119,7 +3228,7 @@ function CartProvider({
|
|
|
3119
3228
|
}) {
|
|
3120
3229
|
const { client, cartCookieAdapter } = useShopify();
|
|
3121
3230
|
const [customAttributes, setCustomAttributes] = react.useState([]);
|
|
3122
|
-
const [
|
|
3231
|
+
const [customAttributesNeedRemove, setCustomAttributesNeedRemove] = react.useState(
|
|
3123
3232
|
[]
|
|
3124
3233
|
);
|
|
3125
3234
|
const [isCodeChanging, setIsCodeChanging] = react.useState(false);
|
|
@@ -3147,15 +3256,34 @@ function CartProvider({
|
|
|
3147
3256
|
refreshDeps: [locale]
|
|
3148
3257
|
}
|
|
3149
3258
|
);
|
|
3150
|
-
const { trigger: updateAttributes } = useUpdateCartAttributes(
|
|
3151
|
-
|
|
3259
|
+
const { trigger: updateAttributes } = useUpdateCartAttributes({
|
|
3260
|
+
mutate: mutateCart,
|
|
3261
|
+
metafieldIdentifiers,
|
|
3262
|
+
disabled: isCartLoading
|
|
3263
|
+
});
|
|
3264
|
+
const { hasPlusMember } = useHasPlusMemberInCart({
|
|
3265
|
+
memberSetting,
|
|
3266
|
+
cart
|
|
3267
|
+
});
|
|
3268
|
+
const { attributes: commonAttributes } = useCartAttributes({
|
|
3269
|
+
profile,
|
|
3270
|
+
customer,
|
|
3271
|
+
cart,
|
|
3272
|
+
memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
|
|
3273
|
+
});
|
|
3152
3274
|
ahooks.useRequest(
|
|
3153
3275
|
() => {
|
|
3154
|
-
const
|
|
3155
|
-
|
|
3276
|
+
const filteredSameCommonAttributes = commonAttributes.filter(
|
|
3277
|
+
(attr) => !customAttributes.some((a) => a.key === attr.key)
|
|
3278
|
+
);
|
|
3279
|
+
const newAttributes = [
|
|
3280
|
+
...filteredSameCommonAttributes,
|
|
3281
|
+
...customAttributes
|
|
3282
|
+
];
|
|
3283
|
+
const needUpdate = cart && checkAttributesUpdateNeeded(
|
|
3156
3284
|
cart.customAttributes,
|
|
3157
3285
|
newAttributes,
|
|
3158
|
-
|
|
3286
|
+
customAttributesNeedRemove
|
|
3159
3287
|
);
|
|
3160
3288
|
if (needUpdate) {
|
|
3161
3289
|
return updateAttributes({ attributes: newAttributes });
|
|
@@ -3168,44 +3296,39 @@ function CartProvider({
|
|
|
3168
3296
|
// 1 秒内只触发最后一次更新
|
|
3169
3297
|
throttleTrailing: true,
|
|
3170
3298
|
throttleLeading: false,
|
|
3171
|
-
refreshDeps: [
|
|
3299
|
+
refreshDeps: [commonAttributes, customAttributes, customAttributesNeedRemove]
|
|
3172
3300
|
}
|
|
3173
3301
|
);
|
|
3174
3302
|
useUpdateLineCodeAmountAttributes({
|
|
3175
3303
|
cart,
|
|
3176
3304
|
mutateCart,
|
|
3177
3305
|
isCartLoading: isCartLoading || isCodeChanging,
|
|
3178
|
-
setLoadingState
|
|
3306
|
+
setLoadingState,
|
|
3307
|
+
metafieldIdentifiers
|
|
3179
3308
|
});
|
|
3180
3309
|
const removeCustomAttributes = react.useCallback(
|
|
3181
|
-
(
|
|
3182
|
-
|
|
3310
|
+
(attributes) => {
|
|
3311
|
+
setCustomAttributesNeedRemove(attributes);
|
|
3183
3312
|
},
|
|
3184
|
-
[
|
|
3313
|
+
[setCustomAttributesNeedRemove]
|
|
3185
3314
|
);
|
|
3186
3315
|
const addCustomAttributes = react.useCallback(
|
|
3187
|
-
(
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
(attr) => !sameAttributes.some((a) => a.key === attr.key)
|
|
3195
|
-
);
|
|
3196
|
-
return [...removedAttributes, ...attributes2];
|
|
3197
|
-
});
|
|
3198
|
-
} else {
|
|
3199
|
-
setCustomAttributes((prev) => [...prev, ...attributes2]);
|
|
3200
|
-
}
|
|
3316
|
+
(attributes) => {
|
|
3317
|
+
setCustomAttributes((oldCustomAttributes) => {
|
|
3318
|
+
const filteredSameAttributes = oldCustomAttributes.filter(
|
|
3319
|
+
(attr) => !attributes.some((a) => a.key === attr.key)
|
|
3320
|
+
);
|
|
3321
|
+
return [...filteredSameAttributes, ...attributes];
|
|
3322
|
+
});
|
|
3201
3323
|
},
|
|
3202
|
-
[
|
|
3324
|
+
[setCustomAttributes]
|
|
3203
3325
|
);
|
|
3204
3326
|
const functionAutoFreeGiftResult = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer);
|
|
3205
3327
|
const scriptAutoFreeGiftResult = useScriptAutoFreeGift({
|
|
3206
3328
|
campaign: gradientGiftsConfig || null,
|
|
3207
3329
|
_giveaway: CUSTOMER_SCRIPT_GIFT_KEY,
|
|
3208
|
-
cart
|
|
3330
|
+
cart,
|
|
3331
|
+
profile
|
|
3209
3332
|
});
|
|
3210
3333
|
const formattedScriptGifts = react.useMemo(() => {
|
|
3211
3334
|
return formatScriptAutoFreeGift({
|
|
@@ -3256,16 +3379,23 @@ function CartProvider({
|
|
|
3256
3379
|
);
|
|
3257
3380
|
return result;
|
|
3258
3381
|
}, [cart?.lineItems, scriptAutoFreeGift, functionAutoFreeGift]);
|
|
3382
|
+
const totalQuantity = react.useMemo(() => {
|
|
3383
|
+
const cartLinesCount = cart?.lineItems.reduce((acc, item) => acc + item.quantity, 0) || 0;
|
|
3384
|
+
const giftLinesCount = giftNeedAddToCartLines?.reduce((acc, item) => acc + (item.quantity || 1), 0) || 0;
|
|
3385
|
+
return cartLinesCount + giftLinesCount;
|
|
3386
|
+
}, [cart?.lineItems, giftNeedAddToCartLines]);
|
|
3259
3387
|
const value = react.useMemo(
|
|
3260
3388
|
() => ({
|
|
3389
|
+
totalQuantity,
|
|
3261
3390
|
cart,
|
|
3262
3391
|
isCartLoading,
|
|
3263
3392
|
triggerFetch: fetchCart,
|
|
3264
3393
|
mutateCart,
|
|
3265
3394
|
addCustomAttributes,
|
|
3266
3395
|
removeCustomAttributes,
|
|
3267
|
-
setCustomAttributes,
|
|
3268
3396
|
locale,
|
|
3397
|
+
profile,
|
|
3398
|
+
customer,
|
|
3269
3399
|
isCodeChanging,
|
|
3270
3400
|
setIsCodeChanging,
|
|
3271
3401
|
autoFreeGiftConfig,
|
|
@@ -3281,10 +3411,12 @@ function CartProvider({
|
|
|
3281
3411
|
scriptAutoFreeGiftResult,
|
|
3282
3412
|
setScriptAutoFreeGift,
|
|
3283
3413
|
giftNeedAddToCartLines,
|
|
3284
|
-
metafieldIdentifiers
|
|
3414
|
+
metafieldIdentifiers,
|
|
3415
|
+
memberSetting
|
|
3285
3416
|
}),
|
|
3286
3417
|
[
|
|
3287
3418
|
cart,
|
|
3419
|
+
totalQuantity,
|
|
3288
3420
|
isCartLoading,
|
|
3289
3421
|
fetchCart,
|
|
3290
3422
|
mutateCart,
|
|
@@ -3304,43 +3436,23 @@ function CartProvider({
|
|
|
3304
3436
|
scriptAutoFreeGiftResult,
|
|
3305
3437
|
setScriptAutoFreeGift,
|
|
3306
3438
|
giftNeedAddToCartLines,
|
|
3307
|
-
metafieldIdentifiers
|
|
3439
|
+
metafieldIdentifiers,
|
|
3440
|
+
customer,
|
|
3441
|
+
profile,
|
|
3442
|
+
memberSetting
|
|
3308
3443
|
]
|
|
3309
3444
|
);
|
|
3310
3445
|
return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
|
|
3311
3446
|
}
|
|
3312
|
-
function useCartContext() {
|
|
3447
|
+
function useCartContext(options) {
|
|
3313
3448
|
const context = react.useContext(CartContext);
|
|
3314
|
-
if (!context) {
|
|
3449
|
+
if (!context && !options?.optional) {
|
|
3315
3450
|
throw new Error("useCartContext must be used within a CartProvider");
|
|
3316
3451
|
}
|
|
3317
3452
|
return context;
|
|
3318
3453
|
}
|
|
3319
3454
|
|
|
3320
|
-
|
|
3321
|
-
enumerable: true,
|
|
3322
|
-
get: function () { return shopifySdk.ShopifyConfig; }
|
|
3323
|
-
});
|
|
3324
|
-
Object.defineProperty(exports, "clearLocalStorage", {
|
|
3325
|
-
enumerable: true,
|
|
3326
|
-
get: function () { return shopifySdk.clearLocalStorage; }
|
|
3327
|
-
});
|
|
3328
|
-
Object.defineProperty(exports, "createShopifyClient", {
|
|
3329
|
-
enumerable: true,
|
|
3330
|
-
get: function () { return shopifySdk.createShopifyClient; }
|
|
3331
|
-
});
|
|
3332
|
-
Object.defineProperty(exports, "getLocalStorage", {
|
|
3333
|
-
enumerable: true,
|
|
3334
|
-
get: function () { return shopifySdk.getLocalStorage; }
|
|
3335
|
-
});
|
|
3336
|
-
Object.defineProperty(exports, "removeLocalStorage", {
|
|
3337
|
-
enumerable: true,
|
|
3338
|
-
get: function () { return shopifySdk.removeLocalStorage; }
|
|
3339
|
-
});
|
|
3340
|
-
Object.defineProperty(exports, "setLocalStorage", {
|
|
3341
|
-
enumerable: true,
|
|
3342
|
-
get: function () { return shopifySdk.setLocalStorage; }
|
|
3343
|
-
});
|
|
3455
|
+
exports.BrowserPerformanceAdapter = BrowserPerformanceAdapter;
|
|
3344
3456
|
exports.BuyRuleType = BuyRuleType;
|
|
3345
3457
|
exports.CODE_AMOUNT_KEY = CODE_AMOUNT_KEY;
|
|
3346
3458
|
exports.CUSTOMER_ATTRIBUTE_KEY = CUSTOMER_ATTRIBUTE_KEY;
|
|
@@ -3348,6 +3460,7 @@ exports.CUSTOMER_SCRIPT_GIFT_KEY = CUSTOMER_SCRIPT_GIFT_KEY;
|
|
|
3348
3460
|
exports.CartProvider = CartProvider;
|
|
3349
3461
|
exports.DeliveryPlusType = DeliveryPlusType;
|
|
3350
3462
|
exports.MAIN_PRODUCT_CODE = MAIN_PRODUCT_CODE;
|
|
3463
|
+
exports.MEMBER_PRICE_ATTRIBUTE_KEY = MEMBER_PRICE_ATTRIBUTE_KEY;
|
|
3351
3464
|
exports.OrderBasePriceType = OrderBasePriceType;
|
|
3352
3465
|
exports.OrderDiscountType = OrderDiscountType;
|
|
3353
3466
|
exports.PLUS_MEMBER_TYPE = PLUS_MEMBER_TYPE;
|
|
@@ -3362,11 +3475,8 @@ exports.ShippingMethodMode = ShippingMethodMode;
|
|
|
3362
3475
|
exports.ShopifyContext = ShopifyContext;
|
|
3363
3476
|
exports.ShopifyProvider = ShopifyProvider;
|
|
3364
3477
|
exports.SpendMoneyType = SpendMoneyType;
|
|
3365
|
-
exports.atobID = atobID;
|
|
3366
3478
|
exports.browserCartCookieAdapter = browserCartCookieAdapter;
|
|
3367
3479
|
exports.browserCookieAdapter = browserCookieAdapter;
|
|
3368
|
-
exports.btoaID = btoaID;
|
|
3369
|
-
exports.checkAttributesUpdateNeeded = checkAttributesUpdateNeeded;
|
|
3370
3480
|
exports.clearGeoLocationCache = clearGeoLocationCache;
|
|
3371
3481
|
exports.createMockCartFromLines = createMockCartFromLines;
|
|
3372
3482
|
exports.currencyCodeMapping = currencyCodeMapping;
|
|
@@ -3375,10 +3485,14 @@ exports.formatFunctionAutoFreeGift = formatFunctionAutoFreeGift;
|
|
|
3375
3485
|
exports.formatScriptAutoFreeGift = formatScriptAutoFreeGift;
|
|
3376
3486
|
exports.gaTrack = gaTrack;
|
|
3377
3487
|
exports.getCachedGeoLocation = getCachedGeoLocation;
|
|
3488
|
+
exports.getCartAttributes = getCartAttributes;
|
|
3378
3489
|
exports.getDiscountEnvAttributeValue = getDiscountEnvAttributeValue;
|
|
3379
3490
|
exports.getMatchedMainProductSubTotal = getMatchedMainProductSubTotal;
|
|
3380
3491
|
exports.getQuery = getQuery;
|
|
3381
3492
|
exports.getReferralAttributes = getReferralAttributes;
|
|
3493
|
+
exports.getUserType = getUserType;
|
|
3494
|
+
exports.hasPlusMemberInCart = hasPlusMemberInCart;
|
|
3495
|
+
exports.hasPlusMemberInLines = hasPlusMemberInLines;
|
|
3382
3496
|
exports.normalizeAddToCartLines = normalizeAddToCartLines;
|
|
3383
3497
|
exports.preCheck = preCheck;
|
|
3384
3498
|
exports.safeParse = safeParse;
|
|
@@ -3388,7 +3502,6 @@ exports.trackBeginCheckoutGA = trackBeginCheckoutGA;
|
|
|
3388
3502
|
exports.trackBuyNowFBQ = trackBuyNowFBQ;
|
|
3389
3503
|
exports.trackBuyNowGA = trackBuyNowGA;
|
|
3390
3504
|
exports.useAddCartLines = useAddCartLines;
|
|
3391
|
-
exports.useAddPlusMemberProductsToCart = useAddPlusMemberProductsToCart;
|
|
3392
3505
|
exports.useAddToCart = useAddToCart;
|
|
3393
3506
|
exports.useAllBlogs = useAllBlogs;
|
|
3394
3507
|
exports.useAllCollections = useAllCollections;
|
|
@@ -3398,6 +3511,7 @@ exports.useArticle = useArticle;
|
|
|
3398
3511
|
exports.useArticles = useArticles;
|
|
3399
3512
|
exports.useArticlesInBlog = useArticlesInBlog;
|
|
3400
3513
|
exports.useAutoRemovePlusMemberInCart = useAutoRemovePlusMemberInCart;
|
|
3514
|
+
exports.useAvailableDeliveryCoupon = useAvailableDeliveryCoupon;
|
|
3401
3515
|
exports.useBlog = useBlog;
|
|
3402
3516
|
exports.useBuyNow = useBuyNow;
|
|
3403
3517
|
exports.useCalcAutoFreeGift = useCalcAutoFreeGift;
|
|
@@ -3412,13 +3526,12 @@ exports.useCreateCart = useCreateCart;
|
|
|
3412
3526
|
exports.useExposure = useExposure;
|
|
3413
3527
|
exports.useGeoLocation = useGeoLocation;
|
|
3414
3528
|
exports.useHasPlusMemberInCart = useHasPlusMemberInCart;
|
|
3529
|
+
exports.useHasPlusMemberInLines = useHasPlusMemberInLines;
|
|
3415
3530
|
exports.useIntersection = useIntersection;
|
|
3416
|
-
exports.usePlusAnnualProductVariant = usePlusAnnualProductVariant;
|
|
3417
3531
|
exports.usePlusMemberCheckoutCustomAttributes = usePlusMemberCheckoutCustomAttributes;
|
|
3418
3532
|
exports.usePlusMemberContext = usePlusMemberContext;
|
|
3419
|
-
exports.
|
|
3420
|
-
exports.
|
|
3421
|
-
exports.usePlusMonthlyProductVariant = usePlusMonthlyProductVariant;
|
|
3533
|
+
exports.usePlusMemberNeedAddToCart = usePlusMemberNeedAddToCart;
|
|
3534
|
+
exports.usePlusMemberVariants = usePlusMemberVariants;
|
|
3422
3535
|
exports.usePrice = usePrice;
|
|
3423
3536
|
exports.useProduct = useProduct;
|
|
3424
3537
|
exports.useProductUrl = useProductUrl;
|
|
@@ -3429,16 +3542,20 @@ exports.useReplaceCartPlusMember = useReplaceCartPlusMember;
|
|
|
3429
3542
|
exports.useScriptAutoFreeGift = useScriptAutoFreeGift;
|
|
3430
3543
|
exports.useSearch = useSearch;
|
|
3431
3544
|
exports.useSelectedOptions = useSelectedOptions;
|
|
3432
|
-
exports.useShippingMethodAvailableCheck = useShippingMethodAvailableCheck;
|
|
3433
3545
|
exports.useShippingMethods = useShippingMethods;
|
|
3434
3546
|
exports.useShopify = useShopify;
|
|
3435
3547
|
exports.useSite = useSite;
|
|
3436
3548
|
exports.useUpdateCartAttributes = useUpdateCartAttributes;
|
|
3437
3549
|
exports.useUpdateCartLines = useUpdateCartLines;
|
|
3438
3550
|
exports.useUpdateLineCodeAmountAttributes = useUpdateLineCodeAmountAttributes;
|
|
3439
|
-
exports.useUpdatePlusMemberDeliveryOptions = useUpdatePlusMemberDeliveryOptions;
|
|
3440
3551
|
exports.useUpdateVariantQuery = useUpdateVariantQuery;
|
|
3441
3552
|
exports.useVariant = useVariant;
|
|
3442
3553
|
exports.useVariantMedia = useVariantMedia;
|
|
3554
|
+
Object.keys(shopifySdk).forEach(function (k) {
|
|
3555
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
3556
|
+
enumerable: true,
|
|
3557
|
+
get: function () { return shopifySdk[k]; }
|
|
3558
|
+
});
|
|
3559
|
+
});
|
|
3443
3560
|
//# sourceMappingURL=index.js.map
|
|
3444
3561
|
//# sourceMappingURL=index.js.map
|