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