@springmicro/cart 0.5.14 → 0.5.15
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 +1004 -990
- package/dist/index.umd.cjs +42 -42
- package/package.json +3 -3
- package/src/CartButton.tsx +15 -7
- package/src/checkout/ReviewCartAndCalculateTaxes.tsx +18 -16
- package/src/checkout/components/AddCard.tsx +128 -107
- package/src/checkout/components/CartList.tsx +1 -0
- package/src/checkout/index.tsx +1 -1
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.15",
|
|
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.15",
|
|
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": "b830a46f0cb3e6081ed9a4f31861c0d0b66a88f2"
|
|
53
53
|
}
|
package/src/CartButton.tsx
CHANGED
|
@@ -140,7 +140,9 @@ function CartModal({
|
|
|
140
140
|
);
|
|
141
141
|
if (pricesToGet.length === 0) return;
|
|
142
142
|
|
|
143
|
-
const url = `${apiBaseUrl}/api/ecommerce/price?filter={'ids':[${pricesToGet.join(
|
|
143
|
+
const url = `${apiBaseUrl}/api/ecommerce/price?filter={'ids':[${pricesToGet.join(
|
|
144
|
+
","
|
|
145
|
+
)}]}`;
|
|
144
146
|
fetch(url, {
|
|
145
147
|
method: "GET",
|
|
146
148
|
headers: {
|
|
@@ -212,12 +214,18 @@ function CartModal({
|
|
|
212
214
|
{prices === null
|
|
213
215
|
? "Price not found."
|
|
214
216
|
: price
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
217
|
+
? `$${(price.unit_amount / 100).toFixed(2)}${
|
|
218
|
+
price.recurring
|
|
219
|
+
? `/${
|
|
220
|
+
price.recurring.interval_count > 1
|
|
221
|
+
? `${price.recurring.interval_count} `
|
|
222
|
+
: ""
|
|
223
|
+
}${price.recurring.interval}${
|
|
224
|
+
price.recurring.interval_count > 1 ? "s" : ""
|
|
225
|
+
}`
|
|
226
|
+
: ""
|
|
227
|
+
}`
|
|
228
|
+
: "Loading price..."}
|
|
221
229
|
</h3>
|
|
222
230
|
</Box>
|
|
223
231
|
<Tooltip title="Remove from cart">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./ReviewCartAndCalculateTaxes.css";
|
|
2
|
-
import { Box, useTheme, useMediaQuery } from "@mui/material";
|
|
2
|
+
import { Box, useTheme, useMediaQuery, Button } from "@mui/material";
|
|
3
3
|
import { setOrder as cartSetOrder } from "../utils/storage";
|
|
4
4
|
import { AddCard, CCFocus, CreditCardValues } from "./components/AddCard";
|
|
5
5
|
import { CartList } from "./components/CartList";
|
|
@@ -133,6 +133,7 @@ export default function ReviewAndCalculateTaxes({
|
|
|
133
133
|
|
|
134
134
|
async function createOrderAndGetTaxes(values) {
|
|
135
135
|
setFormError(undefined);
|
|
136
|
+
setFormDisabled(true);
|
|
136
137
|
// status === 0 when this is clicked.
|
|
137
138
|
// Creates an order and calculates tax.
|
|
138
139
|
Promise.all([
|
|
@@ -153,9 +154,11 @@ export default function ReviewAndCalculateTaxes({
|
|
|
153
154
|
setTax(taxData);
|
|
154
155
|
setOrder(order);
|
|
155
156
|
setStatus(1);
|
|
157
|
+
setFormDisabled(false);
|
|
156
158
|
})
|
|
157
159
|
.catch(() => {
|
|
158
160
|
setFormError(true);
|
|
161
|
+
setFormDisabled(false);
|
|
159
162
|
});
|
|
160
163
|
}
|
|
161
164
|
|
|
@@ -196,9 +199,12 @@ export default function ReviewAndCalculateTaxes({
|
|
|
196
199
|
.catch((e) => {
|
|
197
200
|
dev && console.log("Checkout error", e);
|
|
198
201
|
setFormError(true);
|
|
202
|
+
setFormDisabled(false);
|
|
199
203
|
});
|
|
200
204
|
}
|
|
201
205
|
|
|
206
|
+
const cardRequired = typeof subtotal === "string" || subtotal > 0;
|
|
207
|
+
|
|
202
208
|
/**
|
|
203
209
|
*
|
|
204
210
|
* AddCard formik data
|
|
@@ -262,21 +268,18 @@ export default function ReviewAndCalculateTaxes({
|
|
|
262
268
|
const formik = useFormik({
|
|
263
269
|
initialValues,
|
|
264
270
|
validationSchema: Yup.object(
|
|
265
|
-
|
|
266
|
-
?
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
+
cardRequired
|
|
272
|
+
? address
|
|
273
|
+
? {
|
|
274
|
+
...validationSchemaBase,
|
|
275
|
+
...validationSchemaAddress,
|
|
276
|
+
}
|
|
277
|
+
: validationSchemaBase
|
|
278
|
+
: {}
|
|
271
279
|
),
|
|
272
280
|
onSubmit: async (v, helpers) => {
|
|
273
281
|
dev && console.log("Formik submit");
|
|
274
|
-
setFormDisabled(true);
|
|
275
282
|
const values = { ...v };
|
|
276
|
-
if (formDisabled) {
|
|
277
|
-
setFormDisabled(false);
|
|
278
|
-
throw new Error("Attempted to submit an invalid form.");
|
|
279
|
-
}
|
|
280
283
|
|
|
281
284
|
const submitFunc = status === 0 ? createOrderAndGetTaxes : confirmOrder;
|
|
282
285
|
|
|
@@ -305,9 +308,6 @@ export default function ReviewAndCalculateTaxes({
|
|
|
305
308
|
.then((v) => {})
|
|
306
309
|
.catch((e) => {
|
|
307
310
|
dev && console.log("Submit errors", e);
|
|
308
|
-
})
|
|
309
|
-
.finally(() => {
|
|
310
|
-
setFormDisabled(false);
|
|
311
311
|
});
|
|
312
312
|
} else {
|
|
313
313
|
setFormDisabled(false);
|
|
@@ -340,7 +340,8 @@ export default function ReviewAndCalculateTaxes({
|
|
|
340
340
|
dev &&
|
|
341
341
|
(Object.keys(formik.errors).length > 0
|
|
342
342
|
? console.log("Formik errors", formik.errors)
|
|
343
|
-
: "No formik errors");
|
|
343
|
+
: console.log("No formik errors"));
|
|
344
|
+
|
|
344
345
|
setFormDisabled(Object.keys(formik.errors).length > 0);
|
|
345
346
|
}, [formik.errors]);
|
|
346
347
|
|
|
@@ -379,6 +380,7 @@ export default function ReviewAndCalculateTaxes({
|
|
|
379
380
|
>
|
|
380
381
|
{CollectExtraInfo && <CollectExtraInfo formik={formik} />}
|
|
381
382
|
<AddCard
|
|
383
|
+
cardRequired={cardRequired}
|
|
382
384
|
onSubmit={createOrderAndGetTaxes}
|
|
383
385
|
stacked={stacked}
|
|
384
386
|
formData={{
|
|
@@ -55,6 +55,7 @@ export type AddCardProps = {
|
|
|
55
55
|
};
|
|
56
56
|
stacked?: boolean;
|
|
57
57
|
error?: string;
|
|
58
|
+
cardRequired?: boolean;
|
|
58
59
|
address?: boolean;
|
|
59
60
|
onSubmit?: (
|
|
60
61
|
values: CreditCardValues & Partial<AddressValues>
|
|
@@ -71,6 +72,7 @@ export type AddCardProps = {
|
|
|
71
72
|
|
|
72
73
|
export const AddCard = ({
|
|
73
74
|
contact,
|
|
75
|
+
cardRequired = true,
|
|
74
76
|
error,
|
|
75
77
|
stacked = false,
|
|
76
78
|
address = true,
|
|
@@ -102,33 +104,37 @@ export const AddCard = ({
|
|
|
102
104
|
}
|
|
103
105
|
}
|
|
104
106
|
>
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
<div>
|
|
111
|
-
<TextField
|
|
112
|
-
sx={stacked ? { mt: 2 } : {}}
|
|
113
|
-
fullWidth
|
|
114
|
-
type="tel"
|
|
115
|
-
name="number"
|
|
116
|
-
label="Card Number"
|
|
117
|
-
required
|
|
118
|
-
onBlur={formik.handleBlur}
|
|
119
|
-
onChange={handleInputChange}
|
|
120
|
-
onFocus={handleInputFocus}
|
|
121
|
-
variant="outlined"
|
|
122
|
-
value={formik.values.number}
|
|
123
|
-
error={Boolean(formik.touched.number && formik.errors.number)}
|
|
124
|
-
helperText={formik.touched.number && formik.errors.number}
|
|
107
|
+
{cardRequired && (
|
|
108
|
+
<Cards
|
|
109
|
+
{...(formik.values as CreditCardValues)}
|
|
110
|
+
focused={formik.values.focus || "number"}
|
|
125
111
|
/>
|
|
112
|
+
)}
|
|
113
|
+
|
|
114
|
+
<Box sx={{ flexGrow: cardRequired ? undefined : 1 }}>
|
|
115
|
+
{cardRequired && (
|
|
116
|
+
<TextField
|
|
117
|
+
sx={stacked ? { mt: 2 } : {}}
|
|
118
|
+
fullWidth
|
|
119
|
+
type="tel"
|
|
120
|
+
name="number"
|
|
121
|
+
label="Card Number"
|
|
122
|
+
required
|
|
123
|
+
onBlur={formik.handleBlur}
|
|
124
|
+
onChange={handleInputChange}
|
|
125
|
+
onFocus={handleInputFocus}
|
|
126
|
+
variant="outlined"
|
|
127
|
+
value={formik.values.number}
|
|
128
|
+
error={Boolean(formik.touched.number && formik.errors.number)}
|
|
129
|
+
helperText={formik.touched.number && formik.errors.number}
|
|
130
|
+
/>
|
|
131
|
+
)}
|
|
126
132
|
<TextField
|
|
127
133
|
sx={{ mt: 2 }}
|
|
128
134
|
fullWidth
|
|
129
135
|
type="text"
|
|
130
136
|
name="name"
|
|
131
|
-
label="Name on Card"
|
|
137
|
+
label={cardRequired ? "Name on Card" : "Name"}
|
|
132
138
|
required
|
|
133
139
|
onBlur={formik.handleBlur}
|
|
134
140
|
onChange={handleInputChange}
|
|
@@ -138,104 +144,119 @@ export const AddCard = ({
|
|
|
138
144
|
error={Boolean(formik.touched.name && formik.errors.name)}
|
|
139
145
|
helperText={formik.touched.name && formik.errors.name}
|
|
140
146
|
/>
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
147
|
+
{cardRequired && (
|
|
148
|
+
<>
|
|
149
|
+
<TextField
|
|
150
|
+
sx={{ mt: 2, width: "calc(50% - 8px)", mr: 1 }}
|
|
151
|
+
type="tel"
|
|
152
|
+
name="expiry"
|
|
153
|
+
label="Valid Thru"
|
|
154
|
+
placeholder="MM/YY"
|
|
155
|
+
inputProps={{ pattern: "[0-9]{2}/[0-9]{2}" }}
|
|
156
|
+
required
|
|
157
|
+
onBlur={formik.handleBlur}
|
|
158
|
+
onChange={handleInputChange}
|
|
159
|
+
onFocus={handleInputFocus}
|
|
160
|
+
variant="outlined"
|
|
161
|
+
value={formik.values.expiry}
|
|
162
|
+
error={Boolean(formik.touched.expiry && formik.errors.expiry)}
|
|
163
|
+
helperText={
|
|
164
|
+
(formik.touched.expiry && formik.errors.expiry) || "MM/YY"
|
|
165
|
+
}
|
|
166
|
+
/>
|
|
167
|
+
<TextField
|
|
168
|
+
sx={{ mt: 2, width: "calc(50% - 8px)", ml: 1 }}
|
|
169
|
+
type="tel"
|
|
170
|
+
name="cvc"
|
|
171
|
+
label="CVC"
|
|
172
|
+
required
|
|
173
|
+
onBlur={formik.handleBlur}
|
|
174
|
+
onChange={handleInputChange}
|
|
175
|
+
onFocus={handleInputFocus}
|
|
176
|
+
variant="outlined"
|
|
177
|
+
value={formik.values.cvc}
|
|
178
|
+
error={Boolean(formik.touched.cvc && formik.errors.cvc)}
|
|
179
|
+
helperText={formik.touched.cvc && formik.errors.cvc}
|
|
180
|
+
/>
|
|
181
|
+
</>
|
|
182
|
+
)}
|
|
183
|
+
</Box>
|
|
174
184
|
{/* {formik.errors.submit && (
|
|
175
185
|
<Typography color="error" sx={{ mt: 2 }} variant="body2">
|
|
176
186
|
{formik.errors.submit}
|
|
177
187
|
</Typography>
|
|
178
188
|
)} */}
|
|
179
189
|
</Box>
|
|
180
|
-
|
|
181
|
-
sx={{ display: "flex", flexDirection: "row", gap: 2, width: "100%" }}
|
|
182
|
-
>
|
|
183
|
-
<Box sx={{ flexGrow: 1 }}>
|
|
184
|
-
{!address ? null : (
|
|
185
|
-
<Box>
|
|
186
|
-
<Typography variant="h6" sx={{ mt: 2, mb: 3 }}>
|
|
187
|
-
Billing Address
|
|
188
|
-
</Typography>
|
|
189
|
-
<AddressCountryField formik={formik} name="country" />
|
|
190
|
-
<AddressEmailField
|
|
191
|
-
formik={formik}
|
|
192
|
-
name="email"
|
|
193
|
-
sx={{ mt: 2 }}
|
|
194
|
-
/>
|
|
195
|
-
<AddressOrganizationNameField
|
|
196
|
-
sx={{ mt: 2 }}
|
|
197
|
-
formik={formik}
|
|
198
|
-
name="organization"
|
|
199
|
-
/>
|
|
200
|
-
<AddressStreetField
|
|
201
|
-
sx={{ mt: 2 }}
|
|
202
|
-
formik={formik}
|
|
203
|
-
name="line1"
|
|
204
|
-
lineNo="1"
|
|
205
|
-
/>
|
|
206
|
-
<AddressStreetField
|
|
207
|
-
sx={{ mt: 2 }}
|
|
208
|
-
formik={formik}
|
|
209
|
-
name="line2"
|
|
210
|
-
lineNo="2"
|
|
211
|
-
required={false}
|
|
212
|
-
/>
|
|
213
|
-
<AddressCityField sx={{ mt: 2 }} formik={formik} name="city" />
|
|
214
|
-
<AddressRegionField
|
|
215
|
-
sx={{ mt: 2 }}
|
|
216
|
-
formik={formik}
|
|
217
|
-
name="region"
|
|
218
|
-
/>
|
|
219
|
-
<AddressPostalCodeField
|
|
220
|
-
sx={{ mt: 2 }}
|
|
221
|
-
formik={formik}
|
|
222
|
-
name="postal_code"
|
|
223
|
-
/>
|
|
224
|
-
</Box>
|
|
225
|
-
)}
|
|
226
|
-
</Box>
|
|
190
|
+
{cardRequired && (
|
|
227
191
|
<Box
|
|
228
192
|
sx={{
|
|
229
|
-
mt: "16px",
|
|
230
193
|
display: "flex",
|
|
231
|
-
flexDirection: "
|
|
232
|
-
|
|
233
|
-
|
|
194
|
+
flexDirection: "row",
|
|
195
|
+
gap: 2,
|
|
196
|
+
width: "100%",
|
|
234
197
|
}}
|
|
235
198
|
>
|
|
236
|
-
{
|
|
199
|
+
<Box sx={{ flexGrow: 1 }}>
|
|
200
|
+
{!address ? null : (
|
|
201
|
+
<Box>
|
|
202
|
+
<Typography variant="h6" sx={{ mt: 2, mb: 3 }}>
|
|
203
|
+
Billing Address
|
|
204
|
+
</Typography>
|
|
205
|
+
<AddressCountryField formik={formik} name="country" />
|
|
206
|
+
<AddressEmailField
|
|
207
|
+
formik={formik}
|
|
208
|
+
name="email"
|
|
209
|
+
sx={{ mt: 2 }}
|
|
210
|
+
/>
|
|
211
|
+
<AddressOrganizationNameField
|
|
212
|
+
sx={{ mt: 2 }}
|
|
213
|
+
formik={formik}
|
|
214
|
+
name="organization"
|
|
215
|
+
/>
|
|
216
|
+
<AddressStreetField
|
|
217
|
+
sx={{ mt: 2 }}
|
|
218
|
+
formik={formik}
|
|
219
|
+
name="line1"
|
|
220
|
+
lineNo="1"
|
|
221
|
+
/>
|
|
222
|
+
<AddressStreetField
|
|
223
|
+
sx={{ mt: 2 }}
|
|
224
|
+
formik={formik}
|
|
225
|
+
name="line2"
|
|
226
|
+
lineNo="2"
|
|
227
|
+
required={false}
|
|
228
|
+
/>
|
|
229
|
+
<AddressCityField
|
|
230
|
+
sx={{ mt: 2 }}
|
|
231
|
+
formik={formik}
|
|
232
|
+
name="city"
|
|
233
|
+
/>
|
|
234
|
+
<AddressRegionField
|
|
235
|
+
sx={{ mt: 2 }}
|
|
236
|
+
formik={formik}
|
|
237
|
+
name="region"
|
|
238
|
+
/>
|
|
239
|
+
<AddressPostalCodeField
|
|
240
|
+
sx={{ mt: 2 }}
|
|
241
|
+
formik={formik}
|
|
242
|
+
name="postal_code"
|
|
243
|
+
/>
|
|
244
|
+
</Box>
|
|
245
|
+
)}
|
|
246
|
+
</Box>
|
|
247
|
+
<Box
|
|
248
|
+
sx={{
|
|
249
|
+
mt: "16px",
|
|
250
|
+
display: "flex",
|
|
251
|
+
flexDirection: "column",
|
|
252
|
+
alignItems: "flex-end",
|
|
253
|
+
flexGrow: 1,
|
|
254
|
+
}}
|
|
255
|
+
>
|
|
256
|
+
{PriceDetails}
|
|
257
|
+
</Box>
|
|
237
258
|
</Box>
|
|
238
|
-
|
|
259
|
+
)}
|
|
239
260
|
{error && (
|
|
240
261
|
<Typography color="error" sx={{ mt: 2 }} variant="body2">
|
|
241
262
|
{error}
|