@anker-in/shopify-react 0.1.1-beta.42 → 0.1.1-beta.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { createContext, useMemo, useRef, useState, useEffect, useCallback, useContext } from 'react';
2
2
  import useSWRMutation from 'swr/mutation';
3
- import { getProductsByHandles, createCart, updateCartCodes, addCartLines, updateCartLines, removeCartLines, updateCartAttributes, getLocalStorage, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, setLocalStorage, updateCartDeliveryOptions } from '@anker-in/shopify-sdk';
3
+ import { getProductsByHandles, createCart, updateCartCodes, addCartLines, getLocalStorage, updateCartLines, removeCartLines, updateCartAttributes, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, setLocalStorage } from '@anker-in/shopify-sdk';
4
4
  import Cookies5 from 'js-cookie';
5
5
  import { jsx } from 'react/jsx-runtime';
6
6
  import Decimal2 from 'decimal.js';
@@ -516,7 +516,8 @@ var useScriptAutoFreeGift = ({
516
516
  _giveaway,
517
517
  cart,
518
518
  locale: providedLocale,
519
- lines
519
+ lines,
520
+ profile
520
521
  }) => {
521
522
  const { client, locale: contextLocale } = useShopify();
522
523
  const locale = providedLocale || contextLocale;
@@ -540,8 +541,9 @@ var useScriptAutoFreeGift = ({
540
541
  const utmCampaign = Cookies5.get("utm_campaign") || query?.utm_campaign;
541
542
  if (campaign.activityAvailableQuery && !utmCampaign?.includes(campaign.activityAvailableQuery))
542
543
  return false;
544
+ if (campaign.requireLogin && !profile?.email) return false;
543
545
  return true;
544
- }, [campaign]);
546
+ }, [campaign, profile]);
545
547
  const [upgrade_multiple, upgrade_value] = useMemo(() => {
546
548
  let upgrade_multiple2 = 1;
547
549
  let upgrade_value2 = 0;
@@ -680,7 +682,10 @@ function useCartContext(options) {
680
682
  }
681
683
 
682
684
  // src/hooks/cart/use-create-cart.ts
683
- function useCreateCart(options) {
685
+ function useCreateCart({
686
+ updateCookie = false,
687
+ options
688
+ }) {
684
689
  const { client, locale, cartCookieAdapter } = useShopify();
685
690
  const { mutateCart, metafieldIdentifiers } = useCartContext();
686
691
  const createNewCart = useCallback(
@@ -688,7 +693,8 @@ function useCreateCart(options) {
688
693
  let newCart = await createCart(client, {
689
694
  ...arg,
690
695
  metafieldIdentifiers,
691
- cookieAdapter: cartCookieAdapter
696
+ cookieAdapter: cartCookieAdapter,
697
+ updateCookie
692
698
  });
693
699
  if (newCart) {
694
700
  const unApplicableCodes = newCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
@@ -1026,377 +1032,123 @@ var getLinesWithAttributes = ({
1026
1032
  return functionLine;
1027
1033
  });
1028
1034
  };
1029
-
1030
- // src/hooks/cart/use-add-to-cart.ts
1031
- function useAddToCart({ withTrack = true } = {}, swrOptions) {
1032
- const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
1033
- const { cart, addCustomAttributes } = useCartContext();
1034
- const { trigger: applyCartCodes } = useApplyCartCodes();
1035
- const { trigger: removeInvalidCodes } = useRemoveCartCodes();
1036
- const { trigger: addCartLines2 } = useAddCartLines();
1037
- const { trigger: createCart4 } = useCreateCart();
1038
- const addToCart = useCallback(
1039
- async (_key, { arg }) => {
1040
- const {
1041
- lineItems,
1042
- cartId: providedCartId,
1043
- discountCodes,
1044
- gtmParams = {},
1045
- buyerIdentity,
1046
- needCreateCart = false,
1047
- onCodesInvalid,
1048
- replaceExistingCodes,
1049
- customAttributes
1050
- } = arg;
1051
- if (!lineItems || lineItems.length === 0) {
1052
- return;
1035
+ function useCalcGiftsFromLines({
1036
+ lines,
1037
+ customer,
1038
+ scriptGiveawayKey = CUSTOMER_SCRIPT_GIFT_KEY
1039
+ }) {
1040
+ const { locale } = useShopify();
1041
+ const { cart, autoFreeGiftConfig, gradientGiftsConfig } = useCartContext();
1042
+ const functionGift = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer, lines);
1043
+ const scriptGift = useScriptAutoFreeGift({
1044
+ campaign: gradientGiftsConfig || null,
1045
+ _giveaway: scriptGiveawayKey,
1046
+ cart,
1047
+ locale,
1048
+ lines
1049
+ });
1050
+ const allGiftLines = useMemo(() => {
1051
+ const functionGiftLines = (functionGift.qualifyingGift?.itemsToAdd || []).map((item) => {
1052
+ const product = functionGift.giftProductsResult?.find(
1053
+ (product2) => product2.handle === item.variant.handle
1054
+ );
1055
+ const variants = product?.variants;
1056
+ const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.variant.sku) : void 0;
1057
+ if (!variant) {
1058
+ console.warn(
1059
+ `Function gift: Variant not found for handle=${item.variant.handle}, sku=${item.variant.sku}`
1060
+ );
1061
+ return null;
1053
1062
  }
1054
- performanceAdapter?.addToCartStart();
1055
- const linesWithFunctionAttributes = getLinesWithAttributes({ cart, lineItems });
1056
- const lines = linesWithFunctionAttributes.map((item) => ({
1057
- merchandiseId: item.variant?.id || "",
1058
- quantity: item.quantity || 1,
1059
- attributes: item.attributes,
1060
- sellingPlanId: item.sellingPlanId
1061
- })).filter((item) => item.merchandiseId && item.quantity);
1062
- if (lines.length === 0) {
1063
- return;
1063
+ return {
1064
+ variant: {
1065
+ ...variant,
1066
+ product
1067
+ },
1068
+ quantity: item.quantity ?? 1,
1069
+ attributes: item.attributes
1070
+ };
1071
+ }).filter((item) => item !== null);
1072
+ const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((item) => {
1073
+ const product = scriptGift.giftProductsResult?.find(
1074
+ (product2) => product2.handle === item.handle
1075
+ );
1076
+ const variants = product?.variants;
1077
+ const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.sku) : void 0;
1078
+ if (!variant) {
1079
+ console.warn(`Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`);
1080
+ return null;
1064
1081
  }
1065
- let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
1066
- let resultCart = null;
1067
- if (!cartId) {
1068
- resultCart = await createCart4({
1069
- lines,
1070
- buyerIdentity,
1071
- discountCodes,
1072
- customAttributes
1073
- });
1074
- } else {
1075
- resultCart = await addCartLines2({
1076
- cartId,
1077
- lines
1078
- });
1079
- console.log("npm addCartLines resultCart", resultCart);
1080
- if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
1081
- const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1082
- if (unapplicableCodes.length > 0) {
1083
- if (onCodesInvalid) {
1084
- const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
1085
- if (handledCart) {
1086
- resultCart = handledCart;
1087
- }
1088
- } else {
1089
- await removeInvalidCodes({
1090
- discountCodes: unapplicableCodes
1091
- });
1092
- }
1082
+ return {
1083
+ variant: {
1084
+ ...variant,
1085
+ product
1086
+ },
1087
+ quantity: 1,
1088
+ attributes: [
1089
+ {
1090
+ key: scriptGiveawayKey,
1091
+ value: "true"
1093
1092
  }
1094
- }
1095
- if (resultCart && discountCodes && discountCodes.length > 0) {
1096
- applyCartCodes({
1097
- replaceExistingCodes,
1098
- discountCodes
1099
- });
1100
- }
1101
- if (customAttributes && customAttributes.length > 0) {
1102
- addCustomAttributes(customAttributes);
1103
- }
1104
- }
1105
- if (withTrack) {
1106
- trackAddToCartGA({
1107
- lineItems,
1108
- gtmParams: { ...gtmParams, brand: config.getBrand() }
1109
- });
1110
- trackAddToCartFBQ({ lineItems });
1111
- }
1112
- performanceAdapter?.addToCartEnd();
1113
- return resultCart;
1114
- },
1115
- [
1116
- client,
1117
- locale,
1118
- cartCookieAdapter,
1119
- userAdapter,
1120
- cart,
1121
- withTrack,
1122
- performanceAdapter,
1123
- createCart4,
1124
- addCartLines2,
1125
- applyCartCodes,
1126
- removeInvalidCodes,
1127
- addCustomAttributes,
1128
- config
1129
- ]
1130
- );
1131
- return useSWRMutation("add-to-cart", addToCart, swrOptions);
1093
+ ]
1094
+ };
1095
+ }).filter((item) => item !== null) : [];
1096
+ return [...functionGiftLines, ...scriptGiftLines];
1097
+ }, [
1098
+ functionGift.qualifyingGift,
1099
+ functionGift.giftProductsResult,
1100
+ scriptGift.freeGiftLevel,
1101
+ scriptGift.giftProductsResult,
1102
+ scriptGiveawayKey
1103
+ ]);
1104
+ const hasGifts = useMemo(() => {
1105
+ return allGiftLines.length > 0;
1106
+ }, [allGiftLines]);
1107
+ return {
1108
+ functionGift,
1109
+ scriptGift,
1110
+ allGiftLines,
1111
+ hasGifts
1112
+ };
1132
1113
  }
1133
- function useUpdateCartLines(options) {
1134
- const { client, locale, cartCookieAdapter } = useShopify();
1135
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1136
- const updateLines = useCallback(
1137
- async (_key, { arg }) => {
1138
- const updatedCart = await updateCartLines(client, {
1139
- ...arg,
1140
- metafieldIdentifiers,
1141
- cookieAdapter: cartCookieAdapter
1142
- });
1143
- if (updatedCart) {
1144
- mutateCart(updatedCart);
1145
- }
1146
- console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
1147
- return updatedCart;
1148
- },
1149
- [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1150
- );
1151
- return useSWRMutation("update-cart-lines", updateLines, options);
1152
- }
1153
- function useRemoveCartLines(options) {
1154
- const { client, locale, cartCookieAdapter } = useShopify();
1155
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1156
- const removeLines = useCallback(
1157
- async (_key, { arg }) => {
1158
- const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1159
- let updatedCart = await removeCartLines(client, {
1160
- cartId,
1161
- lineIds,
1162
- metafieldIdentifiers,
1163
- cookieAdapter: cartCookieAdapter
1164
- });
1165
- if (updatedCart && autoRemoveInvalidCodes) {
1166
- const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1167
- if (unApplicableCodes.length > 0) {
1168
- if (onCodesRemoved) {
1169
- const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1170
- if (handledCart) {
1171
- updatedCart = handledCart;
1172
- }
1173
- } else {
1174
- updatedCart = await updateCartCodes(client, {
1175
- cartId: updatedCart.id,
1176
- discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1177
- metafieldIdentifiers,
1178
- cookieAdapter: cartCookieAdapter
1179
- }) || updatedCart;
1180
- }
1181
- }
1182
- }
1183
- if (updatedCart) {
1184
- mutateCart(updatedCart);
1185
- }
1186
- return updatedCart;
1187
- },
1188
- [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1189
- );
1190
- return useSWRMutation("remove-cart-lines", removeLines, options);
1191
- }
1192
- function useUpdateCartAttributes({
1193
- mutate,
1194
- metafieldIdentifiers,
1195
- disabled = false,
1196
- swrOptions
1197
- }) {
1198
- const { client, locale, cartCookieAdapter } = useShopify();
1199
- const updateAttributes = useCallback(
1200
- async (_key, { arg }) => {
1201
- if (disabled || !cartCookieAdapter?.getCartId(locale)) {
1202
- return void 0;
1203
- }
1204
- const updatedCart = await updateCartAttributes(client, {
1205
- ...arg,
1206
- metafieldIdentifiers,
1207
- cookieAdapter: cartCookieAdapter
1208
- });
1209
- if (updatedCart) {
1210
- mutate(updatedCart);
1211
- }
1212
- return updatedCart;
1213
- },
1214
- [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers, disabled]
1215
- );
1216
- return useSWRMutation("update-cart-attributes", updateAttributes, swrOptions);
1217
- }
1218
- function useBuyNow({ withTrack = true } = {}, swrOptions) {
1219
- const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
1220
- const isLoggedIn = userAdapter?.isLoggedIn || false;
1221
- const buyNow = useCallback(
1222
- async (_key, { arg }) => {
1223
- const {
1224
- lineItems,
1225
- discountCodes,
1226
- gtmParams = {},
1227
- buyerIdentity,
1228
- fbqTrackConfig,
1229
- customAttributes,
1230
- metafieldIdentifiers,
1231
- redirectToCheckout
1232
- } = arg;
1233
- if (!lineItems || lineItems.length === 0) {
1234
- return;
1235
- }
1236
- const linesWithFunctionAttributes = getLinesWithAttributes({
1237
- lineItems
1238
- });
1239
- const lines = linesWithFunctionAttributes.map((item) => ({
1240
- merchandiseId: item.variant?.id || "",
1241
- quantity: item.quantity || 1,
1242
- attributes: item.attributes,
1243
- sellingPlanId: item.sellingPlanId
1244
- })).filter((item) => item.merchandiseId);
1245
- if (lines.length === 0) {
1246
- return;
1247
- }
1248
- const resultCart = await createCart(client, {
1249
- lines,
1250
- metafieldIdentifiers,
1251
- cookieAdapter: cartCookieAdapter,
1252
- buyerIdentity,
1253
- discountCodes,
1254
- customAttributes
1255
- });
1256
- if (!resultCart) {
1257
- throw new Error("Failed to create cart for buy now");
1258
- }
1259
- if (withTrack && resultCart.lineItems) {
1260
- trackBuyNowGA({
1261
- lineItems,
1262
- gtmParams: { ...gtmParams, brand: config.getBrand() }
1263
- });
1264
- if (fbqTrackConfig) {
1265
- trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
1266
- }
1267
- }
1268
- if (redirectToCheckout) {
1269
- if (resultCart.url) {
1270
- if (typeof window !== "undefined") {
1271
- window.location.href = resultCart.url;
1272
- }
1273
- } else {
1274
- throw new Error("Failed to get checkout URL");
1275
- }
1276
- }
1277
- return resultCart;
1278
- },
1279
- [client, locale, isLoggedIn, cartCookieAdapter, withTrack]
1280
- );
1281
- return useSWRMutation("buy-now", buyNow, swrOptions);
1282
- }
1283
- function useCalcGiftsFromLines({
1284
- lines,
1285
- customer,
1286
- scriptGiveawayKey = CUSTOMER_SCRIPT_GIFT_KEY
1287
- }) {
1288
- const { locale } = useShopify();
1289
- const { cart, autoFreeGiftConfig, gradientGiftsConfig } = useCartContext();
1290
- const functionGift = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer, lines);
1291
- const scriptGift = useScriptAutoFreeGift({
1292
- campaign: gradientGiftsConfig || null,
1293
- _giveaway: scriptGiveawayKey,
1294
- cart,
1295
- locale,
1296
- lines
1297
- });
1298
- const allGiftLines = useMemo(() => {
1299
- const functionGiftLines = (functionGift.qualifyingGift?.itemsToAdd || []).map((item) => {
1300
- const product = functionGift.giftProductsResult?.find(
1301
- (product2) => product2.handle === item.variant.handle
1302
- );
1303
- const variants = product?.variants;
1304
- const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.variant.sku) : void 0;
1305
- if (!variant) {
1306
- console.warn(
1307
- `Function gift: Variant not found for handle=${item.variant.handle}, sku=${item.variant.sku}`
1308
- );
1309
- return null;
1310
- }
1311
- return {
1312
- variant: {
1313
- ...variant,
1314
- product
1315
- },
1316
- quantity: item.quantity ?? 1,
1317
- attributes: item.attributes
1318
- };
1319
- }).filter((item) => item !== null);
1320
- const scriptGiftLines = scriptGift.freeGiftLevel ? scriptGift.freeGiftLevel.giveawayProducts.map((item) => {
1321
- const product = scriptGift.giftProductsResult?.find(
1322
- (product2) => product2.handle === item.handle
1323
- );
1324
- const variants = product?.variants;
1325
- const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.sku) : void 0;
1326
- if (!variant) {
1327
- console.warn(`Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`);
1328
- return null;
1329
- }
1330
- return {
1331
- variant: {
1332
- ...variant,
1333
- product
1334
- },
1335
- quantity: 1,
1336
- attributes: [
1337
- {
1338
- key: scriptGiveawayKey,
1339
- value: "true"
1340
- }
1341
- ]
1342
- };
1343
- }).filter((item) => item !== null) : [];
1344
- return [...functionGiftLines, ...scriptGiftLines];
1345
- }, [
1346
- functionGift.qualifyingGift,
1347
- functionGift.giftProductsResult,
1348
- scriptGift.freeGiftLevel,
1349
- scriptGift.giftProductsResult,
1350
- scriptGiveawayKey
1351
- ]);
1352
- const hasGifts = useMemo(() => {
1353
- return allGiftLines.length > 0;
1354
- }, [allGiftLines]);
1355
- return {
1356
- functionGift,
1357
- scriptGift,
1358
- allGiftLines,
1359
- hasGifts
1360
- };
1361
- }
1362
-
1363
- // src/hooks/cart/types/order-discount.ts
1364
- var OrderDiscountType = /* @__PURE__ */ ((OrderDiscountType2) => {
1365
- OrderDiscountType2[OrderDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
1366
- OrderDiscountType2[OrderDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
1367
- OrderDiscountType2[OrderDiscountType2["REDUCE_PRICE"] = 3] = "REDUCE_PRICE";
1368
- return OrderDiscountType2;
1369
- })(OrderDiscountType || {});
1370
- var OrderBasePriceType = /* @__PURE__ */ ((OrderBasePriceType2) => {
1371
- OrderBasePriceType2[OrderBasePriceType2["ORIGIN_PRICE"] = 1] = "ORIGIN_PRICE";
1372
- OrderBasePriceType2[OrderBasePriceType2["MIN_DISCOUNTED_PRICE"] = 2] = "MIN_DISCOUNTED_PRICE";
1373
- return OrderBasePriceType2;
1374
- })(OrderBasePriceType || {});
1375
-
1376
- // src/hooks/cart/feature/use-calc-order-discount.ts
1377
- var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1378
- const tags = useMemo(() => customer?.tags || [], [customer?.tags]);
1379
- const isCustomerLoading = useMemo(() => !customer ? true : false, [customer]);
1380
- const dealsType = "";
1381
- const { activeCampaign, subtotal } = useMemo(() => {
1382
- for (const campaign of orderDiscountConfig || []) {
1383
- const { rule_conditions = [], result_detail } = campaign;
1384
- const { main_product, order_discount_conf } = result_detail || {};
1385
- const isPreCheckPassed = preCheck(rule_conditions, tags, []);
1386
- if (isPreCheckPassed && main_product && order_discount_conf) {
1387
- const matchedSubtotal = getMatchedMainProductSubTotal(
1388
- cart,
1389
- main_product?.variant_list?.map((v) => v.variant_id) || [],
1390
- {
1391
- spend_money_type: order_discount_conf.base_price === 2 /* MIN_DISCOUNTED_PRICE */ ? 2 : 1,
1392
- // 根据基础价格类型设置
1393
- variant_id_list: main_product?.variant_list?.map((v) => v.variant_id) || [],
1394
- all_store_variant: main_product?.all_store_variant || false
1395
- }
1396
- );
1397
- if (matchedSubtotal > 0) {
1398
- return { activeCampaign: campaign, subtotal: matchedSubtotal };
1399
- }
1114
+
1115
+ // src/hooks/cart/types/order-discount.ts
1116
+ var OrderDiscountType = /* @__PURE__ */ ((OrderDiscountType2) => {
1117
+ OrderDiscountType2[OrderDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
1118
+ OrderDiscountType2[OrderDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
1119
+ OrderDiscountType2[OrderDiscountType2["REDUCE_PRICE"] = 3] = "REDUCE_PRICE";
1120
+ return OrderDiscountType2;
1121
+ })(OrderDiscountType || {});
1122
+ var OrderBasePriceType = /* @__PURE__ */ ((OrderBasePriceType2) => {
1123
+ OrderBasePriceType2[OrderBasePriceType2["ORIGIN_PRICE"] = 1] = "ORIGIN_PRICE";
1124
+ OrderBasePriceType2[OrderBasePriceType2["MIN_DISCOUNTED_PRICE"] = 2] = "MIN_DISCOUNTED_PRICE";
1125
+ return OrderBasePriceType2;
1126
+ })(OrderBasePriceType || {});
1127
+
1128
+ // src/hooks/cart/feature/use-calc-order-discount.ts
1129
+ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1130
+ const tags = useMemo(() => customer?.tags || [], [customer?.tags]);
1131
+ const isCustomerLoading = useMemo(() => !customer ? true : false, [customer]);
1132
+ const dealsType = "";
1133
+ const { activeCampaign, subtotal } = useMemo(() => {
1134
+ for (const campaign of orderDiscountConfig || []) {
1135
+ const { rule_conditions = [], result_detail } = campaign;
1136
+ const { main_product, order_discount_conf } = result_detail || {};
1137
+ const isPreCheckPassed = preCheck(rule_conditions, tags, []);
1138
+ if (isPreCheckPassed && main_product && order_discount_conf) {
1139
+ const matchedSubtotal = getMatchedMainProductSubTotal(
1140
+ cart,
1141
+ main_product?.variant_list?.map((v) => v.variant_id) || [],
1142
+ {
1143
+ spend_money_type: order_discount_conf.base_price === 2 /* MIN_DISCOUNTED_PRICE */ ? 2 : 1,
1144
+ // 根据基础价格类型设置
1145
+ variant_id_list: main_product?.variant_list?.map((v) => v.variant_id) || [],
1146
+ all_store_variant: main_product?.all_store_variant || false
1147
+ }
1148
+ );
1149
+ if (matchedSubtotal > 0) {
1150
+ return { activeCampaign: campaign, subtotal: matchedSubtotal };
1151
+ }
1400
1152
  }
1401
1153
  }
1402
1154
  return { activeCampaign: null, subtotal: 0 };
@@ -1451,37 +1203,6 @@ var useCalcOrderDiscount = (cart, orderDiscountConfig, customer) => {
1451
1203
  isLoading: isCustomerLoading
1452
1204
  };
1453
1205
  };
1454
- function useHasPlusMemberInCart({
1455
- memberSetting,
1456
- cart
1457
- }) {
1458
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1459
- return useMemo(() => {
1460
- if (!cart?.lineItems) {
1461
- return {
1462
- hasPlusMember: false,
1463
- hasMonthlyPlus: false,
1464
- hasAnnualPlus: false
1465
- };
1466
- }
1467
- const monthlyPlusItem = cart.lineItems.find(
1468
- (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
1469
- );
1470
- const annualPlusItem = cart.lineItems.find(
1471
- (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
1472
- );
1473
- const hasMonthlyPlus = !!monthlyPlusItem;
1474
- const hasAnnualPlus = !!annualPlusItem;
1475
- const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1476
- return {
1477
- hasPlusMember,
1478
- hasMonthlyPlus,
1479
- hasAnnualPlus,
1480
- monthlyPlusItem,
1481
- annualPlusItem
1482
- };
1483
- }, [cart?.lineItems, plus_monthly_product, plus_annual_product]);
1484
- }
1485
1206
  var getReferralAttributes = () => {
1486
1207
  const inviteCode = getLocalStorage("inviteCode") || Cookies5.get("inviteCode");
1487
1208
  const playModeId = getLocalStorage("playModeId") || Cookies5.get("playModeId");
@@ -1498,158 +1219,130 @@ var getReferralAttributes = () => {
1498
1219
  }
1499
1220
  return [];
1500
1221
  };
1501
- var useCartAttributes = ({
1222
+ var getUserType = (customer) => {
1223
+ let userInfo = Cookies5.get("userInfo");
1224
+ if (userInfo) {
1225
+ userInfo = JSON.parse(userInfo);
1226
+ let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1227
+ userInfo.setId = arr[arr.length - 1];
1228
+ }
1229
+ const customerInfo = userInfo || customer;
1230
+ if (!customerInfo) {
1231
+ return "new_user_unlogin";
1232
+ }
1233
+ if (customer) {
1234
+ const { orders = {} } = customer;
1235
+ if (orders?.edges?.length === 1) {
1236
+ return "old_user_orders_once";
1237
+ } else if (orders?.edges?.length > 1) {
1238
+ return "old_user_orders_twice";
1239
+ }
1240
+ }
1241
+ return "new_user_login";
1242
+ };
1243
+ function getCartAttributes({
1502
1244
  profile,
1503
1245
  customer,
1504
1246
  cart,
1505
- memberSetting
1506
- }) => {
1507
- const [currentUrl, setCurrentUrl] = useState("");
1508
- const { hasPlusMember } = useHasPlusMemberInCart({
1509
- memberSetting,
1510
- cart
1511
- });
1512
- useEffect(() => {
1513
- setCurrentUrl(window.location.href);
1514
- }, []);
1515
- const userType = useMemo(() => {
1516
- let userInfo = Cookies5.get("userInfo");
1517
- if (userInfo) {
1518
- userInfo = JSON.parse(userInfo);
1519
- let arr = typeof userInfo?.id == "string" && userInfo?.id.split("/");
1520
- userInfo.setId = arr[arr.length - 1];
1521
- }
1522
- const customerInfo = userInfo || customer;
1523
- if (!customerInfo) {
1524
- return "new_user_unlogin";
1525
- }
1526
- if (customer) {
1527
- const { orders = {} } = customer;
1528
- if (orders?.edges?.length === 1) {
1529
- return "old_user_orders_once";
1530
- } else if (orders?.edges?.length > 1) {
1531
- return "old_user_orders_twice";
1532
- }
1247
+ memberType,
1248
+ currentUrl = ""
1249
+ }) {
1250
+ const userType = getUserType(customer);
1251
+ const memberAttributes = [
1252
+ {
1253
+ key: "_token",
1254
+ value: profile?.token
1255
+ },
1256
+ {
1257
+ key: "_member_type",
1258
+ value: memberType ?? String(profile?.memberType || 0)
1259
+ },
1260
+ {
1261
+ key: "_user_type",
1262
+ value: userType
1263
+ },
1264
+ {
1265
+ key: "_is_login",
1266
+ value: profile?.token ? "true" : "false"
1267
+ }
1268
+ ];
1269
+ if (profile?.token) {
1270
+ memberAttributes.push({
1271
+ key: "_login_user",
1272
+ value: "1"
1273
+ });
1274
+ }
1275
+ const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1276
+ const functionAttributes = [
1277
+ {
1278
+ key: CUSTOMER_ATTRIBUTE_KEY,
1279
+ value: JSON.stringify({
1280
+ discount_code: discountCodes,
1281
+ user_tags: customer?.tags || []
1282
+ })
1283
+ }
1284
+ ];
1285
+ const presellAttributes = [
1286
+ {
1287
+ key: "_presale",
1288
+ value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1533
1289
  }
1534
- return "new_user_login";
1535
- }, [customer]);
1536
- const memberAttributes = useMemo(() => {
1537
- const attributes = [
1538
- {
1539
- key: "_token",
1540
- value: profile?.token
1541
- //是否登录
1542
- },
1543
- {
1544
- key: "_member_type",
1545
- value: hasPlusMember ? "2" : profile?.memberType
1546
- //:0(游客),1(普通会员),2(付费会员)
1547
- },
1548
- {
1549
- key: "_user_type",
1550
- value: userType
1551
- // n
1552
- },
1553
- {
1554
- key: "_is_login",
1555
- value: profile?.token ? "true" : "false"
1556
- }
1557
- ];
1558
- if (profile?.token) {
1559
- attributes.push({
1560
- key: "_login_user",
1561
- value: "1"
1562
- });
1290
+ ];
1291
+ const weightAttributes = [
1292
+ {
1293
+ key: "_weight",
1294
+ value: cart?.lineItems.reduce((acc, item) => {
1295
+ return new Decimal2(acc).plus(item.variant.weight ?? 0).toNumber();
1296
+ }, 0).toString()
1297
+ },
1298
+ {
1299
+ key: "_app_source_name",
1300
+ value: "dtc"
1563
1301
  }
1564
- return attributes;
1565
- }, [profile?.memberType, profile?.token, userType, hasPlusMember]);
1566
- const functionAttributes = useMemo(() => {
1567
- const hasFunctionEnvAttribute = cart?.lineItems.some(
1568
- (item) => item.customAttributes?.some((attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY)
1569
- );
1570
- const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1571
- return hasFunctionEnvAttribute ? [
1572
- {
1573
- key: "_discounts_function_env",
1574
- value: JSON.stringify({
1575
- discount_code: discountCodes,
1576
- user_tags: customer?.tags || []
1577
- })
1578
- }
1579
- ] : [];
1580
- }, [cart, customer]);
1581
- const presellAttributes = useMemo(() => {
1582
- return [
1583
- {
1584
- key: "_presale",
1585
- value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1586
- }
1587
- ];
1588
- }, [cart]);
1589
- const weightAttributes = useMemo(() => {
1590
- return [
1591
- {
1592
- key: "_weight",
1593
- value: cart?.lineItems.reduce((acc, item) => {
1594
- return new Decimal2(acc).plus(item.variant.weight ?? 0).toNumber();
1595
- }, 0).toString()
1596
- },
1597
- {
1598
- key: "_app_source_name",
1599
- value: "dtc"
1600
- }
1601
- ];
1602
- }, [cart]);
1603
- const trackingAttributes = useMemo(() => {
1604
- return [
1605
- {
1606
- key: "utm_params",
1607
- value: currentUrl
1608
- }
1609
- ];
1610
- }, [currentUrl]);
1611
- const commonAttributes = useMemo(
1612
- () => [
1613
- ...memberAttributes,
1614
- ...functionAttributes,
1615
- ...presellAttributes,
1616
- ...weightAttributes,
1617
- ...trackingAttributes,
1618
- ...getReferralAttributes()
1619
- ].filter((item) => item?.value),
1620
- [memberAttributes, functionAttributes, presellAttributes, weightAttributes, trackingAttributes]
1621
- );
1622
- const extraAttributesInCart = useMemo(() => {
1623
- const commonAttributeKeys = [
1624
- // member attributes
1625
- "_token",
1626
- "_member_type",
1627
- "_user_type",
1628
- "_is_login",
1629
- "_login_user",
1630
- // function attributes
1631
- "_discounts_function_env",
1632
- // presell attributes
1633
- "_presale",
1634
- // weight attributes
1635
- "_weight",
1636
- "_app_source_name",
1637
- // tracking attributes
1638
- "utm_params",
1639
- // referral attributes
1640
- "_invite_code",
1641
- "_play_mode_id",
1642
- "_popup"
1643
- ];
1644
- return cart?.customAttributes?.filter((item) => !commonAttributeKeys.includes(item.key)) || [];
1645
- }, [cart]);
1302
+ ];
1303
+ const trackingAttributes = [
1304
+ {
1305
+ key: "utm_params",
1306
+ value: currentUrl
1307
+ }
1308
+ ];
1309
+ const commonAttributes = [
1310
+ ...memberAttributes,
1311
+ ...functionAttributes,
1312
+ ...presellAttributes,
1313
+ ...weightAttributes,
1314
+ ...trackingAttributes,
1315
+ ...getReferralAttributes()
1316
+ ].filter((item) => item?.value);
1317
+ const extraAttributesInCart = cart?.customAttributes?.filter(
1318
+ (item) => !commonAttributes.some((attr) => attr.key === item.key)
1319
+ ) || [];
1320
+ return [...commonAttributes, ...extraAttributesInCart].filter((item) => item?.value);
1321
+ }
1322
+ var useCartAttributes = ({
1323
+ profile,
1324
+ customer,
1325
+ cart,
1326
+ memberType
1327
+ }) => {
1328
+ const [currentUrl, setCurrentUrl] = useState("");
1329
+ useEffect(() => {
1330
+ setCurrentUrl(window.location.href);
1331
+ }, []);
1332
+ const attributes = useMemo(() => {
1333
+ return getCartAttributes({
1334
+ profile,
1335
+ customer,
1336
+ cart,
1337
+ memberType,
1338
+ currentUrl
1339
+ });
1340
+ }, [profile, customer, cart, memberType, currentUrl]);
1646
1341
  return useMemo(
1647
1342
  () => ({
1648
- attributes: [...commonAttributes, ...extraAttributesInCart].filter(
1649
- (item) => item?.value
1650
- )
1343
+ attributes
1651
1344
  }),
1652
- [commonAttributes, extraAttributesInCart]
1345
+ [attributes]
1653
1346
  );
1654
1347
  };
1655
1348
  var DEFAULT_MIN = 1;
@@ -1686,6 +1379,51 @@ var useCartItemQuantityLimit = ({
1686
1379
  }, [cartItem, cart]);
1687
1380
  return quantityLimit;
1688
1381
  };
1382
+ function hasPlusMemberInLines({
1383
+ memberSetting,
1384
+ lines
1385
+ }) {
1386
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1387
+ if (!lines || lines.length === 0) {
1388
+ return {
1389
+ hasPlusMember: false,
1390
+ hasMonthlyPlus: false,
1391
+ hasAnnualPlus: false
1392
+ };
1393
+ }
1394
+ const monthlyPlusLine = lines.find((line) => {
1395
+ const variantHandle = line.variant?.product?.handle;
1396
+ const variantSku = line.variant?.sku;
1397
+ return variantHandle === plus_monthly_product?.handle && variantSku === plus_monthly_product?.sku;
1398
+ });
1399
+ const annualPlusLine = lines.find((line) => {
1400
+ const variantHandle = line.variant?.product?.handle;
1401
+ const variantSku = line.variant?.sku;
1402
+ return variantHandle === plus_annual_product?.handle && variantSku === plus_annual_product?.sku;
1403
+ });
1404
+ const hasMonthlyPlus = !!monthlyPlusLine;
1405
+ const hasAnnualPlus = !!annualPlusLine;
1406
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1407
+ return {
1408
+ hasPlusMember,
1409
+ hasMonthlyPlus,
1410
+ hasAnnualPlus,
1411
+ monthlyPlusLine,
1412
+ annualPlusLine
1413
+ };
1414
+ }
1415
+ function useHasPlusMemberInLines({
1416
+ memberSetting,
1417
+ lines
1418
+ }) {
1419
+ return useMemo(
1420
+ () => hasPlusMemberInLines({
1421
+ memberSetting,
1422
+ lines
1423
+ }),
1424
+ [memberSetting, lines]
1425
+ );
1426
+ }
1689
1427
  var useUpdateLineCodeAmountAttributes = ({
1690
1428
  cart,
1691
1429
  mutateCart,
@@ -1801,45 +1539,61 @@ var useUpdateLineCodeAmountAttributes = ({
1801
1539
  }, [loading, setLoadingState]);
1802
1540
  };
1803
1541
 
1804
- // src/hooks/cart/types/price-discount.ts
1805
- var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
1806
- PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
1807
- PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
1808
- return PriceDiscountType2;
1809
- })(PriceDiscountType || {});
1810
- var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
1811
- PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
1812
- PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
1813
- return PriceBasePriceType2;
1814
- })(PriceBasePriceType || {});
1815
- function useProduct(options = {}) {
1816
- const { client, locale } = useShopify();
1817
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
1818
- return useSWR(
1819
- handle ? ["product", locale, handle, metafieldIdentifiers] : null,
1820
- () => getProduct(client, {
1821
- handle,
1822
- locale,
1823
- metafieldIdentifiers
1824
- }),
1825
- swrOptions
1826
- );
1827
- }
1828
- function useAllProducts(options = {}) {
1829
- const { client, locale } = useShopify();
1830
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
1831
- return useSWR(
1832
- ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
1833
- () => getAllProducts(client, {
1834
- locale,
1835
- first,
1836
- query,
1837
- sortKey,
1838
- reverse,
1839
- metafieldIdentifiers
1840
- }),
1841
- swrOptions
1842
- );
1542
+ // src/hooks/member/plus/types.ts
1543
+ var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
1544
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
1545
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
1546
+ PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
1547
+ return PLUS_MEMBER_TYPE2;
1548
+ })(PLUS_MEMBER_TYPE || {});
1549
+ var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
1550
+ PlusMemberMode2["MONTHLY"] = "monthly";
1551
+ PlusMemberMode2["ANNUAL"] = "annual";
1552
+ return PlusMemberMode2;
1553
+ })(PlusMemberMode || {});
1554
+ var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
1555
+ DeliveryPlusType2["FREE"] = "free";
1556
+ DeliveryPlusType2["MONTHLY"] = "monthly";
1557
+ DeliveryPlusType2["ANNUAL"] = "annual";
1558
+ return DeliveryPlusType2;
1559
+ })(DeliveryPlusType || {});
1560
+ var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
1561
+ ShippingMethodMode2["FREE"] = "free";
1562
+ ShippingMethodMode2["TDD"] = "tdd";
1563
+ ShippingMethodMode2["NDD"] = "ndd";
1564
+ return ShippingMethodMode2;
1565
+ })(ShippingMethodMode || {});
1566
+ var createInitialValue = () => ({
1567
+ plusMemberMetafields: {},
1568
+ selectedPlusMemberMode: "free",
1569
+ setSelectedPlusMemberMode: () => {
1570
+ },
1571
+ selectedShippingMethod: void 0,
1572
+ setSelectedShippingMethod: () => {
1573
+ },
1574
+ showMoreShippingMethod: false,
1575
+ setShowMoreShippingMethod: () => {
1576
+ },
1577
+ variant: {},
1578
+ product: {},
1579
+ shippingMethodsContext: {
1580
+ freeShippingMethods: [],
1581
+ paymentShippingMethods: [],
1582
+ nddOverweight: false,
1583
+ tddOverweight: false,
1584
+ nddCoupon: void 0,
1585
+ tddCoupon: void 0,
1586
+ isLoadingCoupon: false
1587
+ },
1588
+ selectedPlusMemberVariant: void 0,
1589
+ showPlusMemberBenefit: false,
1590
+ setShowPlusMemberBenefit: () => {
1591
+ },
1592
+ profile: void 0
1593
+ });
1594
+ var PlusMemberContext = createContext(createInitialValue());
1595
+ function usePlusMemberContext() {
1596
+ return useContext(PlusMemberContext);
1843
1597
  }
1844
1598
  function useProductsByHandles(options = {}) {
1845
1599
  const { client, locale } = useShopify();
@@ -1865,1185 +1619,1298 @@ function useProductsByHandles(options = {}) {
1865
1619
  }
1866
1620
  );
1867
1621
  }
1868
- function getFirstAvailableVariant(product) {
1869
- const availableVariant = product.variants.find((v) => v.availableForSale);
1870
- return availableVariant || product.variants[0];
1871
- }
1872
- function getVariantFromSelectedOptions(product, selectedOptions) {
1873
- return product.variants.find((variant) => {
1874
- return variant.selectedOptions.every((option) => {
1875
- return selectedOptions[option.name] === option.value;
1876
- });
1877
- });
1878
- }
1879
- function useVariant({
1880
- product,
1881
- selectedOptions
1882
- }) {
1883
- const [variant, setVariant] = useState(
1884
- product ? getFirstAvailableVariant(product) : void 0
1885
- );
1886
- useEffect(() => {
1887
- if (!product) {
1888
- setVariant(void 0);
1889
- return;
1890
- }
1891
- const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
1892
- if (newVariant && newVariant.id !== variant?.id) {
1893
- setVariant(newVariant);
1894
- } else if (!newVariant) {
1895
- setVariant(getFirstAvailableVariant(product));
1896
- }
1897
- }, [selectedOptions, product, variant?.id]);
1898
- return variant;
1899
- }
1900
- var FAKE_PRICE = 999999999e-2;
1901
- function formatPrice({
1902
- amount,
1903
- currencyCode,
1904
- locale,
1905
- maximumFractionDigits,
1906
- minimumFractionDigits,
1907
- removeTrailingZeros
1622
+
1623
+ // src/hooks/member/plus/use-plus-member-variants.ts
1624
+ function usePlusMemberVariants({
1625
+ memberSetting
1908
1626
  }) {
1909
- const formatter = new Intl.NumberFormat(locale, {
1910
- style: "currency",
1911
- currency: currencyCode,
1912
- maximumFractionDigits: maximumFractionDigits ?? 2,
1913
- minimumFractionDigits: minimumFractionDigits ?? 2
1627
+ const plusMonthly = memberSetting?.plus_monthly_product;
1628
+ const plusAnnual = memberSetting?.plus_annual_product;
1629
+ const plusMemberHandles = useMemo(() => {
1630
+ return [plusMonthly?.handle, plusAnnual?.handle].filter(Boolean);
1631
+ }, [plusMonthly?.handle, plusAnnual?.handle]);
1632
+ const { data: plusMemberProducts = [] } = useProductsByHandles({
1633
+ handles: plusMemberHandles
1914
1634
  });
1915
- let formatted = formatter.format(amount);
1916
- if (removeTrailingZeros) {
1917
- formatted = formatted.replace(/\.00$/, "");
1918
- }
1919
- return formatted;
1920
- }
1921
- function formatVariantPrice({
1922
- amount,
1923
- baseAmount,
1924
- currencyCode,
1925
- locale,
1926
- maximumFractionDigits,
1927
- minimumFractionDigits,
1928
- removeTrailingZeros
1929
- }) {
1635
+ const monthlyProduct = useMemo(() => {
1636
+ return plusMemberProducts?.find((item) => item?.handle === plusMonthly?.handle);
1637
+ }, [plusMemberProducts, plusMonthly]);
1638
+ const annualProduct = useMemo(() => {
1639
+ return plusMemberProducts?.find((item) => item?.handle === plusAnnual?.handle);
1640
+ }, [plusMemberProducts, plusAnnual]);
1641
+ const monthlyVariant = useMemo(() => {
1642
+ return monthlyProduct?.variants?.find((item) => item.sku === plusMonthly?.sku);
1643
+ }, [monthlyProduct, plusMonthly]);
1644
+ const annualVariant = useMemo(() => {
1645
+ return annualProduct?.variants?.find((item) => item.sku === plusAnnual?.sku);
1646
+ }, [annualProduct, plusAnnual]);
1930
1647
  return {
1931
- price: formatPrice({
1932
- amount,
1933
- currencyCode,
1934
- locale,
1935
- maximumFractionDigits,
1936
- minimumFractionDigits,
1937
- removeTrailingZeros
1938
- }),
1939
- basePrice: formatPrice({
1940
- amount: baseAmount,
1941
- currencyCode,
1942
- locale,
1943
- maximumFractionDigits,
1944
- minimumFractionDigits,
1945
- removeTrailingZeros
1946
- })
1648
+ monthlyVariant: monthlyVariant ? {
1649
+ ...monthlyVariant,
1650
+ product: monthlyProduct
1651
+ } : void 0,
1652
+ annualVariant: annualVariant ? {
1653
+ ...annualVariant,
1654
+ product: annualProduct
1655
+ } : void 0
1947
1656
  };
1948
1657
  }
1949
- function usePrice({
1950
- amount,
1951
- baseAmount,
1952
- currencyCode,
1953
- soldOutDescription = "",
1954
- maximumFractionDigits,
1955
- minimumFractionDigits,
1956
- removeTrailingZeros
1957
- }) {
1958
- const { locale } = useShopify();
1959
- const value = useMemo(() => {
1960
- if (typeof amount !== "number" || !currencyCode) {
1961
- return "";
1962
- }
1963
- if (soldOutDescription && amount >= FAKE_PRICE) {
1964
- return soldOutDescription;
1658
+ var useAvailableDeliveryCoupon = ({
1659
+ profile
1660
+ }) => {
1661
+ const { data: availableDeliveryCoupon, isLoading } = useSWR(
1662
+ profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
1663
+ async ([apiPath]) => {
1664
+ return fetch(apiPath).then((res) => res.json());
1965
1665
  }
1966
- return baseAmount ? formatVariantPrice({
1967
- amount,
1968
- baseAmount,
1969
- currencyCode,
1970
- locale,
1971
- maximumFractionDigits,
1972
- minimumFractionDigits,
1973
- removeTrailingZeros
1974
- }) : formatPrice({
1975
- amount,
1976
- currencyCode,
1977
- locale,
1978
- maximumFractionDigits,
1979
- minimumFractionDigits,
1980
- removeTrailingZeros
1666
+ );
1667
+ console.log("availableDeliveryCoupon", availableDeliveryCoupon);
1668
+ const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
1669
+ return {
1670
+ nddCoupon,
1671
+ tddCoupon,
1672
+ isLoading
1673
+ };
1674
+ };
1675
+
1676
+ // src/hooks/member/plus/use-shipping-methods.ts
1677
+ function useShippingMethods(options) {
1678
+ const { variant, plusMemberMetafields, selectedPlusMemberMode, profile } = options;
1679
+ const isPlus = profile?.isPlus || false;
1680
+ const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
1681
+ const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
1682
+ const nddOverweight = useMemo(() => {
1683
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
1684
+ }, [shippingMethod?.overWeight_ndd, variant?.weight]);
1685
+ const tddOverweight = useMemo(() => {
1686
+ return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
1687
+ }, [shippingMethod?.overWeight_tdd, variant?.weight]);
1688
+ const paymentShippingMethods = useMemo(() => {
1689
+ const weight = variant?.weight || 0;
1690
+ const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
1691
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1692
+ return __mode !== "free" /* FREE */ && !__plus && fitWeight;
1693
+ }) || [];
1694
+ return methods.map((method) => {
1695
+ let disabled = false;
1696
+ const selectedFreeMember = selectedPlusMemberMode === "free";
1697
+ if (method.__mode === "ndd" /* NDD */) {
1698
+ disabled = selectedFreeMember || nddOverweight;
1699
+ } else if (method.__mode === "tdd" /* TDD */) {
1700
+ disabled = selectedFreeMember || tddOverweight;
1701
+ }
1702
+ return {
1703
+ ...method,
1704
+ id: method.__mode + method.__code,
1705
+ useCoupon: false,
1706
+ subtitle: plus_shipping?.directly || "",
1707
+ disabled
1708
+ };
1981
1709
  });
1982
1710
  }, [
1983
- amount,
1984
- baseAmount,
1985
- currencyCode,
1986
- locale,
1987
- maximumFractionDigits,
1988
- minimumFractionDigits,
1989
- soldOutDescription,
1990
- removeTrailingZeros
1711
+ nddOverweight,
1712
+ plus_shipping?.directly,
1713
+ plus_shipping?.shipping_methods,
1714
+ selectedPlusMemberMode,
1715
+ tddOverweight,
1716
+ variant?.weight
1991
1717
  ]);
1992
- const result = useMemo(() => {
1993
- const free = Boolean(amount && amount <= 0);
1994
- return typeof value === "string" ? { price: value, basePrice: value, free } : { ...value, free };
1995
- }, [value, amount]);
1996
- return result;
1997
- }
1998
- function optionsConstructor(selectedOptions) {
1999
- return selectedOptions.reduce((acc, option) => {
2000
- acc[option.name] = option.value;
2001
- return acc;
2002
- }, {});
2003
- }
2004
- function decodeShopifyId(gid) {
2005
- try {
2006
- const base64 = gid.split("/").pop() || "";
2007
- return atob(base64);
2008
- } catch {
2009
- return gid;
2010
- }
2011
- }
2012
- function useSelectedOptions(product, sku) {
2013
- const [options, setOptions] = useState({});
2014
- useEffect(() => {
2015
- if (!product || !product.variants.length) {
2016
- setOptions({});
2017
- return;
2018
- }
2019
- let variant = product.variants[0];
2020
- if (typeof window !== "undefined") {
2021
- const searchParams = new URLSearchParams(window.location.search);
2022
- const variantIdParam = searchParams.get("variant");
2023
- if (variantIdParam) {
2024
- const foundVariant = product.variants.find((v) => {
2025
- if (sku) return v.sku === sku;
2026
- return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
2027
- });
2028
- if (foundVariant) {
2029
- variant = foundVariant;
2030
- }
1718
+ const nddPrice = useMemo(() => {
1719
+ const weight = variant?.weight || 0;
1720
+ const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1721
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1722
+ return __mode === "ndd" && fitWeight;
1723
+ });
1724
+ return nddMethod?.price || 0;
1725
+ }, [variant?.weight, paymentShippingMethods]);
1726
+ const tddPrice = useMemo(() => {
1727
+ const weight = variant?.weight || 0;
1728
+ const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
1729
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1730
+ return __mode === "tdd" && fitWeight;
1731
+ });
1732
+ return tddMethod?.price || 0;
1733
+ }, [variant?.weight, paymentShippingMethods]);
1734
+ const freeShippingMethods = useMemo(() => {
1735
+ const weight = variant?.weight || 0;
1736
+ let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
1737
+ if (__mode === "free" /* FREE */) {
1738
+ return true;
2031
1739
  }
1740
+ if (isPlus) {
1741
+ const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
1742
+ const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
1743
+ return hasCoupon && fitWeight && !__plus;
1744
+ } else {
1745
+ return __plus;
1746
+ }
1747
+ }) || [];
1748
+ if (isPlus) {
1749
+ methods = methods.sort((a, b) => {
1750
+ if (b.__mode === "free" /* FREE */) return -1;
1751
+ return 0;
1752
+ });
2032
1753
  }
2033
- if (variant) {
2034
- const newOptions = optionsConstructor(variant.selectedOptions);
2035
- setOptions(newOptions);
2036
- }
2037
- }, [product, sku]);
2038
- return [options, setOptions];
2039
- }
2040
- function decodeShopifyId2(gid) {
2041
- try {
2042
- const parts = gid.split("/");
2043
- return parts[parts.length - 1] || gid;
2044
- } catch {
2045
- return gid;
2046
- }
2047
- }
2048
- function useProductUrl(otherQuery) {
2049
- const { routerAdapter } = useShopify();
2050
- return useCallback(
2051
- ({ product, variant }) => {
2052
- if (!product) return "";
2053
- const queryParams = new URLSearchParams();
2054
- if (variant?.id) {
2055
- const variantId = decodeShopifyId2(variant.id);
2056
- if (variantId) {
2057
- queryParams.set("variant", variantId);
1754
+ return methods.map((method) => {
1755
+ let price = 0;
1756
+ let coupon;
1757
+ let disabled;
1758
+ if (method.__mode !== "free" /* FREE */) {
1759
+ switch (method.__mode) {
1760
+ case "tdd":
1761
+ price = tddPrice;
1762
+ coupon = tddCoupon || nddCoupon;
1763
+ break;
1764
+ case "ndd":
1765
+ price = nddPrice;
1766
+ coupon = nddCoupon;
1767
+ break;
1768
+ }
1769
+ disabled = selectedPlusMemberMode === "free";
1770
+ if (method.__mode === "ndd" /* NDD */) {
1771
+ disabled = disabled || nddOverweight;
1772
+ } else if (method.__mode === "tdd" /* TDD */) {
1773
+ disabled = disabled || tddOverweight;
2058
1774
  }
2059
1775
  }
2060
- if (otherQuery) {
2061
- Object.entries(otherQuery).forEach(([key, value]) => {
2062
- queryParams.set(key, value);
2063
- });
2064
- }
2065
- const queryString = queryParams.toString();
2066
- const path = `/products/${product.handle}${queryString ? `?${queryString}` : ""}`;
2067
- if (routerAdapter?.getLocalizedPath) {
2068
- return routerAdapter.getLocalizedPath(path);
2069
- }
2070
- return path;
2071
- },
2072
- [routerAdapter, otherQuery]
2073
- );
2074
- }
2075
- function decodeShopifyId3(gid) {
2076
- try {
2077
- const parts = gid.split("/");
2078
- return parts[parts.length - 1] || gid;
2079
- } catch {
2080
- return gid;
2081
- }
2082
- }
2083
- function useUpdateVariantQuery(variant) {
2084
- useEffect(() => {
2085
- if (!variant || typeof window === "undefined") {
2086
- return;
2087
- }
2088
- const searchParams = new URLSearchParams(window.location.search);
2089
- const currentVariantId = searchParams.get("variant");
2090
- const newVariantId = decodeShopifyId3(variant.id);
2091
- if (newVariantId && currentVariantId !== newVariantId) {
2092
- searchParams.set("variant", newVariantId);
2093
- const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
2094
- window.history.replaceState({}, "", newUrl);
2095
- }
2096
- }, [variant]);
1776
+ return {
1777
+ ...method,
1778
+ id: method.__mode + method.__code,
1779
+ useCoupon: true,
1780
+ disabled,
1781
+ coupon,
1782
+ price
1783
+ };
1784
+ });
1785
+ }, [
1786
+ variant?.weight,
1787
+ plus_shipping?.shipping_methods,
1788
+ isPlus,
1789
+ nddCoupon,
1790
+ tddCoupon,
1791
+ selectedPlusMemberMode,
1792
+ tddPrice,
1793
+ nddPrice,
1794
+ nddOverweight,
1795
+ tddOverweight
1796
+ ]);
1797
+ return {
1798
+ freeShippingMethods,
1799
+ paymentShippingMethods,
1800
+ nddOverweight,
1801
+ tddOverweight,
1802
+ nddCoupon,
1803
+ tddCoupon,
1804
+ isLoadingCoupon: isLoading
1805
+ };
2097
1806
  }
2098
- function getVariantMediaList({
2099
- product,
2100
- variant
2101
- }) {
2102
- if (variant.image?.url) {
2103
- const variantMediaId = variant.image.url;
2104
- const variantMedia = product.media.filter((media) => {
2105
- if (media.mediaContentType === "IMAGE" && media.previewImage) {
2106
- return media.previewImage?.url === variantMediaId;
1807
+ var useReplaceCartPlusMember = () => {
1808
+ const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
1809
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1810
+ const { cart } = useCartContext();
1811
+ const plusMonthly = plusMemberMetafields?.plus_monthly_product;
1812
+ const plusAnnual = plusMemberMetafields?.plus_annual_product;
1813
+ const handler = useCallback(async () => {
1814
+ const plusMonthlyInCart = cart?.lineItems.find(
1815
+ (item) => item.variant?.sku === plusMonthly?.sku
1816
+ );
1817
+ const plusAnnualInCart = cart?.lineItems.find(
1818
+ (item) => item.variant?.sku === plusAnnual?.sku
1819
+ );
1820
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
1821
+ await removeCartLines2({
1822
+ lineIds: [plusMonthlyInCart.id]
1823
+ });
1824
+ } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
1825
+ await removeCartLines2({
1826
+ lineIds: [plusAnnualInCart.id]
1827
+ });
1828
+ }
1829
+ }, [
1830
+ cart?.lineItems,
1831
+ selectedPlusMemberMode,
1832
+ plusMonthly?.sku,
1833
+ plusAnnual?.sku,
1834
+ removeCartLines2
1835
+ ]);
1836
+ return handler;
1837
+ };
1838
+ var usePlusMemberCheckoutCustomAttributes = ({
1839
+ disableShipping = false,
1840
+ isPresaleContains = false
1841
+ }) => {
1842
+ const { profile, selectedShippingMethod, selectedPlusMemberMode } = usePlusMemberContext();
1843
+ return useMemo(() => {
1844
+ const checkoutCustomAttributes = [
1845
+ {
1846
+ key: "_last_url",
1847
+ value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2107
1848
  }
2108
- return false;
1849
+ ];
1850
+ checkoutCustomAttributes.push({
1851
+ key: "_checkout_delivery_custom",
1852
+ value: JSON.stringify({
1853
+ allow_nextday_delivery: true,
1854
+ allow_thirdday_delivery: true,
1855
+ selected_delivery_option: {
1856
+ code: selectedShippingMethod?.__code,
1857
+ mode: selectedShippingMethod?.__mode
1858
+ },
1859
+ is_presale: isPresaleContains,
1860
+ discount_code: selectedShippingMethod?.coupon ? [selectedShippingMethod.coupon] : [],
1861
+ plus_type: profile?.isPlus ? "free" /* FREE */ : selectedPlusMemberMode,
1862
+ is_prime: profile?.isPlus
1863
+ })
2109
1864
  });
2110
- if (variantMedia.length > 0) {
2111
- const otherMedia = product.media.filter((media) => {
2112
- if (media.mediaContentType === "IMAGE" && media.previewImage) {
2113
- return media.previewImage.url !== variantMediaId;
2114
- }
2115
- return true;
1865
+ if (disableShipping) {
1866
+ checkoutCustomAttributes.push({
1867
+ key: "_hide_shipping",
1868
+ value: "true"
2116
1869
  });
2117
- return [...variantMedia, ...otherMedia];
2118
1870
  }
2119
- }
2120
- return product.media;
1871
+ return checkoutCustomAttributes;
1872
+ }, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
1873
+ };
1874
+ function useRemoveCartLines(options) {
1875
+ const { client, locale, cartCookieAdapter } = useShopify();
1876
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
1877
+ const removeLines = useCallback(
1878
+ async (_key, { arg }) => {
1879
+ const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1880
+ let updatedCart = await removeCartLines(client, {
1881
+ cartId,
1882
+ lineIds,
1883
+ metafieldIdentifiers,
1884
+ cookieAdapter: cartCookieAdapter
1885
+ });
1886
+ if (updatedCart && autoRemoveInvalidCodes) {
1887
+ const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1888
+ if (unApplicableCodes.length > 0) {
1889
+ if (onCodesRemoved) {
1890
+ const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1891
+ if (handledCart) {
1892
+ updatedCart = handledCart;
1893
+ }
1894
+ } else {
1895
+ updatedCart = await updateCartCodes(client, {
1896
+ cartId: updatedCart.id,
1897
+ discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1898
+ metafieldIdentifiers,
1899
+ cookieAdapter: cartCookieAdapter
1900
+ }) || updatedCart;
1901
+ }
1902
+ }
1903
+ }
1904
+ if (updatedCart) {
1905
+ mutateCart(updatedCart);
1906
+ }
1907
+ return updatedCart;
1908
+ },
1909
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1910
+ );
1911
+ return useSWRMutation("remove-cart-lines", removeLines, options);
2121
1912
  }
2122
- function useVariantMedia({
2123
- product,
2124
- variant
1913
+
1914
+ // src/hooks/member/plus/use-auto-remove-plus-member-in-cart.ts
1915
+ function useAutoRemovePlusMemberInCart({
1916
+ cart,
1917
+ profile,
1918
+ memberSetting
2125
1919
  }) {
2126
- const [imageList, setImageList] = useState([]);
2127
- const [sceneList, setSceneList] = useState([]);
2128
- const [videoList, setVideoList] = useState([]);
1920
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1921
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
2129
1922
  useEffect(() => {
2130
- if (!product || !variant) {
2131
- setImageList([]);
2132
- setSceneList([]);
2133
- setVideoList([]);
2134
- return;
1923
+ if (!cart || !plus_monthly_product || !plus_annual_product) return;
1924
+ const removePlusProduct = async (productType) => {
1925
+ if (!productType) return;
1926
+ const product = cart.lineItems?.find(
1927
+ (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
1928
+ );
1929
+ if (product) {
1930
+ await removeCartLines2({
1931
+ lineIds: [product.id]
1932
+ });
1933
+ }
1934
+ };
1935
+ if (profile?.isMonthlyPlus) {
1936
+ removePlusProduct(plus_monthly_product);
2135
1937
  }
2136
- const mediaList = getVariantMediaList({ product, variant });
2137
- const images = mediaList.filter((media) => media.mediaContentType === "IMAGE");
2138
- const videos = mediaList.filter(
2139
- (media) => media.mediaContentType === "VIDEO" || media.mediaContentType === "EXTERNAL_VIDEO"
2140
- );
2141
- setImageList(images.length > 0 && images[0] ? [images[0]] : []);
2142
- setSceneList(images.length > 1 ? images.slice(1) : []);
2143
- setVideoList(videos);
2144
- }, [product, variant]);
2145
- return {
2146
- productList: imageList,
2147
- sceneList,
2148
- videoList
2149
- };
1938
+ if (profile?.isAnnualPlus) {
1939
+ removePlusProduct(plus_annual_product);
1940
+ }
1941
+ }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2150
1942
  }
2151
- function useCollection(options = {}) {
2152
- const { client, locale } = useShopify();
2153
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
2154
- return useSWR(
2155
- handle ? ["collection", locale, handle, metafieldIdentifiers] : null,
2156
- () => getCollection(client, {
2157
- handle,
2158
- locale,
2159
- metafieldIdentifiers
2160
- }),
2161
- swrOptions
1943
+ function hasPlusMemberInCart({
1944
+ memberSetting,
1945
+ cart
1946
+ }) {
1947
+ const { plus_monthly_product, plus_annual_product } = memberSetting || {};
1948
+ if (!cart?.lineItems) {
1949
+ return {
1950
+ hasPlusMember: false,
1951
+ hasMonthlyPlus: false,
1952
+ hasAnnualPlus: false
1953
+ };
1954
+ }
1955
+ const monthlyPlusItem = cart.lineItems.find(
1956
+ (item) => item.product?.handle === plus_monthly_product?.handle && item.variant?.sku === plus_monthly_product?.sku
2162
1957
  );
2163
- }
2164
- function useAllCollections(options = {}) {
2165
- const { client, locale } = useShopify();
2166
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2167
- return useSWR(
2168
- ["all-collections", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2169
- () => getAllCollections(client, {
2170
- locale,
2171
- first,
2172
- query,
2173
- sortKey,
2174
- reverse,
2175
- metafieldIdentifiers
2176
- }),
2177
- swrOptions
1958
+ const annualPlusItem = cart.lineItems.find(
1959
+ (item) => item.product?.handle === plus_annual_product?.handle && item.variant?.sku === plus_annual_product?.sku
2178
1960
  );
1961
+ const hasMonthlyPlus = !!monthlyPlusItem;
1962
+ const hasAnnualPlus = !!annualPlusItem;
1963
+ const hasPlusMember = hasMonthlyPlus || hasAnnualPlus;
1964
+ return {
1965
+ hasPlusMember,
1966
+ hasMonthlyPlus,
1967
+ hasAnnualPlus,
1968
+ monthlyPlusItem,
1969
+ annualPlusItem
1970
+ };
2179
1971
  }
2180
- function useCollections(options = {}) {
2181
- const { client, locale } = useShopify();
2182
- const { first, after, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2183
- return useSWR(
2184
- ["collections", locale, first, after, query, sortKey, reverse, metafieldIdentifiers],
2185
- () => getCollections(client, {
2186
- locale,
2187
- first,
2188
- after,
2189
- query,
2190
- sortKey,
2191
- reverse,
2192
- metafieldIdentifiers
1972
+ function useHasPlusMemberInCart({
1973
+ memberSetting,
1974
+ cart
1975
+ }) {
1976
+ return useMemo(
1977
+ () => hasPlusMemberInCart({
1978
+ memberSetting,
1979
+ cart
2193
1980
  }),
2194
- swrOptions
1981
+ [memberSetting, cart]
2195
1982
  );
2196
1983
  }
2197
- function useBlog(options = {}) {
2198
- const { client, locale } = useShopify();
2199
- const { handle, metafieldIdentifiers, ...swrOptions } = options;
2200
- return useSWR(
2201
- handle ? ["blog", locale, handle, metafieldIdentifiers] : null,
2202
- () => getBlog(client, { handle, locale, metafieldIdentifiers }),
2203
- swrOptions
2204
- );
2205
- }
2206
- function useAllBlogs(options = {}) {
2207
- const { client, locale } = useShopify();
2208
- const { first, query, metafieldIdentifiers, ...swrOptions } = options;
2209
- return useSWR(
2210
- ["all-blogs", locale, first, query, metafieldIdentifiers],
2211
- () => getAllBlogs(client, {
2212
- locale,
2213
- first,
2214
- query,
2215
- metafieldIdentifiers
2216
- }),
2217
- swrOptions
2218
- );
2219
- }
2220
- function useArticle(options = {}) {
2221
- const { client, locale } = useShopify();
2222
- const { blogHandle, articleHandle, metafieldIdentifiers, ...swrOptions } = options;
2223
- return useSWR(
2224
- blogHandle && articleHandle ? ["article", locale, blogHandle, articleHandle, metafieldIdentifiers] : null,
2225
- () => getArticle(client, {
2226
- blogHandle,
2227
- articleHandle,
2228
- locale,
2229
- metafieldIdentifiers
2230
- }),
2231
- swrOptions
2232
- );
1984
+ function usePlusMemberNeedAddToCart({
1985
+ cart,
1986
+ profile
1987
+ }) {
1988
+ const { selectedPlusMemberMode, selectedPlusMemberVariant, plusMemberMetafields } = usePlusMemberContext();
1989
+ const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
1990
+ memberSetting: plusMemberMetafields,
1991
+ cart
1992
+ });
1993
+ const plusMemberVariant = useMemo(() => {
1994
+ if (!selectedPlusMemberVariant || selectedPlusMemberMode === "free" /* FREE */) {
1995
+ return void 0;
1996
+ }
1997
+ if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
1998
+ return void 0;
1999
+ }
2000
+ if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2001
+ return void 0;
2002
+ }
2003
+ if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2004
+ return void 0;
2005
+ }
2006
+ if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2007
+ return void 0;
2008
+ }
2009
+ return selectedPlusMemberVariant;
2010
+ }, [selectedPlusMemberMode, selectedPlusMemberVariant, hasMonthlyPlus, hasAnnualPlus]);
2011
+ return plusMemberVariant;
2233
2012
  }
2234
- function useArticles(options = {}) {
2235
- const { client, locale } = useShopify();
2236
- const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2237
- return useSWR(
2238
- ["articles", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2239
- () => getArticles(client, {
2240
- locale,
2241
- first,
2242
- query,
2243
- sortKey,
2244
- reverse,
2245
- metafieldIdentifiers
2246
- }),
2247
- swrOptions
2013
+ var PlusMemberProvider = ({
2014
+ variant,
2015
+ product,
2016
+ memberSetting,
2017
+ initialSelectedPlusMemberMode = "free",
2018
+ profile,
2019
+ children
2020
+ }) => {
2021
+ const [selectedPlusMemberMode, setSelectedPlusMemberMode] = useState(
2022
+ initialSelectedPlusMemberMode
2248
2023
  );
2249
- }
2250
- function useArticlesInBlog(options = {}) {
2251
- const { client, locale } = useShopify();
2252
- const { blogHandle, first, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2253
- return useSWR(
2254
- blogHandle ? ["articles-in-blog", locale, blogHandle, first, sortKey, reverse, metafieldIdentifiers] : null,
2255
- () => getArticlesInBlog(client, {
2256
- blogHandle,
2257
- locale,
2258
- first,
2259
- sortKey,
2260
- reverse,
2261
- metafieldIdentifiers
2262
- }),
2263
- swrOptions
2024
+ const [selectedShippingMethod, setSelectedShippingMethod] = useState();
2025
+ const [showMoreShippingMethod, setShowMoreShippingMethod] = useState(false);
2026
+ const [showPlusMemberBenefit, setShowPlusMemberBenefit] = useState(false);
2027
+ const shippingMethodsContext = useShippingMethods({
2028
+ variant,
2029
+ plusMemberMetafields: memberSetting,
2030
+ selectedPlusMemberMode,
2031
+ profile
2032
+ });
2033
+ const { monthlyVariant, annualVariant } = usePlusMemberVariants({
2034
+ memberSetting
2035
+ });
2036
+ const selectedPlusMemberVariant = useMemo(() => {
2037
+ if (selectedPlusMemberMode === "free" /* FREE */) {
2038
+ return void 0;
2039
+ }
2040
+ return selectedPlusMemberMode === "monthly" /* MONTHLY */ ? monthlyVariant : annualVariant;
2041
+ }, [monthlyVariant, annualVariant, selectedPlusMemberMode]);
2042
+ return /* @__PURE__ */ jsx(
2043
+ PlusMemberContext.Provider,
2044
+ {
2045
+ value: {
2046
+ variant,
2047
+ plusMemberMetafields: memberSetting,
2048
+ selectedPlusMemberMode,
2049
+ setSelectedPlusMemberMode,
2050
+ selectedShippingMethod,
2051
+ setSelectedShippingMethod,
2052
+ shippingMethodsContext,
2053
+ showMoreShippingMethod,
2054
+ setShowMoreShippingMethod,
2055
+ selectedPlusMemberVariant,
2056
+ product,
2057
+ showPlusMemberBenefit,
2058
+ setShowPlusMemberBenefit,
2059
+ profile
2060
+ },
2061
+ children
2062
+ }
2264
2063
  );
2265
- }
2266
- async function performSearch(client, locale, searchQuery, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"]) {
2267
- if (!searchQuery) {
2268
- return void 0;
2269
- }
2270
- const query = (
2271
- /* GraphQL */
2272
- `
2273
- query search($query: String!, $first: Int!, $types: [SearchType!])
2274
- @inContext(language: $language) {
2275
- search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
2276
- totalCount
2277
- edges {
2278
- node {
2279
- ... on Article {
2280
- __typename
2281
- id
2282
- handle
2283
- title
2284
- excerpt
2285
- image {
2286
- url
2287
- altText
2288
- }
2289
- }
2290
- ... on Page {
2291
- __typename
2292
- id
2293
- handle
2294
- title
2295
- }
2296
- ... on Product {
2297
- __typename
2298
- id
2299
- handle
2300
- title
2301
- description
2302
- featuredImage {
2303
- url
2304
- altText
2064
+ };
2065
+
2066
+ // src/hooks/cart/use-add-to-cart.ts
2067
+ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2068
+ const { client, config, locale, cartCookieAdapter, userAdapter, performanceAdapter } = useShopify();
2069
+ const { cart, addCustomAttributes, memberSetting, profile, customer } = useCartContext();
2070
+ const { trigger: applyCartCodes } = useApplyCartCodes();
2071
+ const { trigger: removeInvalidCodes } = useRemoveCartCodes();
2072
+ const { trigger: addCartLines2 } = useAddCartLines();
2073
+ const { trigger: createCart4 } = useCreateCart({
2074
+ updateCookie: true
2075
+ });
2076
+ const { hasPlusMember } = useHasPlusMemberInCart({
2077
+ memberSetting,
2078
+ cart
2079
+ });
2080
+ const { attributes: cartAttributes } = useCartAttributes({
2081
+ profile,
2082
+ customer,
2083
+ cart,
2084
+ memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
2085
+ });
2086
+ const addToCart = useCallback(
2087
+ async (_key, { arg }) => {
2088
+ const {
2089
+ lineItems,
2090
+ cartId: providedCartId,
2091
+ discountCodes,
2092
+ gtmParams = {},
2093
+ buyerIdentity,
2094
+ needCreateCart = false,
2095
+ onCodesInvalid,
2096
+ replaceExistingCodes,
2097
+ customAttributes
2098
+ } = arg;
2099
+ if (!lineItems || lineItems.length === 0) {
2100
+ return;
2101
+ }
2102
+ performanceAdapter?.addToCartStart();
2103
+ const linesWithFunctionAttributes = getLinesWithAttributes({ cart, lineItems });
2104
+ const lines = linesWithFunctionAttributes.map((item) => ({
2105
+ merchandiseId: item.variant?.id || "",
2106
+ quantity: item.quantity || 1,
2107
+ attributes: item.attributes,
2108
+ sellingPlanId: item.sellingPlanId
2109
+ })).filter((item) => item.merchandiseId && item.quantity);
2110
+ if (lines.length === 0) {
2111
+ return;
2112
+ }
2113
+ let cartId = needCreateCart ? void 0 : providedCartId || cart?.id;
2114
+ let resultCart = null;
2115
+ if (!cartId) {
2116
+ resultCart = await createCart4({
2117
+ lines,
2118
+ buyerIdentity,
2119
+ discountCodes,
2120
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2121
+ // 初次加购时,就把所有 cart attributes 带上
2122
+ });
2123
+ } else {
2124
+ resultCart = await addCartLines2({
2125
+ cartId,
2126
+ lines
2127
+ });
2128
+ console.log("npm addCartLines resultCart", resultCart);
2129
+ if (resultCart && resultCart.discountCodes && resultCart.discountCodes.length > 0) {
2130
+ const unapplicableCodes = resultCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
2131
+ if (unapplicableCodes.length > 0) {
2132
+ if (onCodesInvalid) {
2133
+ const handledCart = await onCodesInvalid(resultCart, unapplicableCodes);
2134
+ if (handledCart) {
2135
+ resultCart = handledCart;
2305
2136
  }
2137
+ } else {
2138
+ await removeInvalidCodes({
2139
+ discountCodes: unapplicableCodes
2140
+ });
2306
2141
  }
2307
2142
  }
2308
2143
  }
2309
- pageInfo {
2310
- hasNextPage
2311
- endCursor
2144
+ if (resultCart && discountCodes && discountCodes.length > 0) {
2145
+ applyCartCodes({
2146
+ replaceExistingCodes,
2147
+ discountCodes
2148
+ });
2149
+ }
2150
+ if (customAttributes && customAttributes.length > 0) {
2151
+ addCustomAttributes(customAttributes);
2312
2152
  }
2313
2153
  }
2314
- }
2315
- `
2316
- );
2317
- const data = await client.query(query, {
2318
- query: searchQuery,
2319
- first,
2320
- types
2321
- });
2322
- if (!data || !data.search) {
2323
- return void 0;
2324
- }
2325
- const items = data.search.edges?.map((edge) => {
2326
- const node = edge.node;
2327
- const item = {
2328
- type: node.__typename.toUpperCase(),
2329
- id: node.id,
2330
- handle: node.handle,
2331
- title: node.title
2332
- };
2333
- if (node.__typename === "Product") {
2334
- item.description = node.description;
2335
- item.image = node.featuredImage ? {
2336
- url: node.featuredImage.url,
2337
- altText: node.featuredImage.altText
2338
- } : void 0;
2339
- } else if (node.__typename === "Article") {
2340
- item.description = node.excerpt;
2341
- item.image = node.image ? {
2342
- url: node.image.url,
2343
- altText: node.image.altText
2344
- } : void 0;
2345
- }
2346
- return item;
2347
- }) || [];
2348
- return {
2349
- items,
2350
- totalCount: data.search.totalCount || 0,
2351
- pageInfo: data.search.pageInfo
2352
- };
2154
+ if (withTrack) {
2155
+ trackAddToCartGA({
2156
+ lineItems,
2157
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2158
+ });
2159
+ trackAddToCartFBQ({ lineItems });
2160
+ }
2161
+ performanceAdapter?.addToCartEnd();
2162
+ return resultCart;
2163
+ },
2164
+ [
2165
+ client,
2166
+ locale,
2167
+ cartCookieAdapter,
2168
+ userAdapter,
2169
+ cart,
2170
+ withTrack,
2171
+ performanceAdapter,
2172
+ createCart4,
2173
+ addCartLines2,
2174
+ applyCartCodes,
2175
+ removeInvalidCodes,
2176
+ addCustomAttributes,
2177
+ config
2178
+ ]
2179
+ );
2180
+ return useSWRMutation("add-to-cart", addToCart, swrOptions);
2353
2181
  }
2354
- function useSearch(options = {}) {
2355
- const { client, locale } = useShopify();
2356
- const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2357
- return useSWR(
2358
- query ? ["search", locale, query, first, types] : null,
2359
- () => performSearch(client, locale, query, first, types),
2360
- swrOptions
2182
+ function useUpdateCartLines(options) {
2183
+ const { client, locale, cartCookieAdapter } = useShopify();
2184
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
2185
+ const updateLines = useCallback(
2186
+ async (_key, { arg }) => {
2187
+ const updatedCart = await updateCartLines(client, {
2188
+ ...arg,
2189
+ metafieldIdentifiers,
2190
+ cookieAdapter: cartCookieAdapter
2191
+ });
2192
+ if (updatedCart) {
2193
+ mutateCart(updatedCart);
2194
+ }
2195
+ console.log("use-update-cart-lines updatedCart", metafieldIdentifiers, updatedCart);
2196
+ return updatedCart;
2197
+ },
2198
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
2361
2199
  );
2200
+ return useSWRMutation("update-cart-lines", updateLines, options);
2362
2201
  }
2363
- async function getSiteInfo(client, locale, metafieldIdentifiers) {
2364
- const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2365
- const query = (
2366
- /* GraphQL */
2367
- `
2368
- query getSiteInfo(
2369
- ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2370
- ) @inContext(language: $language) {
2371
- shop {
2372
- name
2373
- description
2374
- primaryDomain {
2375
- url
2376
- host
2202
+ function useUpdateCartAttributes({
2203
+ mutate,
2204
+ metafieldIdentifiers,
2205
+ disabled = false,
2206
+ swrOptions
2207
+ }) {
2208
+ const { client, locale, cartCookieAdapter } = useShopify();
2209
+ const updateAttributes = useCallback(
2210
+ async (_key, { arg }) => {
2211
+ if (disabled) {
2212
+ return void 0;
2213
+ }
2214
+ const updatedCart = await updateCartAttributes(client, {
2215
+ ...arg,
2216
+ metafieldIdentifiers,
2217
+ cookieAdapter: cartCookieAdapter
2218
+ });
2219
+ if (updatedCart) {
2220
+ mutate(updatedCart);
2221
+ }
2222
+ return updatedCart;
2223
+ },
2224
+ [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers, disabled]
2225
+ );
2226
+ return useSWRMutation("update-cart-attributes", updateAttributes, swrOptions);
2227
+ }
2228
+ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2229
+ const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
2230
+ const { profile, customer, memberSetting } = useCartContext();
2231
+ const isLoggedIn = userAdapter?.isLoggedIn || false;
2232
+ const buyNow = useCallback(
2233
+ async (_key, { arg }) => {
2234
+ const {
2235
+ lineItems,
2236
+ discountCodes,
2237
+ gtmParams = {},
2238
+ buyerIdentity,
2239
+ fbqTrackConfig,
2240
+ customAttributes,
2241
+ metafieldIdentifiers,
2242
+ redirectToCheckout
2243
+ } = arg;
2244
+ if (!lineItems || lineItems.length === 0) {
2245
+ return;
2246
+ }
2247
+ const { hasPlusMember } = useHasPlusMemberInLines({
2248
+ memberSetting,
2249
+ lines: lineItems
2250
+ });
2251
+ const memberType = hasPlusMember ? "2" : String(profile?.memberType ?? 0);
2252
+ const cartAttributes = getCartAttributes({
2253
+ profile,
2254
+ customer,
2255
+ memberType,
2256
+ currentUrl: window.location.href
2257
+ });
2258
+ const linesWithFunctionAttributes = getLinesWithAttributes({
2259
+ lineItems
2260
+ });
2261
+ const lines = linesWithFunctionAttributes.map((item) => ({
2262
+ merchandiseId: item.variant?.id || "",
2263
+ quantity: item.quantity || 1,
2264
+ attributes: item.attributes,
2265
+ sellingPlanId: item.sellingPlanId
2266
+ })).filter((item) => item.merchandiseId);
2267
+ if (lines.length === 0) {
2268
+ return;
2269
+ }
2270
+ const resultCart = await createCart(client, {
2271
+ lines,
2272
+ metafieldIdentifiers,
2273
+ cookieAdapter: cartCookieAdapter,
2274
+ buyerIdentity,
2275
+ discountCodes,
2276
+ customAttributes: [...cartAttributes, ...customAttributes || []]
2277
+ });
2278
+ if (!resultCart) {
2279
+ throw new Error("Failed to create cart for buy now");
2280
+ }
2281
+ if (withTrack && resultCart.lineItems) {
2282
+ trackBuyNowGA({
2283
+ lineItems,
2284
+ gtmParams: { ...gtmParams, brand: config.getBrand() }
2285
+ });
2286
+ if (fbqTrackConfig) {
2287
+ trackBuyNowFBQ({ trackConfig: fbqTrackConfig });
2377
2288
  }
2378
- brand {
2379
- logo {
2380
- image {
2381
- url
2382
- }
2383
- }
2384
- colors {
2385
- primary {
2386
- background
2387
- }
2388
- secondary {
2389
- background
2390
- }
2289
+ }
2290
+ if (redirectToCheckout) {
2291
+ if (resultCart.url) {
2292
+ if (typeof window !== "undefined") {
2293
+ window.location.href = resultCart.url;
2391
2294
  }
2295
+ } else {
2296
+ throw new Error("Failed to get checkout URL");
2392
2297
  }
2393
- ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2394
2298
  }
2395
- }
2396
- `
2299
+ return resultCart;
2300
+ },
2301
+ [client, locale, isLoggedIn, cartCookieAdapter, withTrack]
2397
2302
  );
2398
- const variables = {};
2399
- if (hasMetafields) {
2400
- variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2401
- }
2402
- const data = await client.query(query, variables);
2403
- if (!data || !data.shop) {
2404
- return void 0;
2405
- }
2406
- const shop = data.shop;
2407
- const metafields = shop.metafields?.reduce((acc, mf) => {
2408
- if (mf && mf.key) {
2409
- acc[mf.key] = mf.value;
2410
- }
2411
- return acc;
2412
- }, {});
2413
- return {
2414
- name: shop.name,
2415
- description: shop.description,
2416
- primaryDomain: shop.primaryDomain,
2417
- brand: shop.brand ? {
2418
- logo: shop.brand.logo,
2419
- colors: shop.brand.colors ? {
2420
- primary: shop.brand.colors.primary?.background,
2421
- secondary: shop.brand.colors.secondary?.background
2422
- } : void 0
2423
- } : void 0,
2424
- metafields
2425
- };
2303
+ return useSWRMutation("buy-now", buyNow, swrOptions);
2426
2304
  }
2427
- function useSite(options = {}) {
2305
+
2306
+ // src/hooks/cart/types/price-discount.ts
2307
+ var PriceDiscountType = /* @__PURE__ */ ((PriceDiscountType2) => {
2308
+ PriceDiscountType2[PriceDiscountType2["PERCENTAGE"] = 1] = "PERCENTAGE";
2309
+ PriceDiscountType2[PriceDiscountType2["FIXED_AMOUNT"] = 2] = "FIXED_AMOUNT";
2310
+ return PriceDiscountType2;
2311
+ })(PriceDiscountType || {});
2312
+ var PriceBasePriceType = /* @__PURE__ */ ((PriceBasePriceType2) => {
2313
+ PriceBasePriceType2[PriceBasePriceType2["MIN_DISCOUNTED_PRICE"] = 1] = "MIN_DISCOUNTED_PRICE";
2314
+ PriceBasePriceType2[PriceBasePriceType2["MIN_TOTAL_PRICE"] = 2] = "MIN_TOTAL_PRICE";
2315
+ return PriceBasePriceType2;
2316
+ })(PriceBasePriceType || {});
2317
+ function useProduct(options = {}) {
2428
2318
  const { client, locale } = useShopify();
2429
- const { metafieldIdentifiers, ...swrOptions } = options;
2319
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2430
2320
  return useSWR(
2431
- ["site", locale, metafieldIdentifiers],
2432
- () => getSiteInfo(client, locale, metafieldIdentifiers),
2321
+ handle ? ["product", locale, handle, metafieldIdentifiers] : null,
2322
+ () => getProduct(client, {
2323
+ handle,
2324
+ locale,
2325
+ metafieldIdentifiers
2326
+ }),
2433
2327
  swrOptions
2434
2328
  );
2435
2329
  }
2436
-
2437
- // src/hooks/member/plus/types.ts
2438
- var PLUS_MEMBER_TYPE = /* @__PURE__ */ ((PLUS_MEMBER_TYPE2) => {
2439
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["FREE"] = 0] = "FREE";
2440
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["MONTHLY"] = 1] = "MONTHLY";
2441
- PLUS_MEMBER_TYPE2[PLUS_MEMBER_TYPE2["ANNUAL"] = 2] = "ANNUAL";
2442
- return PLUS_MEMBER_TYPE2;
2443
- })(PLUS_MEMBER_TYPE || {});
2444
- var PlusMemberMode = /* @__PURE__ */ ((PlusMemberMode2) => {
2445
- PlusMemberMode2["MONTHLY"] = "monthly";
2446
- PlusMemberMode2["ANNUAL"] = "annual";
2447
- return PlusMemberMode2;
2448
- })(PlusMemberMode || {});
2449
- var DeliveryPlusType = /* @__PURE__ */ ((DeliveryPlusType2) => {
2450
- DeliveryPlusType2["FREE"] = "free";
2451
- DeliveryPlusType2["MONTHLY"] = "monthly";
2452
- DeliveryPlusType2["ANNUAL"] = "annual";
2453
- return DeliveryPlusType2;
2454
- })(DeliveryPlusType || {});
2455
- var ShippingMethodMode = /* @__PURE__ */ ((ShippingMethodMode2) => {
2456
- ShippingMethodMode2["FREE"] = "free";
2457
- ShippingMethodMode2["TDD"] = "tdd";
2458
- ShippingMethodMode2["NDD"] = "ndd";
2459
- return ShippingMethodMode2;
2460
- })(ShippingMethodMode || {});
2461
- var createInitialValue = () => ({
2462
- zipCode: "",
2463
- plusMemberMetafields: {},
2464
- setZipCode: () => {
2465
- },
2466
- allowNextDayDelivery: false,
2467
- setAllowNextDayDelivery: () => {
2468
- },
2469
- allowThirdDayDelivery: false,
2470
- setAllowThirdDayDelivery: () => {
2471
- },
2472
- selectedPlusMemberMode: "free",
2473
- setSelectedPlusMemberMode: () => {
2474
- },
2475
- showAreaCheckModal: false,
2476
- setShowAreaCheckModal: () => {
2477
- },
2478
- selectedShippingMethod: void 0,
2479
- setSelectedShippingMethod: () => {
2480
- },
2481
- showTip: false,
2482
- setShowTip: () => {
2483
- },
2484
- showMoreShippingMethod: false,
2485
- setShowMoreShippingMethod: () => {
2486
- },
2487
- variant: {},
2488
- product: {},
2489
- shippingMethodsContext: {
2490
- freeShippingMethods: [],
2491
- paymentShippingMethods: [],
2492
- nddOverweight: false,
2493
- tddOverweight: false,
2494
- nddCoupon: void 0,
2495
- tddCoupon: void 0,
2496
- isLoadingCoupon: false
2497
- },
2498
- selectedPlusMemberVariant: void 0,
2499
- monthlyVariant: void 0,
2500
- annualVariant: void 0,
2501
- showPlusMemberBenefit: false,
2502
- setShowPlusMemberBenefit: () => {
2503
- },
2504
- deleteMarginBottom: false,
2505
- setDeleteMarginBottom: () => {
2506
- },
2507
- profile: void 0,
2508
- locale: void 0
2509
- });
2510
- var PlusMemberContext = createContext(createInitialValue());
2511
- function usePlusMemberContext() {
2512
- return useContext(PlusMemberContext);
2330
+ function useAllProducts(options = {}) {
2331
+ const { client, locale } = useShopify();
2332
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2333
+ return useSWR(
2334
+ ["all-products", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2335
+ () => getAllProducts(client, {
2336
+ locale,
2337
+ first,
2338
+ query,
2339
+ sortKey,
2340
+ reverse,
2341
+ metafieldIdentifiers
2342
+ }),
2343
+ swrOptions
2344
+ );
2513
2345
  }
2514
- function usePlusMemberVariants({
2515
- memberSetting
2346
+ function getFirstAvailableVariant(product) {
2347
+ const availableVariant = product.variants.find((v) => v.availableForSale);
2348
+ return availableVariant || product.variants[0];
2349
+ }
2350
+ function getVariantFromSelectedOptions(product, selectedOptions) {
2351
+ return product.variants.find((variant) => {
2352
+ return variant.selectedOptions.every((option) => {
2353
+ return selectedOptions[option.name] === option.value;
2354
+ });
2355
+ });
2356
+ }
2357
+ function useVariant({
2358
+ product,
2359
+ selectedOptions
2516
2360
  }) {
2517
- const plusMonthly = memberSetting?.plus_monthly_product;
2518
- const plusAnnual = memberSetting?.plus_annual_product;
2519
- const plusMemberHandles = useMemo(() => {
2520
- return [plusMonthly?.handle, plusAnnual?.handle].filter(Boolean);
2521
- }, [plusMonthly?.handle, plusAnnual?.handle]);
2522
- const { data: plusMemberProducts = [] } = useProductsByHandles({
2523
- handles: plusMemberHandles
2361
+ const [variant, setVariant] = useState(
2362
+ product ? getFirstAvailableVariant(product) : void 0
2363
+ );
2364
+ useEffect(() => {
2365
+ if (!product) {
2366
+ setVariant(void 0);
2367
+ return;
2368
+ }
2369
+ const newVariant = getVariantFromSelectedOptions(product, selectedOptions);
2370
+ if (newVariant && newVariant.id !== variant?.id) {
2371
+ setVariant(newVariant);
2372
+ } else if (!newVariant) {
2373
+ setVariant(getFirstAvailableVariant(product));
2374
+ }
2375
+ }, [selectedOptions, product, variant?.id]);
2376
+ return variant;
2377
+ }
2378
+ var FAKE_PRICE = 999999999e-2;
2379
+ function formatPrice({
2380
+ amount,
2381
+ currencyCode,
2382
+ locale,
2383
+ maximumFractionDigits,
2384
+ minimumFractionDigits,
2385
+ removeTrailingZeros
2386
+ }) {
2387
+ const formatter = new Intl.NumberFormat(locale, {
2388
+ style: "currency",
2389
+ currency: currencyCode,
2390
+ maximumFractionDigits: maximumFractionDigits ?? 2,
2391
+ minimumFractionDigits: minimumFractionDigits ?? 2
2524
2392
  });
2525
- const monthlyProduct = useMemo(() => {
2526
- return plusMemberProducts?.find((item) => item?.handle === plusMonthly?.handle);
2527
- }, [plusMemberProducts, plusMonthly]);
2528
- const annualProduct = useMemo(() => {
2529
- return plusMemberProducts?.find((item) => item?.handle === plusAnnual?.handle);
2530
- }, [plusMemberProducts, plusAnnual]);
2531
- const monthlyVariant = useMemo(() => {
2532
- return monthlyProduct?.variants?.find((item) => item.sku === plusMonthly?.sku);
2533
- }, [monthlyProduct, plusMonthly]);
2534
- const annualVariant = useMemo(() => {
2535
- return annualProduct?.variants?.find((item) => item.sku === plusAnnual?.sku);
2536
- }, [annualProduct, plusAnnual]);
2393
+ let formatted = formatter.format(amount);
2394
+ if (removeTrailingZeros) {
2395
+ formatted = formatted.replace(/\.00$/, "");
2396
+ }
2397
+ return formatted;
2398
+ }
2399
+ function formatVariantPrice({
2400
+ amount,
2401
+ baseAmount,
2402
+ currencyCode,
2403
+ locale,
2404
+ maximumFractionDigits,
2405
+ minimumFractionDigits,
2406
+ removeTrailingZeros
2407
+ }) {
2537
2408
  return {
2538
- monthlyVariant: monthlyVariant ? {
2539
- ...monthlyVariant,
2540
- product: monthlyProduct
2541
- } : void 0,
2542
- annualVariant: annualVariant ? {
2543
- ...annualVariant,
2544
- product: annualProduct
2545
- } : void 0
2409
+ price: formatPrice({
2410
+ amount,
2411
+ currencyCode,
2412
+ locale,
2413
+ maximumFractionDigits,
2414
+ minimumFractionDigits,
2415
+ removeTrailingZeros
2416
+ }),
2417
+ basePrice: formatPrice({
2418
+ amount: baseAmount,
2419
+ currencyCode,
2420
+ locale,
2421
+ maximumFractionDigits,
2422
+ minimumFractionDigits,
2423
+ removeTrailingZeros
2424
+ })
2546
2425
  };
2547
2426
  }
2548
- var useAvailableDeliveryCoupon = ({
2549
- profile
2550
- }) => {
2551
- const { data: availableDeliveryCoupon, isLoading } = useSWR(
2552
- profile?.email ? ["/api/multipass/subsrv/v1/prime/delivery_coupons/current/available", profile?.email] : void 0,
2553
- async ([apiPath]) => {
2554
- return fetch(apiPath).then((res) => res.json());
2427
+ function usePrice({
2428
+ amount,
2429
+ baseAmount,
2430
+ currencyCode,
2431
+ soldOutDescription = "",
2432
+ maximumFractionDigits,
2433
+ minimumFractionDigits,
2434
+ removeTrailingZeros
2435
+ }) {
2436
+ const { locale } = useShopify();
2437
+ const value = useMemo(() => {
2438
+ if (typeof amount !== "number" || !currencyCode) {
2439
+ return "";
2555
2440
  }
2556
- );
2557
- console.log("availableDeliveryCoupon", availableDeliveryCoupon);
2558
- const { ndd_coupon: nddCoupon, tdd_coupon: tddCoupon } = availableDeliveryCoupon?.data?.data || {};
2559
- return {
2560
- nddCoupon,
2561
- tddCoupon,
2562
- isLoading
2563
- };
2564
- };
2565
-
2566
- // src/hooks/member/plus/use-shipping-methods.ts
2567
- function useShippingMethods(options) {
2568
- const { variant, plusMemberMetafields, selectedPlusMemberMode, isPlus = false, profile } = options;
2569
- const { nddCoupon, tddCoupon, isLoading } = useAvailableDeliveryCoupon({ profile });
2570
- console.log("nddCoupon", nddCoupon);
2571
- const { plus_shipping, shippingMethod } = plusMemberMetafields || {};
2572
- const nddOverweight = useMemo(() => {
2573
- return (variant?.weight || 0) > (shippingMethod?.overWeight_ndd || Infinity);
2574
- }, [shippingMethod?.overWeight_ndd, variant?.weight]);
2575
- const tddOverweight = useMemo(() => {
2576
- return (variant?.weight || 0) > (shippingMethod?.overWeight_tdd || Infinity);
2577
- }, [shippingMethod?.overWeight_tdd, variant?.weight]);
2578
- const paymentShippingMethods = useMemo(() => {
2579
- const weight = variant?.weight || 0;
2580
- const methods = plus_shipping?.shipping_methods?.filter(({ weight_low, weight_high, __mode, __plus }) => {
2581
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2582
- return __mode !== "free" /* FREE */ && !__plus && fitWeight;
2583
- }) || [];
2584
- return methods.map((method) => {
2585
- let disabled = false;
2586
- const selectedFreeMember = selectedPlusMemberMode === "free";
2587
- if (method.__mode === "ndd" /* NDD */) {
2588
- disabled = selectedFreeMember || nddOverweight;
2589
- } else if (method.__mode === "tdd" /* TDD */) {
2590
- disabled = selectedFreeMember || tddOverweight;
2591
- }
2592
- return {
2593
- ...method,
2594
- id: method.__mode + method.__code,
2595
- useCoupon: false,
2596
- subtitle: plus_shipping?.directly || "",
2597
- disabled
2598
- };
2441
+ if (soldOutDescription && amount >= FAKE_PRICE) {
2442
+ return soldOutDescription;
2443
+ }
2444
+ return baseAmount ? formatVariantPrice({
2445
+ amount,
2446
+ baseAmount,
2447
+ currencyCode,
2448
+ locale,
2449
+ maximumFractionDigits,
2450
+ minimumFractionDigits,
2451
+ removeTrailingZeros
2452
+ }) : formatPrice({
2453
+ amount,
2454
+ currencyCode,
2455
+ locale,
2456
+ maximumFractionDigits,
2457
+ minimumFractionDigits,
2458
+ removeTrailingZeros
2599
2459
  });
2600
2460
  }, [
2601
- nddOverweight,
2602
- plus_shipping?.directly,
2603
- plus_shipping?.shipping_methods,
2604
- selectedPlusMemberMode,
2605
- tddOverweight,
2606
- variant?.weight
2461
+ amount,
2462
+ baseAmount,
2463
+ currencyCode,
2464
+ locale,
2465
+ maximumFractionDigits,
2466
+ minimumFractionDigits,
2467
+ soldOutDescription,
2468
+ removeTrailingZeros
2607
2469
  ]);
2608
- const nddPrice = useMemo(() => {
2609
- const weight = variant?.weight || 0;
2610
- const nddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
2611
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2612
- return __mode === "ndd" && fitWeight;
2613
- });
2614
- return nddMethod?.price || 0;
2615
- }, [variant?.weight, paymentShippingMethods]);
2616
- const tddPrice = useMemo(() => {
2617
- const weight = variant?.weight || 0;
2618
- const tddMethod = paymentShippingMethods.find(({ __mode, weight_high, weight_low }) => {
2619
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2620
- return __mode === "tdd" && fitWeight;
2621
- });
2622
- return tddMethod?.price || 0;
2623
- }, [variant?.weight, paymentShippingMethods]);
2624
- const freeShippingMethods = useMemo(() => {
2625
- const weight = variant?.weight || 0;
2626
- let methods = plus_shipping?.shipping_methods?.filter(({ __mode, __plus, weight_low, weight_high }) => {
2627
- if (__mode === "free" /* FREE */) {
2628
- return true;
2629
- }
2630
- if (isPlus) {
2631
- const hasCoupon = isPlus && __mode === "ndd" /* NDD */ && nddCoupon || isPlus && __mode === "tdd" /* TDD */ && (tddCoupon || nddCoupon);
2632
- const fitWeight = (!weight_low || weight >= weight_low) && (!weight_high || weight <= weight_high);
2633
- return hasCoupon && fitWeight && !__plus;
2634
- } else {
2635
- return __plus;
2636
- }
2637
- }) || [];
2638
- if (isPlus) {
2639
- methods = methods.sort((a, b) => {
2640
- if (b.__mode === "free" /* FREE */) return -1;
2641
- return 0;
2642
- });
2470
+ const result = useMemo(() => {
2471
+ const free = Boolean(amount && amount <= 0);
2472
+ return typeof value === "string" ? { price: value, basePrice: value, free } : { ...value, free };
2473
+ }, [value, amount]);
2474
+ return result;
2475
+ }
2476
+ function optionsConstructor(selectedOptions) {
2477
+ return selectedOptions.reduce((acc, option) => {
2478
+ acc[option.name] = option.value;
2479
+ return acc;
2480
+ }, {});
2481
+ }
2482
+ function decodeShopifyId(gid) {
2483
+ try {
2484
+ const base64 = gid.split("/").pop() || "";
2485
+ return atob(base64);
2486
+ } catch {
2487
+ return gid;
2488
+ }
2489
+ }
2490
+ function useSelectedOptions(product, sku) {
2491
+ const [options, setOptions] = useState({});
2492
+ useEffect(() => {
2493
+ if (!product || !product.variants.length) {
2494
+ setOptions({});
2495
+ return;
2643
2496
  }
2644
- return methods.map((method) => {
2645
- let price = 0;
2646
- let coupon;
2647
- let disabled;
2648
- if (method.__mode !== "free" /* FREE */) {
2649
- switch (method.__mode) {
2650
- case "tdd":
2651
- price = tddPrice;
2652
- coupon = tddCoupon || nddCoupon;
2653
- break;
2654
- case "ndd":
2655
- price = nddPrice;
2656
- coupon = nddCoupon;
2657
- break;
2497
+ let variant = product.variants[0];
2498
+ if (typeof window !== "undefined") {
2499
+ const searchParams = new URLSearchParams(window.location.search);
2500
+ const variantIdParam = searchParams.get("variant");
2501
+ if (variantIdParam) {
2502
+ const foundVariant = product.variants.find((v) => {
2503
+ if (sku) return v.sku === sku;
2504
+ return v.id === variantIdParam || v.id.includes(variantIdParam) || decodeShopifyId(v.id) === variantIdParam;
2505
+ });
2506
+ if (foundVariant) {
2507
+ variant = foundVariant;
2658
2508
  }
2659
- disabled = selectedPlusMemberMode === "free";
2660
- if (method.__mode === "ndd" /* NDD */) {
2661
- disabled = disabled || nddOverweight;
2662
- } else if (method.__mode === "tdd" /* TDD */) {
2663
- disabled = disabled || tddOverweight;
2509
+ }
2510
+ }
2511
+ if (variant) {
2512
+ const newOptions = optionsConstructor(variant.selectedOptions);
2513
+ setOptions(newOptions);
2514
+ }
2515
+ }, [product, sku]);
2516
+ return [options, setOptions];
2517
+ }
2518
+ function decodeShopifyId2(gid) {
2519
+ try {
2520
+ const parts = gid.split("/");
2521
+ return parts[parts.length - 1] || gid;
2522
+ } catch {
2523
+ return gid;
2524
+ }
2525
+ }
2526
+ function useProductUrl(otherQuery) {
2527
+ const { routerAdapter } = useShopify();
2528
+ return useCallback(
2529
+ ({ product, variant }) => {
2530
+ if (!product) return "";
2531
+ const queryParams = new URLSearchParams();
2532
+ if (variant?.id) {
2533
+ const variantId = decodeShopifyId2(variant.id);
2534
+ if (variantId) {
2535
+ queryParams.set("variant", variantId);
2664
2536
  }
2665
2537
  }
2666
- return {
2667
- ...method,
2668
- id: method.__mode + method.__code,
2669
- useCoupon: true,
2670
- disabled,
2671
- coupon,
2672
- price
2673
- };
2674
- });
2675
- }, [
2676
- variant?.weight,
2677
- plus_shipping?.shipping_methods,
2678
- isPlus,
2679
- nddCoupon,
2680
- tddCoupon,
2681
- selectedPlusMemberMode,
2682
- tddPrice,
2683
- nddPrice,
2684
- nddOverweight,
2685
- tddOverweight
2686
- ]);
2687
- return {
2688
- freeShippingMethods,
2689
- paymentShippingMethods,
2690
- nddOverweight,
2691
- tddOverweight,
2692
- nddCoupon,
2693
- tddCoupon,
2694
- isLoadingCoupon: isLoading
2695
- };
2538
+ if (otherQuery) {
2539
+ Object.entries(otherQuery).forEach(([key, value]) => {
2540
+ queryParams.set(key, value);
2541
+ });
2542
+ }
2543
+ const queryString = queryParams.toString();
2544
+ const path = `/products/${product.handle}${queryString ? `?${queryString}` : ""}`;
2545
+ if (routerAdapter?.getLocalizedPath) {
2546
+ return routerAdapter.getLocalizedPath(path);
2547
+ }
2548
+ return path;
2549
+ },
2550
+ [routerAdapter, otherQuery]
2551
+ );
2696
2552
  }
2697
- function useShippingMethodAvailableCheck() {
2698
- const {
2699
- zipCode,
2700
- allowNextDayDelivery,
2701
- allowThirdDayDelivery,
2702
- selectedShippingMethod,
2703
- setSelectedShippingMethod,
2704
- setShowTip,
2705
- shippingMethodsContext
2706
- } = usePlusMemberContext();
2553
+ function decodeShopifyId3(gid) {
2554
+ try {
2555
+ const parts = gid.split("/");
2556
+ return parts[parts.length - 1] || gid;
2557
+ } catch {
2558
+ return gid;
2559
+ }
2560
+ }
2561
+ function useUpdateVariantQuery(variant) {
2707
2562
  useEffect(() => {
2708
- const freeShippingMethod = shippingMethodsContext.freeShippingMethods[0];
2709
- const standardShippingMethod = shippingMethodsContext.freeShippingMethods?.find(
2710
- (item) => item.__mode === "free" /* FREE */
2711
- );
2712
- const freeTDD = shippingMethodsContext.freeShippingMethods.find(
2713
- (item) => item.__mode === "tdd" /* TDD */
2714
- );
2715
- const paymentTDD = shippingMethodsContext.paymentShippingMethods.find(
2716
- (item) => item.__mode === "tdd" /* TDD */
2717
- );
2718
- if (zipCode) {
2719
- console.log(
2720
- "allowNextDayDelivery, allowThirdDayDelivery:",
2721
- allowNextDayDelivery,
2722
- allowThirdDayDelivery
2723
- );
2724
- if (!allowNextDayDelivery && !allowThirdDayDelivery) {
2725
- setShowTip(true);
2726
- setSelectedShippingMethod(standardShippingMethod);
2727
- } else {
2728
- if (selectedShippingMethod?.__mode === "ndd" /* NDD */ && !allowNextDayDelivery) {
2729
- setShowTip(true);
2730
- if (allowThirdDayDelivery) {
2731
- if (selectedShippingMethod.useCoupon) {
2732
- const method = freeTDD || freeShippingMethod;
2733
- if (method) setSelectedShippingMethod(method);
2734
- } else {
2735
- const method = paymentTDD || freeShippingMethod;
2736
- if (method) setSelectedShippingMethod(method);
2737
- }
2738
- } else {
2739
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2740
- }
2741
- } else if (
2742
- // TDD 无法使用
2743
- selectedShippingMethod?.__mode === "tdd" /* TDD */ && !allowThirdDayDelivery
2744
- ) {
2745
- setShowTip(true);
2746
- if (freeShippingMethod) setSelectedShippingMethod(freeShippingMethod);
2747
- }
2563
+ if (!variant || typeof window === "undefined") {
2564
+ return;
2565
+ }
2566
+ const searchParams = new URLSearchParams(window.location.search);
2567
+ const currentVariantId = searchParams.get("variant");
2568
+ const newVariantId = decodeShopifyId3(variant.id);
2569
+ if (newVariantId && currentVariantId !== newVariantId) {
2570
+ searchParams.set("variant", newVariantId);
2571
+ const newUrl = `${window.location.pathname}?${searchParams.toString()}${window.location.hash}`;
2572
+ window.history.replaceState({}, "", newUrl);
2573
+ }
2574
+ }, [variant]);
2575
+ }
2576
+ function getVariantMediaList({
2577
+ product,
2578
+ variant
2579
+ }) {
2580
+ if (variant.image?.url) {
2581
+ const variantMediaId = variant.image.url;
2582
+ const variantMedia = product.media.filter((media) => {
2583
+ if (media.mediaContentType === "IMAGE" && media.previewImage) {
2584
+ return media.previewImage?.url === variantMediaId;
2748
2585
  }
2586
+ return false;
2587
+ });
2588
+ if (variantMedia.length > 0) {
2589
+ const otherMedia = product.media.filter((media) => {
2590
+ if (media.mediaContentType === "IMAGE" && media.previewImage) {
2591
+ return media.previewImage.url !== variantMediaId;
2592
+ }
2593
+ return true;
2594
+ });
2595
+ return [...variantMedia, ...otherMedia];
2749
2596
  }
2750
- }, [
2751
- allowNextDayDelivery,
2752
- allowThirdDayDelivery,
2753
- zipCode,
2754
- shippingMethodsContext,
2755
- selectedShippingMethod,
2756
- setSelectedShippingMethod,
2757
- setShowTip
2758
- ]);
2597
+ }
2598
+ return product.media;
2759
2599
  }
2760
- var useReplaceCartPlusMember = () => {
2761
- const { plusMemberMetafields, selectedPlusMemberMode } = usePlusMemberContext();
2762
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2763
- const { cart } = useCartContext();
2764
- const plusMonthly = plusMemberMetafields?.plus_monthly_product;
2765
- const plusAnnual = plusMemberMetafields?.plus_annual_product;
2766
- const handler = useCallback(async () => {
2767
- const plusMonthlyInCart = cart?.lineItems.find(
2768
- (item) => item.variant?.sku === plusMonthly?.sku
2769
- );
2770
- const plusAnnualInCart = cart?.lineItems.find(
2771
- (item) => item.variant?.sku === plusAnnual?.sku
2772
- );
2773
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && plusMonthlyInCart) {
2774
- await removeCartLines2({
2775
- lineIds: [plusMonthlyInCart.id]
2776
- });
2777
- } else if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && plusAnnualInCart) {
2778
- await removeCartLines2({
2779
- lineIds: [plusAnnualInCart.id]
2780
- });
2600
+ function useVariantMedia({
2601
+ product,
2602
+ variant
2603
+ }) {
2604
+ const [imageList, setImageList] = useState([]);
2605
+ const [sceneList, setSceneList] = useState([]);
2606
+ const [videoList, setVideoList] = useState([]);
2607
+ useEffect(() => {
2608
+ if (!product || !variant) {
2609
+ setImageList([]);
2610
+ setSceneList([]);
2611
+ setVideoList([]);
2612
+ return;
2781
2613
  }
2782
- }, [
2783
- cart?.lineItems,
2784
- selectedPlusMemberMode,
2785
- plusMonthly?.sku,
2786
- plusAnnual?.sku,
2787
- removeCartLines2
2788
- ]);
2789
- return handler;
2790
- };
2791
- var usePlusMemberDeliveryCodes = ({
2792
- deliveryData
2793
- }) => {
2794
- return useMemo(
2795
- () => deliveryData?.deliveryCustomData?.discount_code,
2796
- [deliveryData]
2614
+ const mediaList = getVariantMediaList({ product, variant });
2615
+ const images = mediaList.filter((media) => media.mediaContentType === "IMAGE");
2616
+ const videos = mediaList.filter(
2617
+ (media) => media.mediaContentType === "VIDEO" || media.mediaContentType === "EXTERNAL_VIDEO"
2618
+ );
2619
+ setImageList(images.length > 0 && images[0] ? [images[0]] : []);
2620
+ setSceneList(images.length > 1 ? images.slice(1) : []);
2621
+ setVideoList(videos);
2622
+ }, [product, variant]);
2623
+ return {
2624
+ productList: imageList,
2625
+ sceneList,
2626
+ videoList
2627
+ };
2628
+ }
2629
+ function useCollection(options = {}) {
2630
+ const { client, locale } = useShopify();
2631
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2632
+ return useSWR(
2633
+ handle ? ["collection", locale, handle, metafieldIdentifiers] : null,
2634
+ () => getCollection(client, {
2635
+ handle,
2636
+ locale,
2637
+ metafieldIdentifiers
2638
+ }),
2639
+ swrOptions
2797
2640
  );
2798
- };
2799
- function useUpdateCartDeliveryOptions(mutate, metafieldIdentifiers, options) {
2800
- const { client, locale, cartCookieAdapter } = useShopify();
2801
- const updateDeliveryOptions = useCallback(
2802
- async (_key, { arg }) => {
2803
- const updatedCart = await updateCartDeliveryOptions(client, {
2804
- ...arg,
2805
- metafieldIdentifiers,
2806
- cookieAdapter: cartCookieAdapter
2807
- });
2808
- console.log("useUpdateCartDeliveryOptions updatedCart", updatedCart);
2809
- if (updatedCart) {
2810
- mutate(updatedCart);
2811
- }
2812
- return updatedCart;
2813
- },
2814
- [client, locale, cartCookieAdapter, mutate, metafieldIdentifiers]
2641
+ }
2642
+ function useAllCollections(options = {}) {
2643
+ const { client, locale } = useShopify();
2644
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2645
+ return useSWR(
2646
+ ["all-collections", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2647
+ () => getAllCollections(client, {
2648
+ locale,
2649
+ first,
2650
+ query,
2651
+ sortKey,
2652
+ reverse,
2653
+ metafieldIdentifiers
2654
+ }),
2655
+ swrOptions
2815
2656
  );
2816
- return useSWRMutation("update-cart-delivery-options", updateDeliveryOptions, options);
2817
2657
  }
2818
-
2819
- // src/hooks/member/plus/use-update-plus-member-delivery-options.ts
2820
- var useUpdatePlusMemberDeliveryOptions = ({
2821
- options
2822
- } = {}) => {
2823
- const { cart: cartContextData, mutateCart, metafieldIdentifiers } = useCartContext();
2824
- const { trigger: updateCartDeliveryOptions2 } = useUpdateCartDeliveryOptions(
2825
- mutateCart,
2826
- metafieldIdentifiers
2658
+ function useCollections(options = {}) {
2659
+ const { client, locale } = useShopify();
2660
+ const { first, after, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2661
+ return useSWR(
2662
+ ["collections", locale, first, after, query, sortKey, reverse, metafieldIdentifiers],
2663
+ () => getCollections(client, {
2664
+ locale,
2665
+ first,
2666
+ after,
2667
+ query,
2668
+ sortKey,
2669
+ reverse,
2670
+ metafieldIdentifiers
2671
+ }),
2672
+ swrOptions
2827
2673
  );
2828
- const handler = useCallback(
2829
- async (_, { arg }) => {
2830
- const currentCart = arg?.cart || cartContextData;
2831
- const { deliveryData } = arg;
2832
- const firstDeliveryGroup = currentCart?.deliveryGroups?.[0];
2833
- const deliveryGroupId = firstDeliveryGroup?.id;
2834
- const selectedOptionCode = deliveryData?.deliveryCustomData?.selected_delivery_option?.code;
2835
- if (!deliveryGroupId || !selectedOptionCode || selectedOptionCode === firstDeliveryGroup?.selectedDeliveryOption?.code) {
2836
- return null;
2837
- }
2838
- const deliveryGroup = currentCart?.deliveryGroups?.find(
2839
- (group) => group?.id === deliveryGroupId
2840
- );
2841
- const matchedOption = deliveryGroup?.deliveryOptions?.find(
2842
- (option) => option?.code === selectedOptionCode
2843
- );
2844
- if (!matchedOption?.handle) {
2845
- return null;
2846
- }
2847
- const deliveryOptions = [
2848
- {
2849
- deliveryGroupId,
2850
- deliveryOptionHandle: matchedOption.handle
2674
+ }
2675
+ function useBlog(options = {}) {
2676
+ const { client, locale } = useShopify();
2677
+ const { handle, metafieldIdentifiers, ...swrOptions } = options;
2678
+ return useSWR(
2679
+ handle ? ["blog", locale, handle, metafieldIdentifiers] : null,
2680
+ () => getBlog(client, { handle, locale, metafieldIdentifiers }),
2681
+ swrOptions
2682
+ );
2683
+ }
2684
+ function useAllBlogs(options = {}) {
2685
+ const { client, locale } = useShopify();
2686
+ const { first, query, metafieldIdentifiers, ...swrOptions } = options;
2687
+ return useSWR(
2688
+ ["all-blogs", locale, first, query, metafieldIdentifiers],
2689
+ () => getAllBlogs(client, {
2690
+ locale,
2691
+ first,
2692
+ query,
2693
+ metafieldIdentifiers
2694
+ }),
2695
+ swrOptions
2696
+ );
2697
+ }
2698
+ function useArticle(options = {}) {
2699
+ const { client, locale } = useShopify();
2700
+ const { blogHandle, articleHandle, metafieldIdentifiers, ...swrOptions } = options;
2701
+ return useSWR(
2702
+ blogHandle && articleHandle ? ["article", locale, blogHandle, articleHandle, metafieldIdentifiers] : null,
2703
+ () => getArticle(client, {
2704
+ blogHandle,
2705
+ articleHandle,
2706
+ locale,
2707
+ metafieldIdentifiers
2708
+ }),
2709
+ swrOptions
2710
+ );
2711
+ }
2712
+ function useArticles(options = {}) {
2713
+ const { client, locale } = useShopify();
2714
+ const { first, query, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2715
+ return useSWR(
2716
+ ["articles", locale, first, query, sortKey, reverse, metafieldIdentifiers],
2717
+ () => getArticles(client, {
2718
+ locale,
2719
+ first,
2720
+ query,
2721
+ sortKey,
2722
+ reverse,
2723
+ metafieldIdentifiers
2724
+ }),
2725
+ swrOptions
2726
+ );
2727
+ }
2728
+ function useArticlesInBlog(options = {}) {
2729
+ const { client, locale } = useShopify();
2730
+ const { blogHandle, first, sortKey, reverse, metafieldIdentifiers, ...swrOptions } = options;
2731
+ return useSWR(
2732
+ blogHandle ? ["articles-in-blog", locale, blogHandle, first, sortKey, reverse, metafieldIdentifiers] : null,
2733
+ () => getArticlesInBlog(client, {
2734
+ blogHandle,
2735
+ locale,
2736
+ first,
2737
+ sortKey,
2738
+ reverse,
2739
+ metafieldIdentifiers
2740
+ }),
2741
+ swrOptions
2742
+ );
2743
+ }
2744
+ async function performSearch(client, locale, searchQuery, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"]) {
2745
+ if (!searchQuery) {
2746
+ return void 0;
2747
+ }
2748
+ const query = (
2749
+ /* GraphQL */
2750
+ `
2751
+ query search($query: String!, $first: Int!, $types: [SearchType!])
2752
+ @inContext(language: $language) {
2753
+ search(query: $query, first: $first, types: $types, unavailableProducts: HIDE) {
2754
+ totalCount
2755
+ edges {
2756
+ node {
2757
+ ... on Article {
2758
+ __typename
2759
+ id
2760
+ handle
2761
+ title
2762
+ excerpt
2763
+ image {
2764
+ url
2765
+ altText
2766
+ }
2767
+ }
2768
+ ... on Page {
2769
+ __typename
2770
+ id
2771
+ handle
2772
+ title
2773
+ }
2774
+ ... on Product {
2775
+ __typename
2776
+ id
2777
+ handle
2778
+ title
2779
+ description
2780
+ featuredImage {
2781
+ url
2782
+ altText
2783
+ }
2784
+ }
2785
+ }
2786
+ }
2787
+ pageInfo {
2788
+ hasNextPage
2789
+ endCursor
2851
2790
  }
2852
- ];
2853
- const updatedCart = await updateCartDeliveryOptions2({
2854
- selectedDeliveryOptions: deliveryOptions,
2855
- cartId: currentCart?.id
2856
- });
2857
- if (updatedCart && mutateCart) {
2858
- mutateCart(updatedCart);
2859
- }
2860
- return updatedCart;
2861
- },
2862
- [cartContextData, updateCartDeliveryOptions2, mutateCart]
2863
- );
2864
- return useSWRMutation("update-cart-delivery-options", handler, options);
2865
- };
2866
- var usePlusMemberItemCustomAttributes = ({
2867
- deliveryData
2868
- }) => {
2869
- const { deliveryCustomData } = deliveryData || {};
2870
- return useMemo(() => {
2871
- const itemCustomAttributes = [];
2872
- if (deliveryCustomData?.is_presale) {
2873
- itemCustomAttributes.push({
2874
- key: "_is_presale",
2875
- value: "true"
2876
- });
2877
- }
2878
- return itemCustomAttributes;
2879
- }, [deliveryCustomData]);
2880
- };
2881
- var usePlusMemberCheckoutCustomAttributes = ({
2882
- deliveryData,
2883
- product,
2884
- variant,
2885
- isShowShippingBenefits
2886
- }) => {
2887
- const { deliveryCustomData } = deliveryData || {};
2888
- const { profile } = usePlusMemberContext();
2889
- return useMemo(() => {
2890
- const checkoutCustomAttributes = [
2891
- // _last_url: 付费会员结算完成之后 checkout 有一个继续购买的按钮, 用于跳转到继续购买的页面
2892
- {
2893
- key: "_last_url",
2894
- value: typeof window !== "undefined" ? window.location.origin + window.location.pathname : ""
2895
- }
2896
- ];
2897
- if (deliveryCustomData) {
2898
- checkoutCustomAttributes.push({
2899
- key: "_checkout_delivery_custom",
2900
- value: JSON.stringify({
2901
- ...deliveryCustomData,
2902
- is_prime: profile?.isPlus
2903
- })
2904
- });
2905
- }
2906
- if (isShowShippingBenefits && !isShowShippingBenefits({ variant, product, setting: {} })) {
2907
- checkoutCustomAttributes.push({
2908
- key: "_hide_shipping",
2909
- value: "true"
2910
- });
2911
- }
2912
- return checkoutCustomAttributes;
2913
- }, [deliveryCustomData, product, profile, variant, isShowShippingBenefits]);
2914
- };
2915
- function useAutoRemovePlusMemberInCart({
2916
- cart,
2917
- profile,
2918
- memberSetting
2919
- }) {
2920
- const { plus_monthly_product, plus_annual_product } = memberSetting || {};
2921
- const { trigger: removeCartLines2 } = useRemoveCartLines();
2922
- useEffect(() => {
2923
- if (!cart || !plus_monthly_product || !plus_annual_product) return;
2924
- const removePlusProduct = async (productType) => {
2925
- if (!productType) return;
2926
- const product = cart.lineItems?.find(
2927
- (item) => item.product?.handle === productType?.handle && item.variant?.sku === productType?.sku
2928
- );
2929
- if (product) {
2930
- await removeCartLines2({
2931
- lineIds: [product.id]
2932
- });
2933
2791
  }
2934
- };
2935
- if (profile?.isMonthlyPlus) {
2936
- removePlusProduct(plus_monthly_product);
2937
- }
2938
- if (profile?.isAnnualPlus) {
2939
- removePlusProduct(plus_annual_product);
2940
2792
  }
2941
- }, [cart, plus_annual_product, plus_monthly_product, profile, removeCartLines2]);
2942
- }
2943
- function usePlusMemberNeedAddToCart({
2944
- cart,
2945
- profile
2946
- }) {
2947
- const { selectedPlusMemberMode, selectedPlusMemberVariant, plusMemberMetafields } = usePlusMemberContext();
2948
- const { hasMonthlyPlus, hasAnnualPlus } = useHasPlusMemberInCart({
2949
- memberSetting: plusMemberMetafields,
2950
- cart
2793
+ `
2794
+ );
2795
+ const data = await client.query(query, {
2796
+ query: searchQuery,
2797
+ first,
2798
+ types
2951
2799
  });
2952
- const plusMemberVariant = useMemo(() => {
2953
- if (!selectedPlusMemberVariant || selectedPlusMemberMode === "free" /* FREE */) {
2954
- return void 0;
2955
- }
2956
- if (selectedPlusMemberMode === "monthly" /* MONTHLY */ && hasMonthlyPlus) {
2957
- return void 0;
2958
- }
2959
- if (selectedPlusMemberMode === "annual" /* ANNUAL */ && hasAnnualPlus) {
2960
- return void 0;
2961
- }
2962
- if (profile?.isMonthlyPlus && selectedPlusMemberMode === "monthly" /* MONTHLY */) {
2963
- return void 0;
2964
- }
2965
- if (profile?.isAnnualPlus && selectedPlusMemberMode === "annual" /* ANNUAL */) {
2966
- return void 0;
2800
+ if (!data || !data.search) {
2801
+ return void 0;
2802
+ }
2803
+ const items = data.search.edges?.map((edge) => {
2804
+ const node = edge.node;
2805
+ const item = {
2806
+ type: node.__typename.toUpperCase(),
2807
+ id: node.id,
2808
+ handle: node.handle,
2809
+ title: node.title
2810
+ };
2811
+ if (node.__typename === "Product") {
2812
+ item.description = node.description;
2813
+ item.image = node.featuredImage ? {
2814
+ url: node.featuredImage.url,
2815
+ altText: node.featuredImage.altText
2816
+ } : void 0;
2817
+ } else if (node.__typename === "Article") {
2818
+ item.description = node.excerpt;
2819
+ item.image = node.image ? {
2820
+ url: node.image.url,
2821
+ altText: node.image.altText
2822
+ } : void 0;
2967
2823
  }
2968
- return selectedPlusMemberVariant;
2969
- }, [selectedPlusMemberMode, selectedPlusMemberVariant, hasMonthlyPlus, hasAnnualPlus]);
2970
- return plusMemberVariant;
2824
+ return item;
2825
+ }) || [];
2826
+ return {
2827
+ items,
2828
+ totalCount: data.search.totalCount || 0,
2829
+ pageInfo: data.search.pageInfo
2830
+ };
2971
2831
  }
2972
- var PlusMemberProvider = ({
2973
- variant,
2974
- product,
2975
- memberSetting,
2976
- initialSelectedPlusMemberMode = "free",
2977
- profile,
2978
- children
2979
- }) => {
2980
- const { locale } = useShopify();
2981
- const [zipCode, setZipCode] = useState("");
2982
- const [showTip, setShowTip] = useState(false);
2983
- const [selectedPlusMemberMode, setSelectedPlusMemberMode] = useState(
2984
- initialSelectedPlusMemberMode
2832
+ function useSearch(options = {}) {
2833
+ const { client, locale } = useShopify();
2834
+ const { query, first = 20, types = ["PRODUCT", "ARTICLE", "PAGE"], ...swrOptions } = options;
2835
+ return useSWR(
2836
+ query ? ["search", locale, query, first, types] : null,
2837
+ () => performSearch(client, locale, query, first, types),
2838
+ swrOptions
2985
2839
  );
2986
- const [selectedShippingMethod, setSelectedShippingMethod] = useState();
2987
- const [allowNextDayDelivery, setAllowNextDayDelivery] = useState(false);
2988
- const [allowThirdDayDelivery, setAllowThirdDayDelivery] = useState(false);
2989
- const [showAreaCheckModal, setShowAreaCheckModal] = useState(false);
2990
- const [showMoreShippingMethod, setShowMoreShippingMethod] = useState(false);
2991
- const [showPlusMemberBenefit, setShowPlusMemberBenefit] = useState(false);
2992
- const [deleteMarginBottom, setDeleteMarginBottom] = useState(false);
2993
- const shippingMethodsContext = useShippingMethods({
2994
- variant,
2995
- plusMemberMetafields: memberSetting,
2996
- selectedPlusMemberMode,
2997
- profile,
2998
- isPlus: profile?.isPlus || false
2999
- });
3000
- const { monthlyVariant, annualVariant } = usePlusMemberVariants({
3001
- memberSetting
3002
- });
3003
- const selectedPlusMemberVariant = useMemo(() => {
3004
- if (selectedPlusMemberMode === "free" /* FREE */) {
3005
- return void 0;
2840
+ }
2841
+ async function getSiteInfo(client, locale, metafieldIdentifiers) {
2842
+ const hasMetafields = metafieldIdentifiers && metafieldIdentifiers.length > 0;
2843
+ const query = (
2844
+ /* GraphQL */
2845
+ `
2846
+ query getSiteInfo(
2847
+ ${hasMetafields ? "$shopMetafieldIdentifiers: [HasMetafieldsIdentifier!]!" : ""}
2848
+ ) @inContext(language: $language) {
2849
+ shop {
2850
+ name
2851
+ description
2852
+ primaryDomain {
2853
+ url
2854
+ host
2855
+ }
2856
+ brand {
2857
+ logo {
2858
+ image {
2859
+ url
2860
+ }
2861
+ }
2862
+ colors {
2863
+ primary {
2864
+ background
2865
+ }
2866
+ secondary {
2867
+ background
2868
+ }
2869
+ }
2870
+ }
2871
+ ${hasMetafields ? "metafields(identifiers: $shopMetafieldIdentifiers) { key value }" : ""}
2872
+ }
3006
2873
  }
3007
- return selectedPlusMemberMode === "monthly" /* MONTHLY */ ? monthlyVariant : annualVariant;
3008
- }, [monthlyVariant, annualVariant, selectedPlusMemberMode]);
3009
- return /* @__PURE__ */ jsx(
3010
- PlusMemberContext.Provider,
3011
- {
3012
- value: {
3013
- variant,
3014
- zipCode,
3015
- setZipCode,
3016
- allowNextDayDelivery,
3017
- setAllowNextDayDelivery,
3018
- allowThirdDayDelivery,
3019
- setAllowThirdDayDelivery,
3020
- plusMemberMetafields: memberSetting,
3021
- selectedPlusMemberMode,
3022
- setSelectedPlusMemberMode,
3023
- showAreaCheckModal,
3024
- setShowAreaCheckModal,
3025
- selectedShippingMethod,
3026
- setSelectedShippingMethod,
3027
- shippingMethodsContext,
3028
- showTip,
3029
- setShowTip,
3030
- showMoreShippingMethod,
3031
- setShowMoreShippingMethod,
3032
- selectedPlusMemberVariant,
3033
- monthlyVariant,
3034
- annualVariant,
3035
- product,
3036
- showPlusMemberBenefit,
3037
- setShowPlusMemberBenefit,
3038
- deleteMarginBottom,
3039
- setDeleteMarginBottom,
3040
- profile,
3041
- locale
3042
- },
3043
- children
2874
+ `
2875
+ );
2876
+ const variables = {};
2877
+ if (hasMetafields) {
2878
+ variables.shopMetafieldIdentifiers = metafieldIdentifiers;
2879
+ }
2880
+ const data = await client.query(query, variables);
2881
+ if (!data || !data.shop) {
2882
+ return void 0;
2883
+ }
2884
+ const shop = data.shop;
2885
+ const metafields = shop.metafields?.reduce((acc, mf) => {
2886
+ if (mf && mf.key) {
2887
+ acc[mf.key] = mf.value;
3044
2888
  }
2889
+ return acc;
2890
+ }, {});
2891
+ return {
2892
+ name: shop.name,
2893
+ description: shop.description,
2894
+ primaryDomain: shop.primaryDomain,
2895
+ brand: shop.brand ? {
2896
+ logo: shop.brand.logo,
2897
+ colors: shop.brand.colors ? {
2898
+ primary: shop.brand.colors.primary?.background,
2899
+ secondary: shop.brand.colors.secondary?.background
2900
+ } : void 0
2901
+ } : void 0,
2902
+ metafields
2903
+ };
2904
+ }
2905
+ function useSite(options = {}) {
2906
+ const { client, locale } = useShopify();
2907
+ const { metafieldIdentifiers, ...swrOptions } = options;
2908
+ return useSWR(
2909
+ ["site", locale, metafieldIdentifiers],
2910
+ () => getSiteInfo(client, locale, metafieldIdentifiers),
2911
+ swrOptions
3045
2912
  );
3046
- };
2913
+ }
3047
2914
  function useIntersection(targetRef, options) {
3048
2915
  const {
3049
2916
  callback,
@@ -3224,6 +3091,6 @@ function clearGeoLocationCache(cacheKey = "geoLocation") {
3224
3091
  }
3225
3092
  }
3226
3093
 
3227
- export { BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, DeliveryPlusType, MAIN_PRODUCT_CODE, MEMBER_PRICE_ATTRIBUTE_KEY, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, SpendMoneyType, checkAttributesUpdateNeeded, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, getCachedGeoLocation, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, normalizeAddToCartLines, preCheck, safeParse, useAddCartLines, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useAvailableDeliveryCoupon, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useIntersection, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberDeliveryCodes, usePlusMemberItemCustomAttributes, usePlusMemberNeedAddToCart, usePlusMemberVariants, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethodAvailableCheck, useShippingMethods, useSite, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdatePlusMemberDeliveryOptions, useUpdateVariantQuery, useVariant, useVariantMedia };
3094
+ export { BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, DeliveryPlusType, MAIN_PRODUCT_CODE, MEMBER_PRICE_ATTRIBUTE_KEY, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, SpendMoneyType, checkAttributesUpdateNeeded, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, getCachedGeoLocation, getCartAttributes, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, getUserType, hasPlusMemberInCart, hasPlusMemberInLines, normalizeAddToCartLines, preCheck, safeParse, useAddCartLines, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useAvailableDeliveryCoupon, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useHasPlusMemberInLines, useIntersection, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberNeedAddToCart, usePlusMemberVariants, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethods, useSite, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdateVariantQuery, useVariant, useVariantMedia };
3228
3095
  //# sourceMappingURL=index.mjs.map
3229
3096
  //# sourceMappingURL=index.mjs.map