@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.
package/dist/index.cjs CHANGED
@@ -627,6 +627,14 @@ var useCart = (options) => {
627
627
  getQuantity
628
628
  };
629
629
  };
630
+ var toWooError = (error) => error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
631
+ code: "unknown_error",
632
+ message: error instanceof Error ? error.message : "Unknown error",
633
+ statusCode: 500,
634
+ url: "",
635
+ method: "POST",
636
+ originalCode: "unknown_error"
637
+ });
630
638
  var useAddToCart = () => {
631
639
  const client = useWooCommerceClient();
632
640
  const queryKeys = useWooCommerceQueryKeys();
@@ -645,15 +653,50 @@ var useAddToCart = () => {
645
653
  },
646
654
  onError: (error) => {
647
655
  if (emitEvent) {
648
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
649
- code: "unknown_error",
650
- message: error instanceof Error ? error.message : "Unknown error",
651
- statusCode: 500,
652
- url: "",
653
- method: "POST",
654
- originalCode: "unknown_error"
655
- });
656
- emitEvent(createErrorEvent("cart:item_added", wooError));
656
+ emitEvent(createErrorEvent("cart:item_added", toWooError(error)));
657
+ }
658
+ }
659
+ });
660
+ };
661
+ var useAddManyToCart = () => {
662
+ const client = useWooCommerceClient();
663
+ const queryKeys = useWooCommerceQueryKeys();
664
+ const queryClient = reactQuery.useQueryClient();
665
+ const emitEvent = useEventEmitter();
666
+ return reactQuery.useMutation({
667
+ mutationKey: queryKeys.cart.mutations.addItems(),
668
+ mutationFn: (input) => client.cart.addItems(input),
669
+ onSuccess: ({ cart, results }) => {
670
+ queryClient.setQueryData(queryKeys.cart.details(), cart);
671
+ queryClient.invalidateQueries({ queryKey: queryKeys.cart.all });
672
+ if (!emitEvent) return;
673
+ results.forEach((result) => {
674
+ if (result.status >= 200 && result.status < 300) {
675
+ const addedItem = cart.items.find((item) => item.id === result.item.id);
676
+ if (addedItem) {
677
+ emitEvent(createSuccessEvent("cart:item_added", { item: addedItem, cart }));
678
+ }
679
+ return;
680
+ }
681
+ emitEvent(
682
+ createErrorEvent(
683
+ "cart:item_added",
684
+ new woocommerceApiClient.WooCommerceApiError({
685
+ code: woocommerceApiClient.mapWooCommerceCode(result.code),
686
+ originalCode: result.code ?? "unknown_error",
687
+ message: result.message ?? "Failed to add item to cart",
688
+ statusCode: result.status,
689
+ url: "",
690
+ method: "POST",
691
+ requestBody: result.item
692
+ })
693
+ )
694
+ );
695
+ });
696
+ },
697
+ onError: (error) => {
698
+ if (emitEvent) {
699
+ emitEvent(createErrorEvent("cart:item_added", toWooError(error)));
657
700
  }
658
701
  }
659
702
  });
@@ -676,15 +719,7 @@ var useUpdateCartItem = () => {
676
719
  },
677
720
  onError: (error) => {
678
721
  if (emitEvent) {
679
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
680
- code: "unknown_error",
681
- message: error instanceof Error ? error.message : "Unknown error",
682
- statusCode: 500,
683
- url: "",
684
- method: "POST",
685
- originalCode: "unknown_error"
686
- });
687
- emitEvent(createErrorEvent("cart:item_updated", wooError));
722
+ emitEvent(createErrorEvent("cart:item_updated", toWooError(error)));
688
723
  }
689
724
  }
690
725
  });
@@ -706,15 +741,7 @@ var useRemoveFromCart = () => {
706
741
  },
707
742
  onError: (error) => {
708
743
  if (emitEvent) {
709
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
710
- code: "unknown_error",
711
- message: error instanceof Error ? error.message : "Unknown error",
712
- statusCode: 500,
713
- url: "",
714
- method: "POST",
715
- originalCode: "unknown_error"
716
- });
717
- emitEvent(createErrorEvent("cart:item_removed", wooError));
744
+ emitEvent(createErrorEvent("cart:item_removed", toWooError(error)));
718
745
  }
719
746
  }
720
747
  });
@@ -736,15 +763,7 @@ var useApplyCoupon = () => {
736
763
  },
737
764
  onError: (error) => {
738
765
  if (emitEvent) {
739
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
740
- code: "unknown_error",
741
- message: error instanceof Error ? error.message : "Unknown error",
742
- statusCode: 500,
743
- url: "",
744
- method: "POST",
745
- originalCode: "unknown_error"
746
- });
747
- emitEvent(createErrorEvent("cart:coupon_applied", wooError));
766
+ emitEvent(createErrorEvent("cart:coupon_applied", toWooError(error)));
748
767
  }
749
768
  }
750
769
  });
@@ -766,15 +785,7 @@ var useRemoveCoupon = () => {
766
785
  },
