@atomic-solutions/woocommerce-react 0.5.0 → 0.6.0

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