@redotech/redo-hydrogen 1.1.0 → 1.1.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/CHANGELOG.md +7 -0
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/types.d.ts +14 -1
- package/package.json +1 -1
- package/src/components/redo-checkout-buttons.tsx +17 -3
- package/src/providers/redo-coverage-client.tsx +55 -4
- package/src/types.ts +25 -5
package/dist/types.d.ts
CHANGED
|
@@ -10,11 +10,13 @@ interface RedoCoverageClient {
|
|
|
10
10
|
disable(): Promise<boolean>;
|
|
11
11
|
get loading(): boolean;
|
|
12
12
|
get enabled(): boolean;
|
|
13
|
-
get
|
|
13
|
+
get eligible(): boolean;
|
|
14
|
+
get price(): number | undefined;
|
|
14
15
|
get storeId(): string | undefined;
|
|
15
16
|
get cart(): CartReturn | undefined;
|
|
16
17
|
get cartProduct(): CartProductVariantFragment | undefined;
|
|
17
18
|
get cartAttribute(): CartAttributeKey | undefined;
|
|
19
|
+
get errors(): RedoError[] | undefined;
|
|
18
20
|
}
|
|
19
21
|
type CartInfoToEnable = {
|
|
20
22
|
productId: string;
|
|
@@ -28,6 +30,17 @@ type RedoContextValue = {
|
|
|
28
30
|
storeId?: string;
|
|
29
31
|
cartInfoToEnable?: CartInfoToEnable;
|
|
30
32
|
cart?: CartReturn;
|
|
33
|
+
errors?: RedoError[];
|
|
34
|
+
};
|
|
35
|
+
declare enum RedoErrorType {
|
|
36
|
+
ApiBadRequest = "API_BAD_REQUEST",
|
|
37
|
+
ApiServerError = "API_SERVER_ERROR",
|
|
38
|
+
ApiUnknownError = "API_UNKNOWN_ERROR"
|
|
39
|
+
}
|
|
40
|
+
type RedoError = {
|
|
41
|
+
type: RedoErrorType;
|
|
42
|
+
message: string;
|
|
43
|
+
context: any;
|
|
31
44
|
};
|
|
32
45
|
|
|
33
46
|
declare const RedoProvider: ({ cart, storeId, children }: {
|
package/package.json
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
import { useRedoCoverageClient } from "../providers/redo-coverage-client";
|
|
8
8
|
import { CartInfoToEnable, RedoCoverageClient } from "../types";
|
|
9
9
|
import { REDO_PUBLIC_API_HOSTNAME } from "../utils/security";
|
|
10
|
+
import { CurrencyCode } from "@shopify/hydrogen-react/storefront-api-types";
|
|
10
11
|
|
|
11
12
|
type CheckoutButtonUIResponse = {
|
|
12
13
|
html: string;
|
|
@@ -44,6 +45,10 @@ const getButtonsToShow = ({
|
|
|
44
45
|
ui: json
|
|
45
46
|
});
|
|
46
47
|
|
|
48
|
+
if(!ui) {
|
|
49
|
+
return reject(null);
|
|
50
|
+
}
|
|
51
|
+
|
|
47
52
|
return resolve(ui);
|
|
48
53
|
});
|
|
49
54
|
});
|
|
@@ -58,10 +63,19 @@ const applyButtonVariables = ({
|
|
|
58
63
|
cart: CartReturn,
|
|
59
64
|
ui: CheckoutButtonUIResponse
|
|
60
65
|
}): CheckoutButtonUIResponse | null => {
|
|
66
|
+
if(!redoCoverageClient.eligible || !redoCoverageClient.price) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let currencyCode: CurrencyCode = cart.cost.totalAmount.currencyCode;
|
|
71
|
+
if(currencyCode === 'XXX') {
|
|
72
|
+
currencyCode = 'USD';
|
|
73
|
+
}
|
|
74
|
+
|
|
61
75
|
const cartContainsRedo = !!(cart.lines.nodes.some((cartItem) => cartItem.merchandise?.product?.vendor === 're:do'));
|
|
62
76
|
const combinedPrice = new Intl.NumberFormat('en-US', {
|
|
63
77
|
style: 'currency',
|
|
64
|
-
currency:
|
|
78
|
+
currency: currencyCode
|
|
65
79
|
}).format(Number(cart.cost.totalAmount.amount) + (cartContainsRedo ? 0 : redoCoverageClient.price));
|
|
66
80
|
|
|
67
81
|
if(!combinedPrice || !combinedPrice.length || combinedPrice.includes('NaN')) {
|
|
@@ -102,7 +116,7 @@ const RedoCheckoutButtons = (props: {
|
|
|
102
116
|
|
|
103
117
|
useEffect(() => {
|
|
104
118
|
(async () => {
|
|
105
|
-
if(!redoCoverageClient.
|
|
119
|
+
if(!redoCoverageClient.eligible || !cart || !redoCoverageClient.storeId) {
|
|
106
120
|
return;
|
|
107
121
|
}
|
|
108
122
|
|
|
@@ -111,7 +125,7 @@ const RedoCheckoutButtons = (props: {
|
|
|
111
125
|
setCheckoutButtonsUI(buttons);
|
|
112
126
|
}
|
|
113
127
|
})();
|
|
114
|
-
}, [cart, redoCoverageClient.price, redoCoverageClient.storeId]);
|
|
128
|
+
}, [cart, redoCoverageClient.eligible, redoCoverageClient.price, redoCoverageClient.storeId]);
|
|
115
129
|
|
|
116
130
|
const wrapperClickHandler = async (e: MouseEvent) => {
|
|
117
131
|
let clickedElement = e.target as HTMLElement;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useFetcher } from "@remix-run/react";
|
|
2
2
|
import { CartReturn } from "@shopify/hydrogen";
|
|
3
3
|
import { createContext, ReactNode, useContext, useEffect, useState } from "react";
|
|
4
|
-
import { CartProductVariantFragment, CartAttributeKey, CartInfoToEnable, RedoContextValue, RedoCoverageClient } from "../types";
|
|
4
|
+
import { CartProductVariantFragment, CartAttributeKey, CartInfoToEnable, RedoContextValue, RedoCoverageClient, RedoError, RedoErrorType } from "../types";
|
|
5
5
|
import { REDO_PUBLIC_API_HOSTNAME } from "../utils/security";
|
|
6
6
|
import { addProductToCartIfNeeded, removeProductFromCartIfNeeded, setCartRedoEnabledAttribute, useFetcherWithPromise } from "../utils/cart";
|
|
7
7
|
|
|
@@ -25,9 +25,18 @@ const RedoProvider = ({
|
|
|
25
25
|
const [cartAttribute, setCartAttribute] = useState<CartAttributeKey>();
|
|
26
26
|
const [cartInfoToEnable, setCartInfoToEnable] = useState<CartInfoToEnable>();
|
|
27
27
|
const [loading, setLoading] = useState<boolean>(true);
|
|
28
|
+
const [errors, setErrors] = useState<RedoError[]>([]);
|
|
29
|
+
|
|
30
|
+
const logUniqueError = (newError: RedoError) => {
|
|
31
|
+
if(errors.find((err) => err.type === newError.type)) {
|
|
32
|
+
} else {
|
|
33
|
+
setErrors([...errors, newError]);
|
|
34
|
+
}
|
|
35
|
+
return newError;
|
|
36
|
+
}
|
|
28
37
|
|
|
29
38
|
useEffect(() => {
|
|
30
|
-
if(!cart) {
|
|
39
|
+
if(!cart || !storeId) {
|
|
31
40
|
return;
|
|
32
41
|
}
|
|
33
42
|
|
|
@@ -68,6 +77,36 @@ const RedoProvider = ({
|
|
|
68
77
|
})
|
|
69
78
|
})
|
|
70
79
|
.then(async (res) => {
|
|
80
|
+
if(res.status === 500) {
|
|
81
|
+
logUniqueError({
|
|
82
|
+
type: RedoErrorType.ApiServerError,
|
|
83
|
+
message: "Internal server error occured when getting available coverage products from Redo API.. Check your inputs are correct and storeId have been configured. Reach out to Redo support if the issue persists.",
|
|
84
|
+
context: {
|
|
85
|
+
json: await res.json()
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
89
|
+
} else if(res.status === 400) {
|
|
90
|
+
logUniqueError({
|
|
91
|
+
type: RedoErrorType.ApiBadRequest,
|
|
92
|
+
message: "Bad request when getting available coverage products from Redo API. Check that the passed in cart is of the correct type Cart/CartReturn and includes all of the correct cart information.",
|
|
93
|
+
context: {
|
|
94
|
+
json: await res.json()
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
} else if(res.status !== 200) {
|
|
99
|
+
logUniqueError({
|
|
100
|
+
type: RedoErrorType.ApiUnknownError,
|
|
101
|
+
message: "Unkown error occured while getting available coverage products from Redo API.",
|
|
102
|
+
context: {
|
|
103
|
+
status: res.status,
|
|
104
|
+
json: await res.json()
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
71
110
|
let json = await res.json();
|
|
72
111
|
|
|
73
112
|
setLoading(false);
|
|
@@ -78,7 +117,7 @@ const RedoProvider = ({
|
|
|
78
117
|
|
|
79
118
|
setCartInfoToEnable(json.coverageProducts[0].cartInfoToEnable);
|
|
80
119
|
})
|
|
81
|
-
}, [cart]);
|
|
120
|
+
}, [cart, storeId]);
|
|
82
121
|
|
|
83
122
|
const contextVal: RedoContextValue = {
|
|
84
123
|
enabled: true,
|
|
@@ -86,6 +125,7 @@ const RedoProvider = ({
|
|
|
86
125
|
storeId,
|
|
87
126
|
cartInfoToEnable,
|
|
88
127
|
cart,
|
|
128
|
+
errors: (errors?.length && errors.length > 0) ? errors : undefined
|
|
89
129
|
};
|
|
90
130
|
|
|
91
131
|
return (
|
|
@@ -146,11 +186,19 @@ const useRedoCoverageClient = (): RedoCoverageClient => {
|
|
|
146
186
|
get loading() {
|
|
147
187
|
return redoContext.loading;
|
|
148
188
|
},
|
|
189
|
+
get eligible() {
|
|
190
|
+
return !this.loading && !!this.price && !!this.cartProduct;
|
|
191
|
+
},
|
|
149
192
|
get enabled() {
|
|
150
193
|
return redoContext.enabled;
|
|
151
194
|
},
|
|
152
195
|
get price() {
|
|
153
|
-
|
|
196
|
+
let priceToEnable = redoContext.cartInfoToEnable?.selectedVariant?.price?.amount;
|
|
197
|
+
if(!priceToEnable || Number(priceToEnable).toString() === 'NaN') {
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return Number(priceToEnable);
|
|
154
202
|
},
|
|
155
203
|
get cart() {
|
|
156
204
|
return redoContext.cart;
|
|
@@ -163,6 +211,9 @@ const useRedoCoverageClient = (): RedoCoverageClient => {
|
|
|
163
211
|
},
|
|
164
212
|
get storeId() {
|
|
165
213
|
return redoContext.storeId;
|
|
214
|
+
},
|
|
215
|
+
get errors() {
|
|
216
|
+
return redoContext.errors;
|
|
166
217
|
}
|
|
167
218
|
}
|
|
168
219
|
};
|
package/src/types.ts
CHANGED
|
@@ -12,11 +12,13 @@ interface RedoCoverageClient {
|
|
|
12
12
|
disable(): Promise<boolean>;
|
|
13
13
|
get loading(): boolean;
|
|
14
14
|
get enabled(): boolean;
|
|
15
|
-
get
|
|
15
|
+
get eligible(): boolean;
|
|
16
|
+
get price(): number | undefined;
|
|
16
17
|
get storeId(): string | undefined;
|
|
17
18
|
get cart(): CartReturn | undefined;
|
|
18
|
-
get cartProduct(): CartProductVariantFragment | undefined
|
|
19
|
-
get cartAttribute(): CartAttributeKey | undefined
|
|
19
|
+
get cartProduct(): CartProductVariantFragment | undefined;
|
|
20
|
+
get cartAttribute(): CartAttributeKey | undefined;
|
|
21
|
+
get errors(): RedoError[] | undefined;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
type CartInfoToEnable = {
|
|
@@ -31,13 +33,31 @@ type RedoContextValue = {
|
|
|
31
33
|
loading: boolean,
|
|
32
34
|
storeId?: string,
|
|
33
35
|
cartInfoToEnable?: CartInfoToEnable,
|
|
34
|
-
cart?: CartReturn
|
|
36
|
+
cart?: CartReturn,
|
|
37
|
+
errors?: RedoError[],
|
|
35
38
|
};
|
|
36
39
|
|
|
40
|
+
enum RedoErrorType {
|
|
41
|
+
ApiBadRequest = "API_BAD_REQUEST",
|
|
42
|
+
ApiServerError = "API_SERVER_ERROR",
|
|
43
|
+
ApiUnknownError = "API_UNKNOWN_ERROR"
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
type RedoError = {
|
|
47
|
+
type: RedoErrorType,
|
|
48
|
+
message: string,
|
|
49
|
+
context: any
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export {
|
|
53
|
+
RedoErrorType,
|
|
54
|
+
}
|
|
55
|
+
|
|
37
56
|
export type {
|
|
38
57
|
CartAttributeKey,
|
|
39
58
|
CartInfoToEnable,
|
|
40
59
|
RedoContextValue,
|
|
41
60
|
RedoCoverageClient,
|
|
42
|
-
CartProductVariantFragment
|
|
61
|
+
CartProductVariantFragment,
|
|
62
|
+
RedoError
|
|
43
63
|
}
|