@springmicro/cart 0.5.7 → 0.5.9
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.js +4218 -4176
- package/dist/index.umd.cjs +63 -63
- package/package.json +3 -3
- package/src/checkout/ReviewCartAndCalculateTaxes.tsx +9 -3
- package/src/checkout/components/CartList.tsx +16 -10
- package/src/checkout/components/CartProductCard.tsx +5 -1
- package/src/checkout/index.tsx +73 -19
- package/src/utils/storage.ts +5 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@springmicro/cart",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.9",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@nanostores/persistent": "^0.10.1",
|
|
25
25
|
"@nanostores/query": "^0.3.3",
|
|
26
26
|
"@nanostores/react": "^0.7.2",
|
|
27
|
-
"@springmicro/utils": "0.5.
|
|
27
|
+
"@springmicro/utils": "0.5.9",
|
|
28
28
|
"dotenv": "^16.4.5",
|
|
29
29
|
"nanostores": "^0.10.3",
|
|
30
30
|
"react": "^18.2.0",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"vite-plugin-css-injected-by-js": "^3.5.1",
|
|
50
50
|
"yup": "^1.4.0"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "1fe9c4a845356e81452c10106dbc3c5266e42ddf"
|
|
53
53
|
}
|
|
@@ -71,13 +71,18 @@ async function createOrder(cart, apiBaseUrl) {
|
|
|
71
71
|
return order;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
async function getTax(apiBaseUrl, taxProvider, items, v) {
|
|
74
|
+
async function getTax(apiBaseUrl, taxProvider, items, v, products) {
|
|
75
|
+
const taxable_items = items.filter(
|
|
76
|
+
(i) => i.unit_amount > 0 && products[i.product_id].type !== "DONATION"
|
|
77
|
+
);
|
|
78
|
+
if (taxable_items.length === 0) return { tax_amount: 0 };
|
|
79
|
+
|
|
75
80
|
const res = await fetch(
|
|
76
81
|
`${apiBaseUrl}/api/ecommerce/tax?tax_provider=${taxProvider ?? "dummy"}`,
|
|
77
82
|
{
|
|
78
83
|
method: "POST",
|
|
79
84
|
body: JSON.stringify({
|
|
80
|
-
cart_data:
|
|
85
|
+
cart_data: taxable_items,
|
|
81
86
|
address: {
|
|
82
87
|
country: v.country,
|
|
83
88
|
city: v.locality,
|
|
@@ -102,6 +107,7 @@ export default function ReviewAndCalculateTaxes({
|
|
|
102
107
|
statusState,
|
|
103
108
|
cart,
|
|
104
109
|
prices,
|
|
110
|
+
products,
|
|
105
111
|
apiBaseUrl,
|
|
106
112
|
orderState,
|
|
107
113
|
disableProductLink,
|
|
@@ -126,7 +132,6 @@ export default function ReviewAndCalculateTaxes({
|
|
|
126
132
|
setFormError(undefined);
|
|
127
133
|
// status === 0 when this is clicked.
|
|
128
134
|
// Creates an order and calculates tax.
|
|
129
|
-
|
|
130
135
|
Promise.all([
|
|
131
136
|
createOrder(cart, apiBaseUrl),
|
|
132
137
|
getTax(
|
|
@@ -344,6 +349,7 @@ export default function ReviewAndCalculateTaxes({
|
|
|
344
349
|
shipping,
|
|
345
350
|
discount,
|
|
346
351
|
prices,
|
|
352
|
+
products,
|
|
347
353
|
disableMissingImage,
|
|
348
354
|
disableProductLink,
|
|
349
355
|
formik,
|
|
@@ -14,6 +14,7 @@ export function CartList({
|
|
|
14
14
|
shipping,
|
|
15
15
|
discount,
|
|
16
16
|
prices,
|
|
17
|
+
products,
|
|
17
18
|
disableMissingImage,
|
|
18
19
|
disableProductLink,
|
|
19
20
|
formik,
|
|
@@ -133,16 +134,21 @@ export function CartList({
|
|
|
133
134
|
</Button>
|
|
134
135
|
)}
|
|
135
136
|
<Box className="checkout-list">
|
|
136
|
-
{cart.items.map(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
{cart.items.map(
|
|
138
|
+
(p, i) => (
|
|
139
|
+
console.log(p),
|
|
140
|
+
(
|
|
141
|
+
<CartProductCard
|
|
142
|
+
product={products[p.product_id] ?? p}
|
|
143
|
+
i={i}
|
|
144
|
+
price={prices[p.price_id]}
|
|
145
|
+
disableProductLink={disableProductLink}
|
|
146
|
+
disableMissingImage={disableMissingImage}
|
|
147
|
+
disableModification={status != 0}
|
|
148
|
+
/>
|
|
149
|
+
)
|
|
150
|
+
)
|
|
151
|
+
)}
|
|
146
152
|
</Box>
|
|
147
153
|
</Box>
|
|
148
154
|
</Box>
|
|
@@ -51,10 +51,14 @@ export function CartProductCard({
|
|
|
51
51
|
price.recurring.interval_count > 1 ? "s" : ""
|
|
52
52
|
}`
|
|
53
53
|
: ""
|
|
54
|
-
}`
|
|
54
|
+
}${product.type === "DONATION" ? " - Donation" : ""}`
|
|
55
55
|
: "Loading price..."}
|
|
56
56
|
</Typography>
|
|
57
57
|
</div>
|
|
58
|
+
<div className="two-row">
|
|
59
|
+
<Typography />
|
|
60
|
+
<Typography variant="caption"></Typography>
|
|
61
|
+
</div>
|
|
58
62
|
</div>
|
|
59
63
|
<div
|
|
60
64
|
style={{
|
package/src/checkout/index.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./ReviewCartAndCalculateTaxes.css";
|
|
2
2
|
import { useStore } from "@nanostores/react";
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
3
|
+
import { useEffect, useMemo, useState } from "react";
|
|
4
4
|
import { Typography } from "@mui/material";
|
|
5
5
|
import { cartStore, clearCart } from "../utils/storage";
|
|
6
6
|
import { StatusBar } from "./components/StatusBar";
|
|
@@ -25,8 +25,11 @@ export default function Checkout({
|
|
|
25
25
|
CollectExtraInfo?: React.FC<{ formik: FormikConfig<any> }>;
|
|
26
26
|
defaultValues?: Record<string, any>;
|
|
27
27
|
}) {
|
|
28
|
-
const
|
|
28
|
+
const store = useStore(cartStore);
|
|
29
|
+
const cart = useMemo(() => JSON.parse(store), [store]);
|
|
30
|
+
// const cart = JSON.parse(useStore(cartStore));
|
|
29
31
|
|
|
32
|
+
const [products, setProducts] = useState({});
|
|
30
33
|
const [prices, setPrices] = useState({});
|
|
31
34
|
const [subtotal, setSubtotal] = useState("Loading prices...");
|
|
32
35
|
const taxState = useState({ tax_amount: "TBD" });
|
|
@@ -59,36 +62,74 @@ export default function Checkout({
|
|
|
59
62
|
}
|
|
60
63
|
}, []);
|
|
61
64
|
|
|
62
|
-
// build pricing list
|
|
65
|
+
// build pricing list and product list
|
|
63
66
|
useEffect(() => {
|
|
64
67
|
// filter out prices that have already been queried
|
|
65
68
|
const pricesToGet = cart.items
|
|
66
69
|
.map((c) => c.price_id)
|
|
67
70
|
.filter(
|
|
68
|
-
(pId) => Object.keys(
|
|
71
|
+
(pId) => Object.keys(products).findIndex((pKey) => pKey == pId) === -1
|
|
69
72
|
);
|
|
70
|
-
if (pricesToGet.length === 0) return;
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
// filter out products that have already been queried
|
|
75
|
+
const productsToGet = cart.items
|
|
76
|
+
.map((c) => c.product_id)
|
|
77
|
+
.filter(
|
|
78
|
+
(pId) => Object.keys(products).findIndex((pKey) => pKey == pId) === -1
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const priceUrl = `${apiBaseUrl}/api/ecommerce/price?filter={'ids':[${pricesToGet.join(
|
|
82
|
+
","
|
|
83
|
+
)}]}`;
|
|
84
|
+
|
|
85
|
+
const productUrl = `${apiBaseUrl}/api/ecommerce/products?filter={'ids':[${productsToGet.join(
|
|
73
86
|
","
|
|
74
87
|
)}]}`;
|
|
75
|
-
|
|
88
|
+
|
|
89
|
+
const fetchSettings = {
|
|
76
90
|
method: "GET",
|
|
77
91
|
headers: {
|
|
78
92
|
"Content-Type": "application/json",
|
|
79
93
|
},
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
if (pricesToGet.length === 0 && productsToGet.length === 0) return;
|
|
97
|
+
|
|
98
|
+
Promise.all([
|
|
99
|
+
pricesToGet.length !== 0
|
|
100
|
+
? fetch(priceUrl, fetchSettings)
|
|
101
|
+
: Promise.resolve(null),
|
|
102
|
+
productsToGet.length !== 0
|
|
103
|
+
? fetch(productUrl, fetchSettings)
|
|
104
|
+
: Promise.resolve(null),
|
|
105
|
+
]).then(([priceRes, productRes]) => {
|
|
106
|
+
Promise.all([
|
|
107
|
+
priceRes != null ? priceRes.json() : Promise.resolve(null),
|
|
108
|
+
productRes != null ? productRes.json() : Promise.resolve(null),
|
|
109
|
+
]).then(([d1, d2]) => {
|
|
110
|
+
if (d1 != null) {
|
|
111
|
+
const data = d1.reduce(
|
|
112
|
+
(o, p) => ({
|
|
113
|
+
...o,
|
|
114
|
+
[p.id]: p,
|
|
115
|
+
}),
|
|
116
|
+
prices
|
|
117
|
+
);
|
|
118
|
+
setPrices(data);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (d2 != null) {
|
|
122
|
+
const data = d2.reduce(
|
|
123
|
+
(o, p) => ({
|
|
124
|
+
...o,
|
|
125
|
+
[p.id]: p,
|
|
126
|
+
}),
|
|
127
|
+
products
|
|
128
|
+
);
|
|
129
|
+
setProducts(data);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
});
|
|
92
133
|
}, [cart]);
|
|
93
134
|
|
|
94
135
|
useEffect(() => {
|
|
@@ -99,6 +140,18 @@ export default function Checkout({
|
|
|
99
140
|
);
|
|
100
141
|
}, [cart, prices]);
|
|
101
142
|
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
const taxable_items = cart.items.filter(
|
|
145
|
+
(i) =>
|
|
146
|
+
prices[i.price_id]?.unit_amount > 0 &&
|
|
147
|
+
products[i.product_id]?.type !== "DONATION"
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
if (taxable_items.length === 0) {
|
|
151
|
+
taxState[1]({ tax_amount: 0 });
|
|
152
|
+
}
|
|
153
|
+
}, [cart, prices, products]);
|
|
154
|
+
|
|
102
155
|
if (status === 0 && cart.items.length === 0)
|
|
103
156
|
return (
|
|
104
157
|
<div
|
|
@@ -146,6 +199,7 @@ export default function Checkout({
|
|
|
146
199
|
statusState={[status, setStatus]}
|
|
147
200
|
cart={cart}
|
|
148
201
|
prices={prices}
|
|
202
|
+
products={products}
|
|
149
203
|
apiBaseUrl={apiBaseUrl}
|
|
150
204
|
orderState={[order, setOrder]}
|
|
151
205
|
disableProductLink={disableProductLink}
|
package/src/utils/storage.ts
CHANGED
|
@@ -121,7 +121,8 @@ export function addToCart(p: CartProduct) {
|
|
|
121
121
|
|
|
122
122
|
// Update cart based on server info.
|
|
123
123
|
const cart = await res.json();
|
|
124
|
-
|
|
124
|
+
if (JSON.stringify(newCart) != apiCartToLocalCart(cart))
|
|
125
|
+
cartStore.set(apiCartToLocalCart(cart));
|
|
125
126
|
});
|
|
126
127
|
}
|
|
127
128
|
}
|
|
@@ -156,7 +157,8 @@ export function removeFromCart(i: number) {
|
|
|
156
157
|
|
|
157
158
|
// Update cart based on server info.
|
|
158
159
|
const cart = await res.json();
|
|
159
|
-
|
|
160
|
+
if (JSON.stringify(newCart) != apiCartToLocalCart(cart))
|
|
161
|
+
cartStore.set(apiCartToLocalCart(cart));
|
|
160
162
|
});
|
|
161
163
|
}
|
|
162
164
|
}
|
|
@@ -171,7 +173,7 @@ export function clearCart() {
|
|
|
171
173
|
const pathDetails = apiPathDetails.get();
|
|
172
174
|
if (pathDetailsIsFullyDefined(pathDetails)) {
|
|
173
175
|
fetchFromCartApi("DELETE", pathDetails).then(async () => {
|
|
174
|
-
cartStore.set(JSON.stringify(newCart));
|
|
176
|
+
// cartStore.set(JSON.stringify(newCart));
|
|
175
177
|
});
|
|
176
178
|
}
|
|
177
179
|
}
|