@atomic-solutions/woocommerce-react 0.5.0 → 0.6.1

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.
@@ -195,6 +195,13 @@ var useCart = (options) => {
195
195
  getQuantity
196
196
  };
197
197
  };
198
+ var toWooError = (error) => error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
199
+ code: "unknown_error",
200
+ message: error instanceof Error ? error.message : "Unknown error",
201
+ url: "",
202
+ method: "POST",
203
+ originalCode: "unknown_error"
204
+ });
198
205
  var useAddToCart = () => {
199
206
  const client = useWooCommerceClient();
200
207
  const queryKeys = useWooCommerceQueryKeys();
@@ -213,15 +220,50 @@ var useAddToCart = () => {
213
220
  },
214
221
  onError: (error) => {
215
222
  if (emitEvent) {
216
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
217
- code: "unknown_error",
218
- message: error instanceof Error ? error.message : "Unknown error",
219
- statusCode: 500,
220
- url: "",
221
- method: "POST",
222
- originalCode: "unknown_error"
223
- });
224
- emitEvent(createErrorEvent("cart:item_added", wooError));
223
+ emitEvent(createErrorEvent("cart:item_added", toWooError(error)));
224
+ }
225
+ }
226
+ });
227
+ };
228
+ var useAddManyToCart = () => {
229
+ const client = useWooCommerceClient();
230
+ const queryKeys = useWooCommerceQueryKeys();
231
+ const queryClient = reactQuery.useQueryClient();
232
+ const emitEvent = useEventEmitter();
233
+ return reactQuery.useMutation({
234
+ mutationKey: queryKeys.cart.mutations.addItems(),
235
+ mutationFn: (input) => client.cart.addItems(input),
236
+ onSuccess: ({ cart, results }) => {
237
+ queryClient.setQueryData(queryKeys.cart.details(), cart);
238
+ queryClient.invalidateQueries({ queryKey: queryKeys.cart.all });
239
+ if (!emitEvent) return;
240
+ results.forEach((result) => {
241
+ if (result.status >= 200 && result.status < 300) {
242
+ const addedItem = cart.items.find((item) => item.id === result.item.id);
243
+ if (addedItem) {
244
+ emitEvent(createSuccessEvent("cart:item_added", { item: addedItem, cart }));
245
+ }
246
+ return;
247
+ }
248
+ emitEvent(
249
+ createErrorEvent(
250
+ "cart:item_added",
251
+ new woocommerceApiClient.WooCommerceApiError({
252
+ code: woocommerceApiClient.mapWooCommerceCode(result.code),
253
+ originalCode: result.code ?? "unknown_error",
254
+ message: result.message ?? "Failed to add item to cart",
255
+ statusCode: result.status,
256
+ url: "",
257
+ method: "POST",
258
+ requestBody: result.item
259
+ })
260
+ )
261
+ );
262
+ });
263
+ },
264
+ onError: (error) => {
265
+ if (emitEvent) {
266
+ emitEvent(createErrorEvent("cart:item_added", toWooError(error)));
225
267
  }
226
268
  }
227
269
  });
@@ -244,15 +286,7 @@ var useUpdateCartItem = () => {
244
286
  },
245
287
  onError: (error) => {
246
288
  if (emitEvent) {
247
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
248
- code: "unknown_error",
249
- message: error instanceof Error ? error.message : "Unknown error",
250
- statusCode: 500,
251
- url: "",
252
- method: "POST",
253
- originalCode: "unknown_error"
254
- });
255
- emitEvent(createErrorEvent("cart:item_updated", wooError));
289
+ emitEvent(createErrorEvent("cart:item_updated", toWooError(error)));
256
290
  }
257
291
  }
258
292
  });
@@ -274,15 +308,7 @@ var useRemoveFromCart = () => {
274
308
  },
275
309
  onError: (error) => {
276
310
  if (emitEvent) {
277
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
278
- code: "unknown_error",
279
- message: error instanceof Error ? error.message : "Unknown error",
280
- statusCode: 500,
281
- url: "",
282
- method: "POST",
283
- originalCode: "unknown_error"
284
- });
285
- emitEvent(createErrorEvent("cart:item_removed", wooError));
311
+ emitEvent(createErrorEvent("cart:item_removed", toWooError(error)));
286
312
  }
287
313
  }
288
314
  });
@@ -304,15 +330,7 @@ var useApplyCoupon = () => {
304
330
  },
305
331
  onError: (error) => {
306
332
  if (emitEvent) {
307
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
308
- code: "unknown_error",
309
- message: error instanceof Error ? error.message : "Unknown error",
310
- statusCode: 500,
311
- url: "",
312
- method: "POST",
313
- originalCode: "unknown_error"
314
- });
315
- emitEvent(createErrorEvent("cart:coupon_applied", wooError));
333
+ emitEvent(createErrorEvent("cart:coupon_applied", toWooError(error)));
316
334
  }