767
786
  onError: (error) => {
768
787
  if (emitEvent) {
769
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
770
- code: "unknown_error",
771
- message: error instanceof Error ? error.message : "Unknown error",
772
- statusCode: 500,
773
- url: "",
774
- method: "POST",
775
- originalCode: "unknown_error"
776
- });
777
- emitEvent(createErrorEvent("cart:coupon_removed", wooError));
788
+ emitEvent(createErrorEvent("cart:coupon_removed", toWooError(error)));
778
789
  }
779
790
  }
780
791
  });
@@ -796,15 +807,7 @@ var useUpdateCustomer = () => {
796
807
  },
797
808
  onError: (error) => {
798
809
  if (emitEvent) {
799
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
800
- code: "unknown_error",
801
- message: error instanceof Error ? error.message : "Unknown error",
802
- statusCode: 500,
803
- url: "",
804
- method: "POST",
805
- originalCode: "unknown_error"
806
- });
807
- emitEvent(createErrorEvent("cart:customer_updated", wooError));
810
+ emitEvent(createErrorEvent("cart:customer_updated", toWooError(error)));
808
811
  }
809
812
  }
810
813
  });
@@ -826,15 +829,7 @@ var useSelectShippingRate = () => {
826
829
  },
827
830
  onError: (error) => {
828
831
  if (emitEvent) {
829
- const wooError = error instanceof woocommerceApiClient.WooCommerceApiError ? error : new woocommerceApiClient.WooCommerceApiError({
830
- code: "unknown_error",
831
- message: error instanceof Error ? error.message : "Unknown error",
832
- statusCode: 500,
833
- url: "",
834
- method: "POST",
835
- originalCode: "unknown_error"
836
- });
837
- emitEvent(createErrorEvent("cart:shipping_selected", wooError));
832
+ emitEvent(createErrorEvent("cart:shipping_selected", toWooError(error)));
838
833
  }
839
834
  }
840
835
  });
