@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.
- package/README.md +4 -4
- package/package.json +2 -2
- package/scripts/install.js +15 -0
- package/skills/commerce/SKILL.md +31 -13
- package/skills/commerce/docs/api-admin.md +1 -1
- package/skills/commerce/docs/api-storefront.md +12 -12
- package/skills/commerce/install/01-install.md +5 -2
- package/skills/commerce/install/02-storefront.md +179 -220
- package/skills/commerce/install/03-data.md +1 -1
- package/skills/commerce/references/catalog-rendering.md +37 -43
- package/skills/commerce/references/reviews.md +21 -14
- package/skills/commerce/references/store-settings.md +1 -1
- package/skills/commerce/references/storefront-verification.md +21 -15
- package/src/commerce/storefront/StorefrontProvider.jsx +65 -128
- package/src/commerce/storefront/cartUI.jsx +26 -117
- package/src/commerce/storefront/index.js +61 -98
- package/src/commerce/storefront/pickers.jsx +53 -81
- package/src/commerce/storefront/useCartLine.js +23 -130
- package/src/commerce/storefront/useCheckout.jsx +50 -43
- package/src/commerce/storefront/useOrderReturn.js +17 -7
- package/src/commerce/storefront/useProduct.js +54 -119
- package/src/commerce/storefront/useProductList.js +15 -28
- package/src/commerce/utils/address-spec.js +1 -1
- package/src/commerce/utils/images.js +1 -1
- package/src/commerce/utils/index.js +9 -9
- package/src/commerce/utils/price.js +2 -1
- package/src/commerce/utils/specs.js +41 -91
- package/src/commerce/utils/totals.js +7 -4
- package/src/commerce/storefront/useAddressForm.js +0 -175
- package/src/commerce/storefront/usePlaceOrder.js +0 -55
- package/src/commerce/storefront/useProductGallery.js +0 -78
- package/src/commerce/storefront/useProductPrice.js +0 -58
- package/src/commerce/storefront/useProductReviews.js +0 -242
- package/src/commerce/storefront/useStorefrontSeo.js +0 -204
- package/src/commerce/storefront/useTotalsLines.js +0 -109
- 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
|
-
}
|