317
335
  }
318
336
  });
@@ -334,15 +352,7 @@ var useRemoveCoupon = () => {
334
352
  },
335
353
  onError: (error) => {
336
354
  if (emitEvent) {
337
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
338
- code: "unknown_error",
339
- message: error instanceof Error ? error.message : "Unknown error",
340
- statusCode: 500,
341
- url: "",
342
- method: "POST",
343
- originalCode: "unknown_error"
344
- });
345
- emitEvent(createErrorEvent("cart:coupon_removed", wooError));
355
+ emitEvent(createErrorEvent("cart:coupon_removed", toWooError(error)));
346
356
  }
347
357
  }
348
358
  });
@@ -364,15 +374,7 @@ var useUpdateCustomer = () => {
364
374
  },
365
375
  onError: (error) => {
366
376
  if (emitEvent) {
367
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
368
- code: "unknown_error",
369
- message: error instanceof Error ? error.message : "Unknown error",
370
- statusCode: 500,
371
- url: "",
372
- method: "POST",
373
- originalCode: "unknown_error"
374
- });
375
- emitEvent(createErrorEvent("cart:customer_updated", wooError));
377
+ emitEvent(createErrorEvent("cart:customer_updated", toWooError(error)));
376
378
  }
377
379
  }
378
380
  });
@@ -394,15 +396,7 @@ var useSelectShippingRate = () => {
394
396
  },
395
397
  onError: (error) => {
396
398
  if (emitEvent) {
397
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
398
- code: "unknown_error",
399
- message: error instanceof Error ? error.message : "Unknown error",
400
- statusCode: 500,
401
- url: "",
402
- method: "POST",
403
- originalCode: "unknown_error"
404
- });
405
- emitEvent(createErrorEvent("cart:shipping_selected", wooError));
399
+ emitEvent(createErrorEvent("cart:shipping_selected", toWooError(error)));
406
400
  }
407
401
  }
408
402
  });