@@ -911,6 +906,7 @@ var createQueryKeys = (prefix = ["woocommerce"]) => ({
911
906
  // Mutation keys
912
907
  mutations: {
913
908
  addItem: () => [...prefix, "cart", "mutation", "addItem"],
909
+ addItems: () => [...prefix, "cart", "mutation", "addItems"],
914
910
  updateItem: () => [...prefix, "cart", "mutation", "updateItem"],
915
911
  removeItem: () => [...prefix, "cart", "mutation", "removeItem"],
916
912
  applyCoupon: () => [...prefix, "cart", "mutation", "applyCoupon"],
@@ -1304,6 +1300,18 @@ function isPurchasable(status, quantity, manageStock = true) {
1304
1300
  }
1305
1301
  return true;
1306
1302
  }
1303
+ function unavailableReason(product) {
1304
+ if (!product.is_in_stock || product.is_on_backorder || product.add_to_cart.maximum <= 0) {
1305
+ return "out_of_stock";
1306
+ }
1307
+ if (!product.is_purchasable) {
1308
+ return "not_purchasable";
1309
+ }
1310
+ return void 0;
1311
+ }
1312
+ function canAddToCart(product) {
1313
+ return !unavailableReason(product);
1314
+ }
1307
1315
  function getStockSeverity(status, quantity, lowStockThreshold = 5) {
1308
1316
  switch (status) {
1309
1317
  case "outofstock":
@@ -1646,6 +1654,98 @@ function useCartView(options = {}) {
1646
1654
  isBusy
1647
1655
  };
1648
1656
  }
1657
+ function useReorderView(items, options = {}) {
1658
+ const { imageSize = "thumbnail" } = options;
1659
+ const storeContext = react.useContext(WooCommerceStoreContext);
1660
+ const storeConfig = storeContext?.config;
1661
+ const localeTag = options.localeTag ?? storeConfig?.locale?.localeTag ?? DEFAULT_STORE_CONFIG.locale.localeTag;
1662
+ const fallbackImageUrl = options.fallbackImageUrl ?? storeConfig?.fallbackImageUrl;
1663
+ const imageUrlTransformer = storeConfig?.imageUrlTransformer;
1664
+ const productIds = react.useMemo(() => [...new Set(items.map((item) => item.productId))], [items]);
1665
+ const {
1666
+ data: productsPage,
1667
+ isLoading,
1668
+ error
1669
+ } = useProducts(
1670
+ { include: productIds, page: 1, per_page: 100 },
1671
+ { enabled: productIds.length > 0 }
1672
+ );
1673
+ const { data: cart } = useCart();
1674
+ const getProcessedImageUrl = react.useCallback(
1675
+ (images) => {
1676
+ const baseUrl = getImageUrl(images, imageSize, fallbackImageUrl);
1677
+ if (baseUrl && imageUrlTransformer) {
1678
+ return imageUrlTransformer(baseUrl, imageSize);
1679
+ }
1680
+ return baseUrl;
1681
+ },
1682
+ [imageSize, fallbackImageUrl, imageUrlTransformer]
1683
+ );
1684
+ const views = react.useMemo(() => {
1685
+ const products = new Map((productsPage?.data ?? []).map((product) => [product.id, product]));
1686
+ return items.map((item) => {
1687
+ const product = products.get(item.productId);
1688
+ if (!product) {
1689
+ return {
1690
+ productId: item.productId,
1691
+ name: "",
1692
+ requestedQuantity: item.quantity,
1693
+ minQuantity: 1,
1694
+ maxQuantity: 0,
1695
+ unitPrice: "-",
1696
+ lineTotal: "-",
1697
+ reason: "missing"
1698
+ };
1699
+ }
1700
+ const currencyCode = product.prices.currency_code;
1701
+ const minQuantity = product.add_to_cart.minimum || 1;
1702
+ const maxQuantity = product.add_to_cart.maximum;
1703
+ const step = product.add_to_cart.multiple_of || 1;
1704
+ const upperQuantity = maxQuantity > 0 ? maxQuantity : item.quantity;
1705
+ const clampedQuantity = Math.min(Math.max(item.quantity, minQuantity), upperQuantity);
1706
+ const requestedQuantity = step > 1 ? Math.max(step, Math.floor(clampedQuantity / step) * step) : clampedQuantity;
1707
+ const unitAmount = Number(product.prices.price);
1708
+ const reason = unavailableReason(product);
1709
+ return {
1710
+ productId: product.id,
1711
+ name: product.name,
1712
+ imageUrl: getProcessedImageUrl(product.images),
1713
+ requestedQuantity,
1714
+ minQuantity,
1715
+ maxQuantity,
1716
+ unitPrice: formatStoreApiPriceIntl(product.prices.price, currencyCode, localeTag),
1717
+ lineTotal: formatStoreApiPriceIntl(
1718
+ Number.isNaN(unitAmount) ? null : String(unitAmount * requestedQuantity),
1719
+ currencyCode,
1720
+ localeTag
1721
+ ),
1722
+ ...reason ? { reason } : {},
1723
+ raw: product
1724
+ };
1725
+ });
1726
+ }, [items, productsPage?.data, localeTag, getProcessedImageUrl]);
1727
+ const cartProductIds = react.useMemo(
1728
+ () => new Set((cart?.items ?? []).map((item) => item.id)),
1729
+ [cart?.items]
1730
+ );
1731
+ const { addable, inCart, unavailable } = react.useMemo(
1732
+ () => ({
1733
+ addable: views.filter((view) => !view.reason && !cartProductIds.has(view.productId)),
1734
+ inCart: views.filter((view) => !view.reason && cartProductIds.has(view.productId)),
1735
+ unavailable: views.filter((view) => !!view.reason)
1736
+ }),
1737
+ [views, cartProductIds]
1738
+ );
1739
+ return {
1740
+ addable,
1741
+ inCart,
1742
+ unavailable,
1743
+ availableCount: addable.length + inCart.length,
1744
+ totalCount: views.length,
1745
+ isLoading,
1746
+ error
1747
+ };
1748
+ }
1649
1749
  var ORDER_STATUS_LABELS = {
1650
1750
  pending: "Pending Payment",
1651
1751
  processing: "Processing",
@@ -1786,6 +1886,7 @@ exports.WooCommerceProvider = WooCommerceProvider;
1786
1886
  exports.WooCommerceStoreContext = WooCommerceStoreContext;
1787
1887
  exports.WooCommerceStoreProvider = WooCommerceStoreProvider;
1788
1888
  exports.calculateDiscount = calculateDiscount;
1889
+ exports.canAddToCart = canAddToCart;
1789
1890
  exports.composeHandlers = composeHandlers;
1790
1891
  exports.configureGlobalRateLimiter = configureGlobalRateLimiter;
1791
1892
  exports.createAnalyticsHandler = createAnalyticsHandler;
@@ -1815,6 +1916,8 @@ exports.parseWooCommercePrice = parseWooCommercePrice;
1815
1916
  exports.preloadImage = preloadImage;
1816
1917
  exports.preloadImages = preloadImages;
1817
1918
  exports.resetGlobalRateLimiter = resetGlobalRateLimiter;
1919
+ exports.unavailableReason = unavailableReason;
1920
+ exports.useAddManyToCart = useAddManyToCart;
1818
1921
  exports.useAddToCart = useAddToCart;
1819
1922
  exports.useApplyCoupon = useApplyCoupon;
1820
1923
  exports.useCart = useCart;
@@ -1832,6 +1935,7 @@ exports.useProducts = useProducts;
1832
1935
  exports.useProductsFeed = useProductsFeed;
1833
1936
  exports.useRemoveCoupon = useRemoveCoupon;
1834
1937
  exports.useRemoveFromCart = useRemoveFromCart;
1938
+ exports.useReorderView = useReorderView;
1835
1939
  exports.useSelectShippingRate = useSelectShippingRate;
1836
1940
  exports.useStore = useStore;
1837
1941
  exports.useStoreFeatures = useStoreFeatures;