@tapcart/mobile-components 0.7.27 → 0.7.29
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/components/hooks/use-customer.d.ts +10 -0
- package/dist/components/hooks/use-customer.d.ts.map +1 -0
- package/dist/components/hooks/use-customer.js +24 -0
- package/dist/components/hooks/use-nosto-recommendation.d.ts +9 -1
- package/dist/components/hooks/use-nosto-recommendation.d.ts.map +1 -1
- package/dist/components/hooks/use-nosto-recommendation.js +138 -53
- package/dist/components/hooks/use-nosto-recommendation.queries.d.ts +48 -0
- package/dist/components/hooks/use-nosto-recommendation.queries.d.ts.map +1 -0
- package/dist/components/hooks/use-nosto-recommendation.queries.js +143 -0
- package/dist/components/hooks/use-nosto-recommendation.test.d.ts +2 -0
- package/dist/components/hooks/use-nosto-recommendation.test.d.ts.map +1 -0
- package/dist/components/hooks/use-nosto-recommendation.test.js +248 -0
- package/dist/components/hooks/use-recommendations.d.ts.map +1 -1
- package/dist/components/hooks/use-recommendations.js +1 -2
- package/dist/components/ui/apple-pay-button.d.ts +24 -0
- package/dist/components/ui/apple-pay-button.d.ts.map +1 -0
- package/dist/components/ui/apple-pay-button.js +121 -0
- package/dist/components/ui/drawer.js +1 -1
- package/dist/components/ui/price.js +1 -1
- package/dist/styles.css +3 -3
- package/package.json +4 -2
- package/dist/components/contexts/translationContext.d.ts +0 -9
- package/dist/components/contexts/translationContext.d.ts.map +0 -1
- package/dist/components/contexts/translationContext.js +0 -5
- package/dist/components/hooks/use-destination.d.ts +0 -23
- package/dist/components/hooks/use-destination.d.ts.map +0 -1
- package/dist/components/hooks/use-destination.js +0 -13
- package/dist/components/ui/use-tap.d.ts +0 -8
- package/dist/components/ui/use-tap.d.ts.map +0 -1
- package/dist/components/ui/use-tap.js +0 -100
- package/dist/components/ui/video copy.d.ts +0 -18
- package/dist/components/ui/video copy.d.ts.map +0 -1
- package/dist/components/ui/video copy.js +0 -70
- package/dist/components/ui/video.v2.d.ts +0 -18
- package/dist/components/ui/video.v2.d.ts.map +0 -1
- package/dist/components/ui/video.v2.js +0 -70
- package/dist/index copy.d.ts +0 -59
- package/dist/index copy.d.ts.map +0 -1
- package/dist/index copy.js +0 -59
- package/dist/lib/utils/destination.d.ts +0 -17
- package/dist/lib/utils/destination.d.ts.map +0 -1
- package/dist/lib/utils/destination.js +0 -15
- package/dist/lib/utils/id.d.ts +0 -5
- package/dist/lib/utils/id.d.ts.map +0 -1
- package/dist/lib/utils/id.js +0 -29
- package/dist/lib/utils/index.d.ts +0 -18
- package/dist/lib/utils/index.d.ts.map +0 -1
- package/dist/lib/utils/index.js +0 -55
- package/dist/lib/utils/misc.d.ts +0 -1
- package/dist/lib/utils/misc.d.ts.map +0 -1
- package/dist/lib/utils/misc.js +0 -1
- package/dist/lib/utils/style.d.ts +0 -154
- package/dist/lib/utils/style.d.ts.map +0 -1
- package/dist/lib/utils/style.js +0 -148
- package/dist/lib/utils.deprecated.d.ts +0 -181
- package/dist/lib/utils.deprecated.d.ts.map +0 -1
- package/dist/lib/utils.deprecated.js +0 -222
- package/dist/v2.d.ts +0 -59
- package/dist/v2.d.ts.map +0 -1
- package/dist/v2.js +0 -59
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { renderHook } from "@testing-library/react-hooks";
|
|
11
|
+
import { NostoRecommendationsType, useNostoRecommendations, } from "./use-nosto-recommendation";
|
|
12
|
+
import { useProducts } from "./use-products";
|
|
13
|
+
jest.mock("./use-products", () => ({
|
|
14
|
+
useProducts: jest.fn(),
|
|
15
|
+
}));
|
|
16
|
+
// Mock fetch for GraphQL queries
|
|
17
|
+
global.fetch = jest.fn((url, options) => {
|
|
18
|
+
const body = JSON.parse(options === null || options === void 0 ? void 0 : options.body);
|
|
19
|
+
if (body.query.includes("newSession")) {
|
|
20
|
+
return Promise.resolve({
|
|
21
|
+
json: () => Promise.resolve({ data: { newSession: "mockSessionId" } }),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (body.query.includes("GetFrontPageRecommendations")) {
|
|
25
|
+
return Promise.resolve({
|
|
26
|
+
json: () => Promise.resolve({
|
|
27
|
+
data: {
|
|
28
|
+
updateSession: {
|
|
29
|
+
pages: {
|
|
30
|
+
forFrontPage: [{ primary: [{ productId: "front-page-id-1" }] }],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (body.query.includes("GetBestSellersRecommendations")) {
|
|
38
|
+
return Promise.resolve({
|
|
39
|
+
json: () => Promise.resolve({
|
|
40
|
+
data: {
|
|
41
|
+
recos: {
|
|
42
|
+
toplist: {
|
|
43
|
+
primary: [{ name: "Product 1", productId: "best-seller-1" }],
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (body.query.includes("GetRelatedProductsRecommendations")) {
|
|
51
|
+
return Promise.resolve({
|
|
52
|
+
json: () => Promise.resolve({
|
|
53
|
+
data: {
|
|
54
|
+
recos: {
|
|
55
|
+
related: {
|
|
56
|
+
primary: [{ productId: "related-1" }],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
}),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (body.query.includes("GetProductPageRecommendations")) {
|
|
64
|
+
return Promise.resolve({
|
|
65
|
+
json: () => Promise.resolve({
|
|
66
|
+
data: {
|
|
67
|
+
updateSession: {
|
|
68
|
+
pages: {
|
|
69
|
+
forProductPage: [
|
|
70
|
+
{ primary: [{ productId: "product-page-id-1" }] },
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
}),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
if (body.query.includes("CategoryPageRecommendations")) {
|
|
79
|
+
return Promise.resolve({
|
|
80
|
+
json: () => Promise.resolve({
|
|
81
|
+
data: {
|
|
82
|
+
updateSession: {
|
|
83
|
+
pages: {
|
|
84
|
+
forCategoryPage: [
|
|
85
|
+
{ primary: [{ productId: "category-page-id-1" }] },
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
}),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return Promise.reject(new Error("Unknown query"));
|
|
94
|
+
});
|
|
95
|
+
describe("useNostoRecommendations", () => {
|
|
96
|
+
const mockIntegrations = [
|
|
97
|
+
{
|
|
98
|
+
name: "nosto",
|
|
99
|
+
key: "mockNostoKey",
|
|
100
|
+
enabled: true,
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
const mockBaseURL = "http://mockbaseurl.com";
|
|
104
|
+
beforeEach(() => {
|
|
105
|
+
jest.clearAllMocks();
|
|
106
|
+
useProducts.mockReturnValue({
|
|
107
|
+
products: [{ id: "1", name: "Product 1" }],
|
|
108
|
+
isLoading: false,
|
|
109
|
+
error: null,
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
it("should return front page recommendations if productIds is empty and slotId is provided", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
113
|
+
const slotId = "mockSlotId";
|
|
114
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, slotId, undefined, undefined, undefined));
|
|
115
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
116
|
+
expect(result.current.isLoading).toBe(false);
|
|
117
|
+
expect(result.current.error).toBe(null);
|
|
118
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
119
|
+
productIds: ["front-page-id-1"],
|
|
120
|
+
baseURL: mockBaseURL,
|
|
121
|
+
productHandles: [],
|
|
122
|
+
});
|
|
123
|
+
}));
|
|
124
|
+
it("should return best sellers recommendations if productIds is empty and slotId is not provided", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
125
|
+
const slotId = "";
|
|
126
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, slotId, undefined, undefined));
|
|
127
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
128
|
+
expect(result.current.error).toBe(null);
|
|
129
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
130
|
+
productIds: ["best-seller-1"],
|
|
131
|
+
baseURL: mockBaseURL,
|
|
132
|
+
productHandles: [],
|
|
133
|
+
});
|
|
134
|
+
}));
|
|
135
|
+
it("should return best sellers recommendations if productIds is not empty, Best Sellers is the recommendation type and slotId is not provided", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
136
|
+
const slotId = "";
|
|
137
|
+
const productIds = ["mockProductId"];
|
|
138
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, slotId, NostoRecommendationsType.BEST_SELLERS, productIds));
|
|
139
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
140
|
+
expect(result.current.error).toBe(null);
|
|
141
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
142
|
+
productIds: ["best-seller-1"],
|
|
143
|
+
baseURL: mockBaseURL,
|
|
144
|
+
productHandles: [],
|
|
145
|
+
});
|
|
146
|
+
}));
|
|
147
|
+
it("should return default front page recommendations if slotId is provided but layoutType is not", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
148
|
+
const slotId = "mockSlotId";
|
|
149
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, slotId));
|
|
150
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
151
|
+
expect(result.current.error).toBe(null);
|
|
152
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
153
|
+
productIds: ["front-page-id-1"],
|
|
154
|
+
baseURL: mockBaseURL,
|
|
155
|
+
productHandles: [],
|
|
156
|
+
});
|
|
157
|
+
}));
|
|
158
|
+
it("should return the correct recommendations for best sellers", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
159
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, "", NostoRecommendationsType.BEST_SELLERS, undefined, undefined));
|
|
160
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
161
|
+
expect(result.current.error).toBe(null);
|
|
162
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
163
|
+
productIds: ["best-seller-1"],
|
|
164
|
+
baseURL: mockBaseURL,
|
|
165
|
+
productHandles: [],
|
|
166
|
+
});
|
|
167
|
+
}));
|
|
168
|
+
it("should return the related recommendations when only productIds and a recommendation type are provided on a non-home layout", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
169
|
+
const productIds = ["mockProductId"];
|
|
170
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, "", NostoRecommendationsType.VIEWED_TOGETHER, productIds, undefined));
|
|
171
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
172
|
+
expect(result.current.error).toBe(null);
|
|
173
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
174
|
+
productIds: ["related-1"],
|
|
175
|
+
baseURL: mockBaseURL,
|
|
176
|
+
productHandles: [],
|
|
177
|
+
});
|
|
178
|
+
}));
|
|
179
|
+
it("should return the correct recommendations when productIds and slotIds are provided", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
180
|
+
const slotId = "mockSlotId";
|
|
181
|
+
const productIds = ["mockProductId"];
|
|
182
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, slotId, NostoRecommendationsType.VIEWED_TOGETHER, productIds, undefined));
|
|
183
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
184
|
+
expect(result.current.error).toBe(null);
|
|
185
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
186
|
+
productIds: ["product-page-id-1"],
|
|
187
|
+
baseURL: mockBaseURL,
|
|
188
|
+
productHandles: [],
|
|
189
|
+
});
|
|
190
|
+
}));
|
|
191
|
+
it("should return the related products fallback recommendations when productIds are provided and no slotId and a type other than viewed_category and best_sellers is provided", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
192
|
+
const productIds = ["mockProductId"];
|
|
193
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, "", NostoRecommendationsType.VIEWED_TOGETHER, productIds, undefined));
|
|
194
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
195
|
+
expect(result.current.error).toBe(null);
|
|
196
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
197
|
+
productIds: ["related-1"],
|
|
198
|
+
baseURL: mockBaseURL,
|
|
199
|
+
productHandles: [],
|
|
200
|
+
});
|
|
201
|
+
}));
|
|
202
|
+
it("should return the category fallback recommendations when no slotId, productIds are provided and a recommendation type of viewed_category is provided", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
203
|
+
const productIds = ["mockProductId"];
|
|
204
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, "", NostoRecommendationsType.VIEWED_CATEGORY, productIds, undefined));
|
|
205
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
206
|
+
expect(result.current.error).toBe(null);
|
|
207
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
208
|
+
productIds: ["category-page-id-1"],
|
|
209
|
+
baseURL: mockBaseURL,
|
|
210
|
+
productHandles: [],
|
|
211
|
+
});
|
|
212
|
+
}));
|
|
213
|
+
it("should handle loading state", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
214
|
+
const { result } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, ""));
|
|
215
|
+
expect(result.current.isLoading).toBe(true);
|
|
216
|
+
}));
|
|
217
|
+
it("should handle error state", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
218
|
+
const mockError = () => "Failed to fetch products";
|
|
219
|
+
useProducts.mockReturnValue({
|
|
220
|
+
products: [],
|
|
221
|
+
isLoading: false,
|
|
222
|
+
error: mockError,
|
|
223
|
+
});
|
|
224
|
+
const { result, waitForNextUpdate } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL));
|
|
225
|
+
yield waitForNextUpdate();
|
|
226
|
+
expect(result.current.error).toBe(mockError);
|
|
227
|
+
}));
|
|
228
|
+
it("should default to best sellers if productIds are empty but a recommendation type other than Best Sellers is used", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
229
|
+
const productIds = [];
|
|
230
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, "", NostoRecommendationsType.VIEWED_TOGETHER, productIds, undefined));
|
|
231
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
232
|
+
expect(result.current.error).toBe(null);
|
|
233
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
234
|
+
productIds: ["best-seller-1"],
|
|
235
|
+
baseURL: mockBaseURL,
|
|
236
|
+
productHandles: [],
|
|
237
|
+
});
|
|
238
|
+
}));
|
|
239
|
+
it("should return an empty array if skip is true", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
240
|
+
const { result, waitFor } = renderHook(() => useNostoRecommendations(mockIntegrations, mockBaseURL, "", NostoRecommendationsType.BEST_SELLERS, undefined, true));
|
|
241
|
+
yield waitFor(() => result.current.isLoading === false);
|
|
242
|
+
expect(useProducts).toHaveBeenCalledWith({
|
|
243
|
+
productIds: [],
|
|
244
|
+
baseURL: mockBaseURL,
|
|
245
|
+
productHandles: [],
|
|
246
|
+
});
|
|
247
|
+
}));
|
|
248
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-recommendations.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-recommendations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAKtD,UAAU,sBAAsB;IAC9B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACnC,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,GAAG,CAAA;CACX;AAOD,QAAA,MAAM,kBAAkB,+BAGrB,sBAAsB,KAAG,
|
|
1
|
+
{"version":3,"file":"use-recommendations.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-recommendations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAKtD,UAAU,sBAAsB;IAC9B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACnC,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,uBAAuB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,GAAG,CAAA;CACX;AAOD,QAAA,MAAM,kBAAkB,+BAGrB,sBAAsB,KAAG,uBAgC3B,CAAA;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
|
|
@@ -8,7 +8,6 @@ const constructURL = (apiURL) => {
|
|
|
8
8
|
const useRecommendations = ({ queryVariables, apiURL }) => {
|
|
9
9
|
const searchParams = useSearchParams();
|
|
10
10
|
const recommendation = (searchParams === null || searchParams === void 0 ? void 0 : searchParams.get('recommendation')) || "*";
|
|
11
|
-
const isBestSeller = recommendation === "*";
|
|
12
11
|
const fetcher = (body) => fetch(constructURL(apiURL), {
|
|
13
12
|
method: "POST",
|
|
14
13
|
body: JSON.stringify(body),
|
|
@@ -24,7 +23,7 @@ const useRecommendations = ({ queryVariables, apiURL }) => {
|
|
|
24
23
|
return {
|
|
25
24
|
products: data === null || data === void 0 ? void 0 : data.products,
|
|
26
25
|
collections: data === null || data === void 0 ? void 0 : data.collections,
|
|
27
|
-
searches:
|
|
26
|
+
searches: data === null || data === void 0 ? void 0 : data.searches,
|
|
28
27
|
isLoading: isLoading,
|
|
29
28
|
error: error
|
|
30
29
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/// <reference types="applepayjs" />
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export type ApplePayButtonType = 'plain' | 'add-money' | 'book' | 'buy' | 'check-out' | 'continue' | 'contribute' | 'donate' | 'order' | 'pay' | 'reload' | 'rent' | 'set-up' | 'subscribe' | 'support' | 'tip' | 'top-up';
|
|
4
|
+
export type ApplePayButtonStyle = 'black' | 'white' | 'white-outline';
|
|
5
|
+
export interface ApplePayButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
6
|
+
displayName: string;
|
|
7
|
+
amount: number;
|
|
8
|
+
startSessionURL: string;
|
|
9
|
+
appId: string;
|
|
10
|
+
domainName: string;
|
|
11
|
+
countryCode?: string;
|
|
12
|
+
currencyCode?: string;
|
|
13
|
+
merchantCapabilities?: ApplePayJS.ApplePayMerchantCapability[];
|
|
14
|
+
supportedNetworks?: string[];
|
|
15
|
+
buttonType?: ApplePayButtonType;
|
|
16
|
+
buttonStyle?: ApplePayButtonStyle;
|
|
17
|
+
onPaymentAuthorized?: (paymentData: ApplePayJS.ApplePayPayment) => void;
|
|
18
|
+
}
|
|
19
|
+
declare const ApplePayButton: {
|
|
20
|
+
({ displayName, amount, startSessionURL, appId, domainName, countryCode, currencyCode, merchantCapabilities, supportedNetworks, buttonType, buttonStyle, onPaymentAuthorized, }: ApplePayButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
displayName: string;
|
|
22
|
+
};
|
|
23
|
+
export { ApplePayButton };
|
|
24
|
+
//# sourceMappingURL=apple-pay-button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apple-pay-button.d.ts","sourceRoot":"","sources":["../../../components/ui/apple-pay-button.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE3N,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,OAAO,GAAG,eAAe,CAAA;AAErE,MAAM,WAAW,mBACf,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,UAAU,CAAC,0BAA0B,EAAE,CAAC;IAC/D,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,mBAAmB,CAAC,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC,eAAe,KAAK,IAAI,CAAC;CACzE;AAED,QAAA,MAAM,cAAc;qLAcf,mBAAmB;;CA2IvB,CAAA;AAID,OAAO,EAAE,cAAc,EAAE,CAAA"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
import * as React from "react";
|
|
12
|
+
import ApplePayButtonComponent from 'apple-pay-button';
|
|
13
|
+
const ApplePayButton = ({ displayName, amount, startSessionURL, appId, domainName, countryCode = 'US', currencyCode = 'USD', merchantCapabilities = ["supports3DS"], supportedNetworks = ["visa", "masterCard", "amex", "discover"], buttonType = 'plain', buttonStyle = 'white-outline', onPaymentAuthorized, }) => {
|
|
14
|
+
const [paymentDataResult, setPaymentDataResult] = React.useState("");
|
|
15
|
+
const onClick = () => {
|
|
16
|
+
const applePayRequest = {
|
|
17
|
+
countryCode,
|
|
18
|
+
currencyCode,
|
|
19
|
+
merchantCapabilities,
|
|
20
|
+
supportedNetworks,
|
|
21
|
+
total: {
|
|
22
|
+
label: displayName,
|
|
23
|
+
type: "final",
|
|
24
|
+
amount: amount.toString(),
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const session = new ApplePaySession(3, applePayRequest);
|
|
28
|
+
handleEventsForApplePay(session);
|
|
29
|
+
session.begin();
|
|
30
|
+
};
|
|
31
|
+
const defaultFetcher = (url, body) => fetch(url, {
|
|
32
|
+
method: body ? "POST" : "GET",
|
|
33
|
+
headers: {
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
},
|
|
36
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
37
|
+
}).then((res) => res.json());
|
|
38
|
+
const validateMerchant = (validationURL, appId, domainName, displayName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
+
let url = startSessionURL;
|
|
40
|
+
let body = {
|
|
41
|
+
validationURL,
|
|
42
|
+
appId,
|
|
43
|
+
domainName,
|
|
44
|
+
displayName
|
|
45
|
+
};
|
|
46
|
+
console.log("request body", body);
|
|
47
|
+
const response = yield defaultFetcher(url, body);
|
|
48
|
+
return response.data;
|
|
49
|
+
});
|
|
50
|
+
const handleEventsForApplePay = (session) => {
|
|
51
|
+
session.onvalidatemerchant = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
52
|
+
const response = yield validateMerchant(event.validationURL, appId, domainName, displayName);
|
|
53
|
+
if (response) {
|
|
54
|
+
session.completeMerchantValidation(response);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.error("Error during validating merchant");
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
session.onpaymentmethodselected = (event) => {
|
|
61
|
+
const update = {
|
|
62
|
+
newTotal: {
|
|
63
|
+
label: displayName,
|
|
64
|
+
type: "final",
|
|
65
|
+
amount: amount.toString(),
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
session.completePaymentMethodSelection(update);
|
|
69
|
+
};
|
|
70
|
+
session.onshippingmethodselected = (event) => {
|
|
71
|
+
const update = {
|
|
72
|
+
newTotal: {
|
|
73
|
+
label: displayName,
|
|
74
|
+
type: "final",
|
|
75
|
+
amount: amount.toString(),
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
session.completeShippingMethodSelection(update);
|
|
79
|
+
};
|
|
80
|
+
session.onshippingcontactselected = (event) => {
|
|
81
|
+
const update = {
|
|
82
|
+
newTotal: {
|
|
83
|
+
label: displayName,
|
|
84
|
+
type: "final",
|
|
85
|
+
amount: amount.toString(),
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
session.completeShippingContactSelection(update);
|
|
89
|
+
};
|
|
90
|
+
session.onpaymentauthorized = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
91
|
+
const paymentData = event.payment;
|
|
92
|
+
if (onPaymentAuthorized) { // Call the callback if provided
|
|
93
|
+
onPaymentAuthorized(paymentData);
|
|
94
|
+
}
|
|
95
|
+
if (paymentData.token) {
|
|
96
|
+
const paymentDataJson = JSON.stringify(paymentData.token, null, 2);
|
|
97
|
+
console.log("paymentData", paymentDataJson);
|
|
98
|
+
setPaymentDataResult(paymentDataJson);
|
|
99
|
+
const result = {
|
|
100
|
+
status: ApplePaySession.STATUS_SUCCESS,
|
|
101
|
+
};
|
|
102
|
+
session.completePayment(result);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const result = {
|
|
106
|
+
status: ApplePaySession.STATUS_FAILURE,
|
|
107
|
+
};
|
|
108
|
+
session.completePayment(result);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
session.oncancel = (event) => {
|
|
112
|
+
console.log("Session Cancelled.");
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
return (_jsxs("div", { children: [_jsx("div", Object.assign({ className: "flex flex-row justify-center items-center pt-40" }, { children: _jsx(ApplePayButtonComponent, { onClick: onClick, style: {
|
|
116
|
+
height: "48px",
|
|
117
|
+
borderRadius: '4px',
|
|
118
|
+
}, type: buttonType, buttonStyle: buttonStyle }) })), _jsx("div", Object.assign({ className: "w-100 overflow-auto" }, { children: _jsx("pre", Object.assign({ className: "whitespace-pre-wrap break-words" }, { children: paymentDataResult })) }))] }));
|
|
119
|
+
};
|
|
120
|
+
ApplePayButton.displayName = "ApplePayButton";
|
|
121
|
+
export { ApplePayButton };
|
|
@@ -25,7 +25,7 @@ const DrawerPortal = ({ children, containerRef }) => {
|
|
|
25
25
|
}
|
|
26
26
|
// If no ref is passed, attempt to look for the dashboard specific block container.
|
|
27
27
|
// This will only be valid within the CMS Dashboard.
|
|
28
|
-
const dashboardContainer = document.querySelector("#_tcDashboard-BlockPhonePreview");
|
|
28
|
+
const dashboardContainer = typeof document !== "undefined" && document.querySelector("#_tcDashboard-BlockPhonePreview");
|
|
29
29
|
if (dashboardContainer) {
|
|
30
30
|
return ReactDOM.createPortal(children, dashboardContainer);
|
|
31
31
|
}
|
|
@@ -7,7 +7,7 @@ function Price({ price, priceHigh, priceRanges = false, isSale = false, compareA
|
|
|
7
7
|
const ProductPrice = () => {
|
|
8
8
|
const priceStyles = (!isSale || !compareAtPrice) ? standardStyles : saleStyles;
|
|
9
9
|
const colorClass = isSale ? 'text-textColors-salePriceText' : 'text-textColors-priceText';
|
|
10
|
-
return (_jsx(Text, Object.assign({ className: `${colorClass} flex-shrink-0`, style: { fontSize: `${fontSize}px` } }, { children: _jsxs("span", Object.assign({ className: "flex-grow min-w-[fit-content]" }, { children: [_jsx(Money, { price: price, currency: currency, locale: locale, styles: priceStyles, hideZeroCents: hideZeroCents }), priceRanges && priceHigh !== undefined && _jsx(Spacer, {}), priceRanges && priceHigh !== undefined && (_jsx(Money, { price: priceHigh, currency: currency, locale: locale, styles: priceStyles, hideZeroCents: hideZeroCents }))] })) })));
|
|
10
|
+
return (_jsx(Text, Object.assign({ className: `${colorClass} flex-shrink-0 w-full`, style: { fontSize: `${fontSize}px` } }, { children: _jsxs("span", Object.assign({ className: "flex-grow min-w-[fit-content] break-all" }, { children: [_jsx(Money, { price: price, currency: currency, locale: locale, styles: priceStyles, hideZeroCents: hideZeroCents }), priceRanges && priceHigh !== undefined && _jsx(Spacer, {}), priceRanges && priceHigh !== undefined && (_jsx(Money, { price: priceHigh, currency: currency, locale: locale, styles: priceStyles, hideZeroCents: hideZeroCents }))] })) })));
|
|
11
11
|
};
|
|
12
12
|
const StrikeThroughPrice = () => {
|
|
13
13
|
if (!isSale || !compareAtPrice)
|
package/dist/styles.css
CHANGED
|
@@ -1002,9 +1002,6 @@ video {
|
|
|
1002
1002
|
.min-h-\[24px\] {
|
|
1003
1003
|
min-height: 24px;
|
|
1004
1004
|
}
|
|
1005
|
-
.min-h-\[315px\] {
|
|
1006
|
-
min-height: 315px;
|
|
1007
|
-
}
|
|
1008
1005
|
.w-0 {
|
|
1009
1006
|
width: 0px;
|
|
1010
1007
|
}
|
|
@@ -1372,6 +1369,9 @@ video {
|
|
|
1372
1369
|
.break-words {
|
|
1373
1370
|
overflow-wrap: break-word;
|
|
1374
1371
|
}
|
|
1372
|
+
.break-all {
|
|
1373
|
+
word-break: break-all;
|
|
1374
|
+
}
|
|
1375
1375
|
.rounded {
|
|
1376
1376
|
border-radius: 0.25rem;
|
|
1377
1377
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tapcart/mobile-components",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.29",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"style": "dist/styles.css",
|
|
@@ -39,12 +39,14 @@
|
|
|
39
39
|
"eslint": "^7.32.0",
|
|
40
40
|
"eslint-config-custom": "workspace:*",
|
|
41
41
|
"jest": "^29.7.0",
|
|
42
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
42
43
|
"postcss": "^8.4.24",
|
|
43
44
|
"tailwindcss": "^3.3.2",
|
|
44
45
|
"ts-jest": "^29.2.5",
|
|
45
46
|
"tsc-alias": "^1.8.10",
|
|
46
47
|
"tsconfig": "workspace:*",
|
|
47
|
-
"typescript": "^4.5.2"
|
|
48
|
+
"typescript": "^4.5.2",
|
|
49
|
+
"@testing-library/react-hooks": "^8.0.1"
|
|
48
50
|
},
|
|
49
51
|
"dependencies": {
|
|
50
52
|
"@radix-ui/react-accordion": "^1.1.2",
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
type TranslationMap = Record<string, string>;
|
|
3
|
-
export declare const TranslationProvider: ({ translations, children, }: {
|
|
4
|
-
translations: TranslationMap;
|
|
5
|
-
children: React.ReactNode;
|
|
6
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
export declare const useTranslation: () => TranslationMap;
|
|
8
|
-
export {};
|
|
9
|
-
//# sourceMappingURL=translationContext.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"translationContext.d.ts","sourceRoot":"","sources":["../../../components/contexts/translationContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAA;AAExD,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAI5C,eAAO,MAAM,mBAAmB;kBAIhB,cAAc;cAClB,MAAM,SAAS;6CAK1B,CAAA;AAED,eAAO,MAAM,cAAc,sBAAuC,CAAA"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext } from "react";
|
|
3
|
-
const TranslationContext = createContext({});
|
|
4
|
-
export const TranslationProvider = ({ translations, children, }) => (_jsx(TranslationContext.Provider, Object.assign({ value: translations }, { children: children })));
|
|
5
|
-
export const useTranslation = () => useContext(TranslationContext);
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
type OpenProductFn = (arg: {
|
|
2
|
-
productId: string;
|
|
3
|
-
}) => void;
|
|
4
|
-
type OpenCollectionFn = (arg: {
|
|
5
|
-
collectionId: string;
|
|
6
|
-
}) => void;
|
|
7
|
-
type OpenScreenFn = (arg: {
|
|
8
|
-
destination: {
|
|
9
|
-
type: "internal" | "web";
|
|
10
|
-
url: string;
|
|
11
|
-
};
|
|
12
|
-
}) => void;
|
|
13
|
-
type DestinationType = "product" | "collection" | "url" | "app-screen";
|
|
14
|
-
interface UseDestinationProps {
|
|
15
|
-
openProduct: OpenProductFn;
|
|
16
|
-
openCollection: OpenCollectionFn;
|
|
17
|
-
openScreen: OpenScreenFn;
|
|
18
|
-
type: DestinationType;
|
|
19
|
-
location: string;
|
|
20
|
-
}
|
|
21
|
-
export declare const useDestination: ({ openProduct, openCollection, openScreen, type, location, }: UseDestinationProps) => (() => void);
|
|
22
|
-
export {};
|
|
23
|
-
//# sourceMappingURL=use-destination.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-destination.d.ts","sourceRoot":"","sources":["../../../components/hooks/use-destination.ts"],"names":[],"mappings":"AAEA,KAAK,aAAa,GAAG,CAAC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAA;AACzD,KAAK,gBAAgB,GAAG,CAAC,GAAG,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAA;AAC/D,KAAK,YAAY,GAAG,CAAC,GAAG,EAAE;IACxB,WAAW,EAAE;QAAE,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CACvD,KAAK,IAAI,CAAA;AAEV,KAAK,eAAe,GAAG,SAAS,GAAG,YAAY,GAAG,KAAK,GAAG,YAAY,CAAA;AAEtE,UAAU,mBAAmB;IAC3B,WAAW,EAAE,aAAa,CAAA;IAC1B,cAAc,EAAE,gBAAgB,CAAA;IAChC,UAAU,EAAE,YAAY,CAAA;IACxB,IAAI,EAAE,eAAe,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,cAAc,iEAMxB,mBAAmB,KAAG,CAAC,MAAM,IAAI,CAYnC,CAAA"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
export const useDestination = ({ openProduct, openCollection, openScreen, type, location, }) => {
|
|
3
|
-
switch (type) {
|
|
4
|
-
case "product":
|
|
5
|
-
return () => openProduct({ productId: location });
|
|
6
|
-
case "collection":
|
|
7
|
-
return () => openCollection({ collectionId: location });
|
|
8
|
-
case "url":
|
|
9
|
-
return () => openScreen({ destination: { type: "web", url: location } });
|
|
10
|
-
case "app-screen":
|
|
11
|
-
return () => openScreen({ destination: { type: "internal", url: location } });
|
|
12
|
-
}
|
|
13
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
declare const useTap: (tapThreshold?: number) => {
|
|
3
|
-
onTap: (handler: (event: any) => void) => (event: any) => void;
|
|
4
|
-
isPressed: boolean;
|
|
5
|
-
ref: React.MutableRefObject<null>;
|
|
6
|
-
};
|
|
7
|
-
export { useTap };
|
|
8
|
-
//# sourceMappingURL=use-tap.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-tap.d.ts","sourceRoot":"","sources":["../../../components/ui/use-tap.ts"],"names":[],"mappings":"AACA,OAAO,KAAmD,MAAM,OAAO,CAAA;AAuFvE,QAAA,MAAM,MAAM;6BAuBkC,GAAG,KAAK,IAAI,aACvC,GAAG;;;CAerB,CAAA;AAED,OAAO,EAAE,MAAM,EAAE,CAAA"}
|