@@ -438,7 +432,6 @@ var useProcessCheckout = () => {
438
432
  const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
439
433
  code: "unknown_error",
440
434
  message: error instanceof Error ? error.message : "Unknown error",
441
- statusCode: 500,
442
435
  url: "",
443
436
  method: "POST",
444
437
  originalCode: "unknown_error"
@@ -479,6 +472,7 @@ var createQueryKeys = (prefix = ["woocommerce"]) => ({
479
472
  // Mutation keys
480
473
  mutations: {
481
474
  addItem: () => [...prefix, "cart", "mutation", "addItem"],
475
+ addItems: () => [...prefix, "cart", "mutation", "addItems"],
482
476
  updateItem: () => [...prefix, "cart", "mutation", "updateItem"],
483
477
  removeItem: () => [...prefix, "cart", "mutation", "removeItem"],
484
478
  applyCoupon: () => [...prefix, "cart", "mutation", "applyCoupon"],
@@ -699,6 +693,15 @@ function isPurchasable(status, quantity, manageStock = true) {
699
693
  }
700
694
  return true;
701
695
  }
696
+ function unavailableReason(product) {
697
+ if (!product.is_in_stock || product.is_on_backorder || product.add_to_cart.maximum <= 0) {
698
+ return "out_of_stock";
699
+ }
700
+ if (!product.is_purchasable) {
701
+ return "not_purchasable";
702
+ }
703
+ return void 0;
704
+ }
702
705
  function isLowStock(status, quantity, threshold = 5) {
703
706
  return status === "instock" && quantity !== null && quantity !== void 0 && quantity <= threshold && quantity > 0;
704
707
  }
@@ -1135,6 +1138,98 @@ function useCartView(options = {}) {
1135
1138
  isBusy
1136
1139
  };
1137
1140
  }
1141
+ function useReorderView(items, options = {}) {
1142
+ const { imageSize = "thumbnail" } = options;
1143
+ const storeContext = react.useContext(WooCommerceStoreContext);
1144
+ const storeConfig = storeContext?.config;
1145
+ const localeTag = options.localeTag ?? storeConfig?.locale?.localeTag ?? DEFAULT_STORE_CONFIG.locale.localeTag;
1146
+ const fallbackImageUrl = options.fallbackImageUrl ?? storeConfig?.fallbackImageUrl;
1147
+ const imageUrlTransformer = storeConfig?.imageUrlTransformer;
1148
+ const productIds = react.useMemo(() => [...new Set(items.map((item) => item.productId))], [items]);
1149
+ const {
1150
+ data: productsPage,
1151
+ isLoading,
1152
+ error
1153
+ } = useProducts(
1154
+ { include: productIds, page: 1, per_page: 100 },
1155
+ { enabled: productIds.length > 0 }
1156
+ );
1157
+ const { data: cart } = useCart();
1158
+ const getProcessedImageUrl = react.useCallback(
1159
+ (images) => {
1160
+ const baseUrl = getImageUrl(images, imageSize, fallbackImageUrl);
1161
+ if (baseUrl && imageUrlTransformer) {
1162
+ return imageUrlTransformer(baseUrl, imageSize);
1163
+ }
1164
+ return baseUrl;
1165
+ },
1166
+ [imageSize, fallbackImageUrl, imageUrlTransformer]
1167
+ );
1168
+ const views = react.useMemo(() => {
1169
+ const products = new Map((productsPage?.data ?? []).map((product) => [product.id, product]));
1170
+ return items.map((item) => {
1171
+ const product = products.get(item.productId);
1172
+ if (!product) {
1173
+ return {
1174
+ productId: item.productId,
1175
+ name: "",
1176
+ requestedQuantity: item.quantity,
1177
+ minQuantity: 1,
1178
+ maxQuantity: 0,
1179
+ unitPrice: "-",
1180
+ lineTotal: "-",
1181
+ reason: "missing"
1182
+ };
1183
+ }
1184
+ const currencyCode = product.prices.currency_code;
1185
+ const minQuantity = product.add_to_cart.minimum || 1;
1186
+ const maxQuantity = product.add_to_cart.maximum;
1187
+ const step = product.add_to_cart.multiple_of || 1;
1188
+ const upperQuantity = maxQuantity > 0 ? maxQuantity : item.quantity;
1189
+ const clampedQuantity = Math.min(Math.max(item.quantity, minQuantity), upperQuantity);
1190
+ const requestedQuantity = step > 1 ? Math.max(step, Math.floor(clampedQuantity / step) * step) : clampedQuantity;
1191
+ const unitAmount = Number(product.prices.price);
1192
+ const reason = unavailableReason(product);
1193
+ return {
1194
+ productId: product.id,
1195
+ name: product.name,
1196
+ imageUrl: getProcessedImageUrl(product.images),
1197
+ requestedQuantity,
1198
+ minQuantity,
1199
+ maxQuantity,
1200
+ unitPrice: formatStoreApiPriceIntl(product.prices.price, currencyCode, localeTag),
1201
+ lineTotal: formatStoreApiPriceIntl(
1202
+ Number.isNaN(unitAmount) ? null : String(unitAmount * requestedQuantity),
1203
+ currencyCode,
1204
+ localeTag
1205
+ ),
1206
+ ...reason ? { reason } : {},
1207
+ raw: product
1208
+ };
1209
+ });
1210
+ }, [items, productsPage?.data, localeTag, getProcessedImageUrl]);
1211
+ const cartProductIds = react.useMemo(
1212
+ () => new Set((cart?.items ?? []).map((item) => item.id)),
1213
+ [cart?.items]
1214
+ );
1215
+ const { addable, inCart, unavailable } = react.useMemo(
1216
+ () => ({
1217
+ addable: views.filter((view) => !view.reason && !cartProductIds.has(view.productId)),
1218
+ inCart: views.filter((view) => !view.reason && cartProductIds.has(view.productId)),
1219
+ unavailable: views.filter((view) => !!view.reason)
1220
+ }),
1221
+ [views, cartProductIds]
1222
+ );
1223
+ return {
1224
+ addable,
1225
+ inCart,
1226
+ unavailable,
1227
+ availableCount: addable.length + inCart.length,
1228
+ totalCount: views.length,
1229
+ isLoading,
1230
+ error
1231
+ };
1232
+ }
1138
1233
  var ORDER_STATUS_LABELS = {
1139
1234
  pending: "Pending Payment",
1140
1235
  processing: "Processing",
@@ -1186,6 +1281,7 @@ function useOrderView(input, options = {}) {
1186
1281
 
1187
1282
  exports.createQueryKeys = createQueryKeys;
1188
1283
  exports.getOrderStatusLabel = getOrderStatusLabel;
1284
+ exports.useAddManyToCart = useAddManyToCart;
1189
1285
  exports.useAddToCart = useAddToCart;
1190
1286
  exports.useApplyCoupon = useApplyCoupon;
1191
1287
  exports.useCart = useCart;
@@ -1203,6 +1299,7 @@ exports.useProducts = useProducts;
1203
1299
  exports.useProductsFeed = useProductsFeed;
1204
1300
  exports.useRemoveCoupon = useRemoveCoupon;
1205
1301
  exports.useRemoveFromCart = useRemoveFromCart;
1302
+ exports.useReorderView = useReorderView;
1206
1303
  exports.useSelectShippingRate = useSelectShippingRate;
1207
1304
  exports.useStore = useStore;
1208
1305
  exports.useStoreFeatures = useStoreFeatures;