@base44/app-plugin-commerce 0.2.6 → 0.3.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.
Files changed (36) hide show
  1. package/README.md +4 -4
  2. package/package.json +2 -2
  3. package/scripts/install.js +15 -0
  4. package/skills/commerce/SKILL.md +31 -13
  5. package/skills/commerce/docs/api-admin.md +1 -1
  6. package/skills/commerce/docs/api-storefront.md +12 -12
  7. package/skills/commerce/install/01-install.md +5 -2
  8. package/skills/commerce/install/02-storefront.md +179 -220
  9. package/skills/commerce/install/03-data.md +1 -1
  10. package/skills/commerce/references/catalog-rendering.md +37 -43
  11. package/skills/commerce/references/reviews.md +21 -14
  12. package/skills/commerce/references/store-settings.md +1 -1
  13. package/skills/commerce/references/storefront-verification.md +21 -15
  14. package/src/commerce/storefront/StorefrontProvider.jsx +65 -128
  15. package/src/commerce/storefront/cartUI.jsx +26 -117
  16. package/src/commerce/storefront/index.js +61 -98
  17. package/src/commerce/storefront/pickers.jsx +53 -81
  18. package/src/commerce/storefront/useCartLine.js +23 -130
  19. package/src/commerce/storefront/useCheckout.jsx +50 -43
  20. package/src/commerce/storefront/useOrderReturn.js +17 -7
  21. package/src/commerce/storefront/useProduct.js +54 -119
  22. package/src/commerce/storefront/useProductList.js +15 -28
  23. package/src/commerce/utils/address-spec.js +1 -1
  24. package/src/commerce/utils/images.js +1 -1
  25. package/src/commerce/utils/index.js +9 -9
  26. package/src/commerce/utils/price.js +2 -1
  27. package/src/commerce/utils/specs.js +41 -91
  28. package/src/commerce/utils/totals.js +7 -4
  29. package/src/commerce/storefront/useAddressForm.js +0 -175
  30. package/src/commerce/storefront/usePlaceOrder.js +0 -55
  31. package/src/commerce/storefront/useProductGallery.js +0 -78
  32. package/src/commerce/storefront/useProductPrice.js +0 -58
  33. package/src/commerce/storefront/useProductReviews.js +0 -242
  34. package/src/commerce/storefront/useStorefrontSeo.js +0 -204
  35. package/src/commerce/storefront/useTotalsLines.js +0 -109
  36. package/src/commerce/storefront/useUpsell.js +0 -90
@@ -1,90 +0,0 @@
1
- import { useCallback } from "react";
2
- import { productImages } from "@/commerce/utils";
3
- import { useCart, useStorefront } from "./StorefrontProvider";
4
- import { useCartUIOptional } from "./cartUI";
5
- import { useAsyncData } from "./internal/useAsyncData";
6
- import { useAddToCart } from "./useProduct";
7
- import { useProductPrice } from "./useProductPrice";
8
-
9
- /**
10
- * useUpsell — one product offered beside another surface (a cart drawer's
11
- * "add the care kit", a checkout's "complete the set", a cross-sell strip
12
- * entry), with the lifecycle solved:
13
- *
14
- * const kit = useUpsell("care-kit"); // slug or { id }…
15
- * const kit = useUpsell(p.crossSells[0]); // …or a row you already have
16
- * {kit.show && (
17
- * <aside className="…">
18
- * {kit.image && <img src={kit.image.src} alt={kit.image.alt} className="…" />}
19
- * {kit.product.name} {kit.price.label}
20
- * <button type="button" onClick={kit.add} disabled={kit.adding}>Add</button>
21
- * {kit.error && <p role="alert">{kit.error.message}</p>}
22
- * </aside>
23
- * )}
24
- *
25
- * `show` is the one flag to branch on: it is false while loading, on a fetch
26
- * failure, when the product is out of stock, and **when it is already in the
27
- * cart** — matched by product id, never by display name (a rename must not
28
- * break the match). Passing a row you already hold (`product.upsells` /
29
- * `product.crossSells` from `useProduct`, or a `useProductList` row) skips the
30
- * fetch entirely — prefer that when the row is on hand.
31
- *
32
- * `add()` never throws; a product with options can't be one-click added
33
- * (`needsSelection` — link to its page instead). With `<CartUIProvider>`
34
- * mounted, a successful add opens the drawer.
35
- *
36
- * @param {string|{id: string}|object} ref slug, `{ id }`, or a product row
37
- * @param {{quantity?: number}} [options]
38
- * @returns {{show: boolean, inCart: boolean, needsSelection: boolean,
39
- * product: object|null, image: {src: string, alt: string}|null,
40
- * price: object, add: () => Promise<object>, adding: boolean,
41
- * error: object|null}}
42
- */
43
- export function useUpsell(ref, { quantity = 1 } = {}) {
44
- const store = useStorefront();
45
- const { cart } = useCart();
46
- const cartUI = useCartUIOptional();
47
-
48
- // A row (has id + name) is used as-is; a slug or { id } is fetched.
49
- const isRow = Boolean(ref && typeof ref === "object" && ref.id && ref.name !== undefined);
50
- const refKey = isRow ? `row:${ref.id}` : typeof ref === "string" ? ref : JSON.stringify(ref ?? null);
51
-
52
- const { data, loading, error: fetchError } = useAsyncData(
53
- () => (isRow || !ref ? Promise.resolve(null) : store.getProduct(ref)),
54
- [store, refKey], // eslint-disable-line react-hooks/exhaustive-deps
55
- );
56
-
57
- const product = isRow ? ref : (data?.product ?? null);
58
- const needsSelection = isRow
59
- ? (ref.attributes?.length ?? 0) > 0
60
- : (data?.variations?.length ?? 0) > 0;
61
-
62
- const price = useProductPrice(product);
63
- const { add: rawAdd, adding, error, reset } = useAddToCart();
64
-
65
- const add = useCallback(async () => {
66
- if (!product) return { ok: false, error: { code: "no_product", message: "Product not loaded." } };
67
- if (needsSelection) {
68
- return { ok: false, error: { code: "variation_required", message: "Choose an option first." } };
69
- }
70
- const res = await rawAdd({ product_id: product.id }, quantity);
71
- if (res.ok) cartUI?.onItemAdded?.();
72
- return res;
73
- }, [product, needsSelection, rawAdd, quantity, cartUI]);
74
-
75
- const inCart = Boolean(product) && (cart?.items ?? []).some((i) => i.product_id === product.id);
76
- const busy = !isRow && Boolean(ref) && loading;
77
-
78
- return {
79
- show: !busy && !fetchError && Boolean(product) && !inCart && product?.stock_status !== "outofstock",
80
- inCart,
81
- needsSelection,
82
- product,
83
- image: productImages(product)[0] ?? null,
84
- price,
85
- add,
86
- adding,
87
- error,
88
- reset,
89
- };
90
- }