@superlogic/spree-pay 0.1.16 → 0.1.18
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 +21 -9
- package/build/index.cjs +1918 -587
- package/build/index.css +228 -20
- package/build/index.d.cts +7 -3
- package/build/index.d.ts +7 -3
- package/build/index.js +1923 -593
- package/package.json +3 -2
package/build/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/SpreePay.tsx
|
|
2
|
-
import { useLayoutEffect, useMemo as
|
|
3
|
-
import
|
|
2
|
+
import { useLayoutEffect as useLayoutEffect3, useMemo as useMemo8, useRef as useRef7, useState as useState13 } from "react";
|
|
3
|
+
import NiceModal7 from "@ebay/nice-modal-react";
|
|
4
4
|
import { SWRConfig } from "swr";
|
|
5
5
|
|
|
6
6
|
// src/context/SpreePayActionsContext.tsx
|
|
@@ -18,6 +18,15 @@ var PaymentError = class extends Error {
|
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
// src/types/payments.ts
|
|
22
|
+
var PaymentType = /* @__PURE__ */ ((PaymentType2) => {
|
|
23
|
+
PaymentType2["CREDIT_CARD"] = "CREDIT_CARD";
|
|
24
|
+
PaymentType2["CRYPTO"] = "CRYPTO";
|
|
25
|
+
PaymentType2["SPLIT"] = "SPLIT";
|
|
26
|
+
PaymentType2["POINTS"] = "POINTS";
|
|
27
|
+
return PaymentType2;
|
|
28
|
+
})(PaymentType || {});
|
|
29
|
+
|
|
21
30
|
// src/context/SpreePayActionsContext.tsx
|
|
22
31
|
import { jsx } from "react/jsx-runtime";
|
|
23
32
|
var SpreePayActionsContext = createContext(void 0);
|
|
@@ -84,6 +93,86 @@ var useSpreePayRegister = () => {
|
|
|
84
93
|
return { register: ctx.register };
|
|
85
94
|
};
|
|
86
95
|
|
|
96
|
+
// src/context/StaticConfigContext.tsx
|
|
97
|
+
import { createContext as createContext2, useContext as useContext2, useEffect, useMemo, useState as useState2 } from "react";
|
|
98
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
99
|
+
var CONFIG = {
|
|
100
|
+
dev: {
|
|
101
|
+
bookit: {
|
|
102
|
+
slapiUrl: "https://slapi.dev.superlogic.com",
|
|
103
|
+
keycloakUrl: "https://auth.dev.join.bookit.com",
|
|
104
|
+
keycloakClientId: "oneof-next",
|
|
105
|
+
pointsConversionRatio: 100,
|
|
106
|
+
pointsTitle: "AIR SP"
|
|
107
|
+
},
|
|
108
|
+
moca: {
|
|
109
|
+
slapiUrl: "https://slapi.dev.air.shop",
|
|
110
|
+
keycloakUrl: "https://login.dev.air.shop",
|
|
111
|
+
keycloakClientId: "oneof-next",
|
|
112
|
+
pointsConversionRatio: 100,
|
|
113
|
+
pointsTitle: "AIR SP"
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
stg: {
|
|
117
|
+
bookit: {
|
|
118
|
+
slapiUrl: "https://slapi.stg.superlogic.com",
|
|
119
|
+
keycloakUrl: "https://auth.stg.join.bookit.com",
|
|
120
|
+
keycloakClientId: "oneof-next",
|
|
121
|
+
pointsConversionRatio: 100,
|
|
122
|
+
pointsTitle: "AIR SP"
|
|
123
|
+
},
|
|
124
|
+
moca: {
|
|
125
|
+
slapiUrl: "https://slapi.stg.air.shop",
|
|
126
|
+
keycloakUrl: "https://login.stg.air.shop",
|
|
127
|
+
keycloakClientId: "oneof-next",
|
|
128
|
+
pointsConversionRatio: 100,
|
|
129
|
+
pointsTitle: "AIR SP"
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
prod: {
|
|
133
|
+
bookit: {
|
|
134
|
+
slapiUrl: "https://slapi.superlogic.com",
|
|
135
|
+
keycloakUrl: "https://auth.join.bookit.com",
|
|
136
|
+
keycloakClientId: "oneof-next",
|
|
137
|
+
pointsConversionRatio: 100,
|
|
138
|
+
pointsTitle: "AIR SP"
|
|
139
|
+
},
|
|
140
|
+
moca: {
|
|
141
|
+
slapiUrl: "https://slapi.air.shop",
|
|
142
|
+
keycloakUrl: "https://login.air.shop",
|
|
143
|
+
keycloakClientId: "oneof-next",
|
|
144
|
+
pointsConversionRatio: 100,
|
|
145
|
+
pointsTitle: "AIR SP"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
var StaticConfigContext = createContext2(null);
|
|
150
|
+
var StaticConfigProvider = ({ children, props }) => {
|
|
151
|
+
const { env } = useSpreePayEnv();
|
|
152
|
+
const [appProps, setAppProps] = useState2(props);
|
|
153
|
+
useEffect(() => {
|
|
154
|
+
setAppProps(props);
|
|
155
|
+
}, [props]);
|
|
156
|
+
const staticConfig = useMemo(() => {
|
|
157
|
+
const envConfig = CONFIG[env.environment];
|
|
158
|
+
const appKey = env.tenantId in envConfig ? env.tenantId : "moca";
|
|
159
|
+
return envConfig[appKey];
|
|
160
|
+
}, [env.environment, env.tenantId]);
|
|
161
|
+
return /* @__PURE__ */ jsx2(StaticConfigContext.Provider, { value: { staticConfig, appProps }, children });
|
|
162
|
+
};
|
|
163
|
+
var useStaticConfig = () => {
|
|
164
|
+
const ctx = useContext2(StaticConfigContext);
|
|
165
|
+
if (!ctx) throw new Error("useStaticConfig must be used within StaticConfigProvider");
|
|
166
|
+
return ctx;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// src/hooks/useSpreePayConfig.ts
|
|
170
|
+
import useSWR from "swr";
|
|
171
|
+
var useSpreePayConfig = () => {
|
|
172
|
+
const { data, isLoading } = useSWR("/v1/tenants/configs/spree-pay");
|
|
173
|
+
return { spreePayConfig: data, configIsLoading: isLoading };
|
|
174
|
+
};
|
|
175
|
+
|
|
87
176
|
// src/lib/utils.ts
|
|
88
177
|
import { clsx } from "clsx";
|
|
89
178
|
import { twMerge } from "tailwind-merge";
|
|
@@ -92,7 +181,7 @@ function cn(...inputs) {
|
|
|
92
181
|
}
|
|
93
182
|
|
|
94
183
|
// src/ui/spinner.tsx
|
|
95
|
-
import { jsx as
|
|
184
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
96
185
|
var Spinner = (props) => {
|
|
97
186
|
const { size = "md", className } = props;
|
|
98
187
|
const sizeClasses = {
|
|
@@ -112,7 +201,7 @@ var Spinner = (props) => {
|
|
|
112
201
|
width: "24",
|
|
113
202
|
height: "24",
|
|
114
203
|
children: [
|
|
115
|
-
/* @__PURE__ */
|
|
204
|
+
/* @__PURE__ */ jsx3(
|
|
116
205
|
"path",
|
|
117
206
|
{
|
|
118
207
|
d: "M32 3C35.8083 3 39.5794 3.75011 43.0978 5.20749C46.6163 6.66488 49.8132 8.80101 52.5061 11.4939C55.199 14.1868 57.3351 17.3837 58.7925 20.9022C60.2499 24.4206 61 28.1917 61 32C61 35.8083 60.2499 39.5794 58.7925 43.0978C57.3351 46.6163 55.199 49.8132 52.5061 52.5061C49.8132 55.199 46.6163 57.3351 43.0978 58.7925C39.5794 60.2499 35.8083 61 32 61C28.1917 61 24.4206 60.2499 20.9022 58.7925C17.3837 57.3351 14.1868 55.199 11.4939 52.5061C8.801 49.8132 6.66487 46.6163 5.20749 43.0978C3.7501 39.5794 3 35.8083 3 32C3 28.1917 3.75011 24.4206 5.2075 20.9022C6.66489 17.3837 8.80101 14.1868 11.4939 11.4939C14.1868 8.80099 17.3838 6.66487 20.9022 5.20749C24.4206 3.7501 28.1917 3 32 3L32 3Z",
|
|
@@ -122,7 +211,7 @@ var Spinner = (props) => {
|
|
|
122
211
|
strokeLinejoin: "round"
|
|
123
212
|
}
|
|
124
213
|
),
|
|
125
|
-
/* @__PURE__ */
|
|
214
|
+
/* @__PURE__ */ jsx3(
|
|
126
215
|
"path",
|
|
127
216
|
{
|
|
128
217
|
d: "M32 3C36.5778 3 41.0906 4.08374 45.1692 6.16256C49.2477 8.24138 52.7762 11.2562 55.466 14.9605C58.1558 18.6647 59.9304 22.9531 60.6448 27.4748C61.3591 31.9965 60.9928 36.6232 59.5759 40.9762",
|
|
@@ -150,8 +239,9 @@ var formatUSD = (amount, currency = "USD") => {
|
|
|
150
239
|
};
|
|
151
240
|
var formatPoints = (amount, pointsTitle = "Pts") => {
|
|
152
241
|
const formattedAmount = new Intl.NumberFormat("en-US", {
|
|
242
|
+
notation: "compact",
|
|
153
243
|
style: "decimal",
|
|
154
|
-
maximumFractionDigits:
|
|
244
|
+
maximumFractionDigits: 1,
|
|
155
245
|
minimumFractionDigits: 0
|
|
156
246
|
}).format(amount);
|
|
157
247
|
return `${formattedAmount} ${pointsTitle}`;
|
|
@@ -165,45 +255,85 @@ var formatCoin = (amount, currency = "USDC") => {
|
|
|
165
255
|
return `${formattedAmount} ${currency}`;
|
|
166
256
|
};
|
|
167
257
|
|
|
258
|
+
// src/utils/split.ts
|
|
259
|
+
var getSplitAmount = (amount, splitTokens, pointsConversionRatio) => {
|
|
260
|
+
if (!Number.isFinite(amount) || !Number.isFinite(splitTokens) || !Number.isFinite(pointsConversionRatio)) {
|
|
261
|
+
return amount;
|
|
262
|
+
}
|
|
263
|
+
if (pointsConversionRatio <= 0) return amount;
|
|
264
|
+
const usdCoveredByPoints = splitTokens / pointsConversionRatio;
|
|
265
|
+
const remaining = amount - usdCoveredByPoints;
|
|
266
|
+
return Math.max(0, parseFloat(remaining.toFixed(2)));
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
// src/utils/transactionFee.ts
|
|
270
|
+
var getTransactionFee = (amount = 0, transactionFeePercentage) => {
|
|
271
|
+
if (!Number.isFinite(amount) || amount <= 0) return 0;
|
|
272
|
+
if (!Number.isFinite(transactionFeePercentage) || !transactionFeePercentage || transactionFeePercentage <= 0) {
|
|
273
|
+
return 0;
|
|
274
|
+
}
|
|
275
|
+
const fee = amount * transactionFeePercentage;
|
|
276
|
+
return Math.round((fee + Number.EPSILON) * 100) / 100;
|
|
277
|
+
};
|
|
278
|
+
|
|
168
279
|
// src/components/CheckoutButton.tsx
|
|
169
|
-
import { jsx as
|
|
170
|
-
var CheckoutButton = ({ isLoggedIn
|
|
280
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
281
|
+
var CheckoutButton = ({ isLoggedIn }) => {
|
|
282
|
+
const { staticConfig, appProps } = useStaticConfig();
|
|
283
|
+
const { amount, onProcess, isProcessing, transactionFeePercentage } = appProps;
|
|
284
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
285
|
+
const { pointsTitle, pointsConversionRatio } = staticConfig;
|
|
171
286
|
const { selectedPaymentMethod, isInternalProcessing } = useSpreePaymentMethod();
|
|
172
|
-
const
|
|
173
|
-
const
|
|
287
|
+
const { splitAmount, type, method } = selectedPaymentMethod;
|
|
288
|
+
const isDisabled = !amount || !method || !!isProcessing || isInternalProcessing || !isLoggedIn;
|
|
289
|
+
const isCC = type === "CREDIT_CARD" /* CREDIT_CARD */;
|
|
290
|
+
const isCrypto = type === "CRYPTO" /* CRYPTO */;
|
|
291
|
+
const getCheckoutContent = () => {
|
|
292
|
+
if (!!isProcessing || isInternalProcessing) {
|
|
293
|
+
return /* @__PURE__ */ jsx4(Spinner, { className: "inline", size: "sm" });
|
|
294
|
+
}
|
|
295
|
+
if (isCC && amount) {
|
|
296
|
+
const usdAmount = getSplitAmount(amount, splitAmount ?? 0, pointsConversionRatio);
|
|
297
|
+
if (splitAmount && usdAmount) {
|
|
298
|
+
return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))} + ${formatPoints(splitAmount, pointsTitle)}`;
|
|
299
|
+
}
|
|
300
|
+
if (usdAmount) {
|
|
301
|
+
return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))}`;
|
|
302
|
+
}
|
|
303
|
+
if (splitAmount) {
|
|
304
|
+
return `Pay ${formatPoints(splitAmount, pointsTitle)}`;
|
|
305
|
+
}
|
|
306
|
+
return "Checkout";
|
|
307
|
+
}
|
|
308
|
+
if (isCrypto && amount) {
|
|
309
|
+
return `Pay ${formatCoin(amount)}`;
|
|
310
|
+
}
|
|
311
|
+
return "Checkout";
|
|
312
|
+
};
|
|
174
313
|
return /* @__PURE__ */ jsxs2("div", { className: "flex w-full flex-col overflow-hidden rounded-3xl border border-black/25 bg-white text-xs font-medium", children: [
|
|
175
|
-
/* @__PURE__ */
|
|
314
|
+
/* @__PURE__ */ jsx4("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsxs2("p", { className: "text-black/50", children: [
|
|
176
315
|
"By clicking on the button below I acknowledge that I have read and accepted the",
|
|
177
316
|
" ",
|
|
178
|
-
/* @__PURE__ */
|
|
179
|
-
"a",
|
|
180
|
-
{
|
|
181
|
-
className: "underline",
|
|
182
|
-
href: "https://uat.travel.air.shop/terms?locale=en-US¤cy=USD",
|
|
183
|
-
target: "_blank",
|
|
184
|
-
rel: "noreferrer",
|
|
185
|
-
children: "Terms and Conditions"
|
|
186
|
-
}
|
|
187
|
-
),
|
|
317
|
+
/* @__PURE__ */ jsx4("a", { className: "underline", href: spreePayConfig?.termsConditionsUrl, target: "_blank", rel: "noreferrer", children: "Terms and Conditions" }),
|
|
188
318
|
"."
|
|
189
319
|
] }) }),
|
|
190
|
-
|
|
320
|
+
onProcess && /* @__PURE__ */ jsx4(
|
|
191
321
|
"button",
|
|
192
322
|
{
|
|
193
323
|
disabled: isDisabled,
|
|
194
|
-
onClick:
|
|
324
|
+
onClick: onProcess,
|
|
195
325
|
className: "bg-primary h-[60px] w-full cursor-pointer text-xl font-semibold text-white disabled:cursor-not-allowed disabled:opacity-50",
|
|
196
|
-
children:
|
|
326
|
+
children: getCheckoutContent()
|
|
197
327
|
}
|
|
198
328
|
)
|
|
199
329
|
] });
|
|
200
330
|
};
|
|
201
331
|
|
|
202
332
|
// src/components/SpreeLegal.tsx
|
|
203
|
-
import { jsx as
|
|
333
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
204
334
|
var SpreeLegal = () => {
|
|
205
335
|
return /* @__PURE__ */ jsxs3("div", { className: "mt-4 flex items-center gap-4", children: [
|
|
206
|
-
/* @__PURE__ */
|
|
336
|
+
/* @__PURE__ */ jsx5("svg", { className: "flex-shrink-0", xmlns: "http://www.w3.org/2000/svg", width: "66", height: "30", fill: "none", children: /* @__PURE__ */ jsx5(
|
|
207
337
|
"path",
|
|
208
338
|
{
|
|
209
339
|
fill: "#000",
|
|
@@ -214,7 +344,7 @@ var SpreeLegal = () => {
|
|
|
214
344
|
/* @__PURE__ */ jsxs3("p", { className: "text-xs text-black/50", children: [
|
|
215
345
|
"Spree enables seamless crypto payments for real-world goods, travel, and experiences. Enjoy secure, fast transactions and earn rewards.",
|
|
216
346
|
" ",
|
|
217
|
-
/* @__PURE__ */
|
|
347
|
+
/* @__PURE__ */ jsx5("a", { className: "underline", href: "https://www.spree.finance/", target: "_blank", rel: "noreferrer", children: "Learn more" }),
|
|
218
348
|
" ",
|
|
219
349
|
"about Spree."
|
|
220
350
|
] })
|
|
@@ -222,31 +352,13 @@ var SpreeLegal = () => {
|
|
|
222
352
|
};
|
|
223
353
|
|
|
224
354
|
// src/components/CreditCardTab/CreditCardTab.tsx
|
|
225
|
-
import { useCallback as
|
|
226
|
-
|
|
227
|
-
// src/hooks/useCards.ts
|
|
228
|
-
import useSWR from "swr";
|
|
229
|
-
var useCards = () => {
|
|
230
|
-
const { data, isLoading, mutate } = useSWR(`/v1/payments/cards`);
|
|
231
|
-
return {
|
|
232
|
-
cards: data?.data.filter((c) => c.active) || [],
|
|
233
|
-
cardsIsLoading: isLoading,
|
|
234
|
-
mutateCards: mutate
|
|
235
|
-
};
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
// src/hooks/useSlapiBalance.ts
|
|
239
|
-
import useSWR2 from "swr";
|
|
240
|
-
var useSlapiBalance = () => {
|
|
241
|
-
const { data, isLoading, mutate } = useSWR2(`/v1/loyalty/accounts`);
|
|
242
|
-
return { balance: data?.detail, isBalanceLoading: isLoading, mutateBalance: mutate };
|
|
243
|
-
};
|
|
355
|
+
import { useCallback as useCallback5, useEffect as useEffect7 } from "react";
|
|
244
356
|
|
|
245
|
-
// src/
|
|
357
|
+
// src/hooks/useCardPayment.ts
|
|
246
358
|
import NiceModal2 from "@ebay/nice-modal-react";
|
|
247
359
|
|
|
248
360
|
// src/modals/Iframe3ds.tsx
|
|
249
|
-
import { useEffect } from "react";
|
|
361
|
+
import { useEffect as useEffect2 } from "react";
|
|
250
362
|
import NiceModal, { useModal } from "@ebay/nice-modal-react";
|
|
251
363
|
|
|
252
364
|
// src/services/eventBus.ts
|
|
@@ -281,17 +393,17 @@ function usePortalContainer() {
|
|
|
281
393
|
}
|
|
282
394
|
|
|
283
395
|
// src/ui/dialog.tsx
|
|
284
|
-
import { jsx as
|
|
396
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
285
397
|
function Dialog({ ...props }) {
|
|
286
|
-
return /* @__PURE__ */
|
|
398
|
+
return /* @__PURE__ */ jsx6(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
287
399
|
}
|
|
288
400
|
function DialogPortal({ ...props }) {
|
|
289
401
|
const container = usePortalContainer();
|
|
290
402
|
const safeContainer = container && document.body.contains(container) ? container : void 0;
|
|
291
|
-
return /* @__PURE__ */
|
|
403
|
+
return /* @__PURE__ */ jsx6(DialogPrimitive.Portal, { container: safeContainer, "data-slot": "dialog-portal", ...props });
|
|
292
404
|
}
|
|
293
405
|
function DialogOverlay({ className, ...props }) {
|
|
294
|
-
return /* @__PURE__ */
|
|
406
|
+
return /* @__PURE__ */ jsx6(
|
|
295
407
|
DialogPrimitive.Overlay,
|
|
296
408
|
{
|
|
297
409
|
"data-slot": "dialog-overlay",
|
|
@@ -310,7 +422,7 @@ function DialogContent({
|
|
|
310
422
|
...props
|
|
311
423
|
}) {
|
|
312
424
|
return /* @__PURE__ */ jsxs4(DialogPortal, { "data-slot": "dialog-portal", children: [
|
|
313
|
-
/* @__PURE__ */
|
|
425
|
+
/* @__PURE__ */ jsx6(DialogOverlay, {}),
|
|
314
426
|
/* @__PURE__ */ jsxs4(
|
|
315
427
|
DialogPrimitive.Content,
|
|
316
428
|
{
|
|
@@ -328,8 +440,8 @@ function DialogContent({
|
|
|
328
440
|
"data-slot": "dialog-close",
|
|
329
441
|
className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
330
442
|
children: [
|
|
331
|
-
/* @__PURE__ */
|
|
332
|
-
/* @__PURE__ */
|
|
443
|
+
/* @__PURE__ */ jsx6(XIcon, {}),
|
|
444
|
+
/* @__PURE__ */ jsx6("span", { className: "sr-only", children: "Close" })
|
|
333
445
|
]
|
|
334
446
|
}
|
|
335
447
|
)
|
|
@@ -339,7 +451,7 @@ function DialogContent({
|
|
|
339
451
|
] });
|
|
340
452
|
}
|
|
341
453
|
function DialogTitle({ className, ...props }) {
|
|
342
|
-
return /* @__PURE__ */
|
|
454
|
+
return /* @__PURE__ */ jsx6(
|
|
343
455
|
DialogPrimitive.Title,
|
|
344
456
|
{
|
|
345
457
|
"data-slot": "dialog-title",
|
|
@@ -349,7 +461,7 @@ function DialogTitle({ className, ...props }) {
|
|
|
349
461
|
);
|
|
350
462
|
}
|
|
351
463
|
function DialogDescription({ className, ...props }) {
|
|
352
|
-
return /* @__PURE__ */
|
|
464
|
+
return /* @__PURE__ */ jsx6(
|
|
353
465
|
DialogPrimitive.Description,
|
|
354
466
|
{
|
|
355
467
|
"data-slot": "dialog-description",
|
|
@@ -360,10 +472,10 @@ function DialogDescription({ className, ...props }) {
|
|
|
360
472
|
}
|
|
361
473
|
|
|
362
474
|
// src/modals/Iframe3ds.tsx
|
|
363
|
-
import { jsx as
|
|
475
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
364
476
|
var Iframe3ds = NiceModal.create(({ url }) => {
|
|
365
477
|
const modal = useModal();
|
|
366
|
-
|
|
478
|
+
useEffect2(() => {
|
|
367
479
|
return bus.on("paymentIntent", (data) => {
|
|
368
480
|
modal.resolve(data.paymentIntent);
|
|
369
481
|
modal.remove();
|
|
@@ -373,9 +485,9 @@ var Iframe3ds = NiceModal.create(({ url }) => {
|
|
|
373
485
|
modal.reject();
|
|
374
486
|
modal.remove();
|
|
375
487
|
};
|
|
376
|
-
return /* @__PURE__ */
|
|
377
|
-
/* @__PURE__ */
|
|
378
|
-
/* @__PURE__ */
|
|
488
|
+
return /* @__PURE__ */ jsx7(Dialog, { open: modal.visible, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs5(DialogContent, { className: "max-h-[600px] w-full max-w-[680px] p-0", children: [
|
|
489
|
+
/* @__PURE__ */ jsx7(DialogTitle, { className: "hidden", children: "3D Secure Verification" }),
|
|
490
|
+
/* @__PURE__ */ jsx7("iframe", { src: url, id: "3ds-iframe", title: "3D Secure Checkout", className: "h-[500px] w-full rounded-lg border-0" })
|
|
379
491
|
] }) });
|
|
380
492
|
});
|
|
381
493
|
Iframe3ds.displayName = "Iframe3ds";
|
|
@@ -477,32 +589,13 @@ var registerApi = (config2) => {
|
|
|
477
589
|
|
|
478
590
|
// src/services/slapi.ts
|
|
479
591
|
var SlapiPaymentService = {
|
|
480
|
-
// checkBallance: async ({ coin, amount, slippage }: CheckBallanceParams) => {
|
|
481
|
-
// // if no ballance known, return true and check by wallet
|
|
482
|
-
// if (!coin.balance) return true;
|
|
483
|
-
// const isUSDC = coin.symbol === COIN.USDC;
|
|
484
|
-
// if (isUSDC) return coin.balance > amount;
|
|
485
|
-
// const inputDecimals = cryptoAssets[COIN.USDC].decimals; // Decimals for USDC
|
|
486
|
-
// const outputDecimals = coin.decimals; // Decimals for the input asset (e.g., SOL, BONK)
|
|
487
|
-
// const params = {
|
|
488
|
-
// inputMint: env.NEXT_PUBLIC_USDC_MAINNET_MINT_ADDRESS, // should be main net
|
|
489
|
-
// outputMint: coin.address,
|
|
490
|
-
// amount: Math.floor(amount * Math.pow(10, inputDecimals)), // Convert amount to smallest units
|
|
491
|
-
// slippage,
|
|
492
|
-
// };
|
|
493
|
-
// // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
494
|
-
// const { data } = await jupiterApi.get<any>(`/quote?${qs.stringify(params)}`);
|
|
495
|
-
// // Convert back to human-readable form
|
|
496
|
-
// const outAmountNumber = data?.outAmount ? Number(data.outAmount) / Math.pow(10, outputDecimals) : null;
|
|
497
|
-
// // if no ballance known, return true and check by wallet
|
|
498
|
-
// if (!outAmountNumber) return true;
|
|
499
|
-
// return coin.balance > outAmountNumber;
|
|
500
|
-
// },
|
|
501
592
|
createPayment: (params) => {
|
|
502
593
|
const { type, hash, metadata, capture = false } = params;
|
|
503
594
|
let reqParams;
|
|
504
595
|
if (type === "CRYPTO" /* CRYPTO */) {
|
|
505
596
|
reqParams = { type, hash, crypto: params.crypto };
|
|
597
|
+
} else if (type === "CREDIT_CARD" /* CREDIT_CARD */ && params.points && params.points.amount > 0) {
|
|
598
|
+
reqParams = { type: "SPLIT" /* SPLIT */, hash, card: params.card, points: params.points };
|
|
506
599
|
} else {
|
|
507
600
|
reqParams = { type, hash, card: params.card };
|
|
508
601
|
}
|
|
@@ -511,148 +604,280 @@ var SlapiPaymentService = {
|
|
|
511
604
|
baseVerify: ({ id, txHash }) => {
|
|
512
605
|
return slapiApi.post(`/v1/base-transactions/transactions/${id}/verify`, { txHash });
|
|
513
606
|
},
|
|
514
|
-
|
|
515
|
-
// const swapTransactionBuf = Buffer.from(encodedTX, 'base64');
|
|
516
|
-
// const transaction = VersionedTransaction.deserialize(swapTransactionBuf);
|
|
517
|
-
// // Sign and send the transaction
|
|
518
|
-
// const signedTransaction = await signTransaction(transaction);
|
|
519
|
-
// return Buffer.from(signedTransaction.serialize()).toString('base64');
|
|
520
|
-
// },
|
|
521
|
-
// executeSolana: (params: { txId: string; signedTx: string }) => {
|
|
522
|
-
// const { txId, signedTx } = params;
|
|
523
|
-
// return slapiApi.post<string>(`/solana-transactions/transactions/${txId}/execute`, { signedTx });
|
|
524
|
-
// },
|
|
525
|
-
addCard: (params) => {
|
|
526
|
-
const { source, hash } = params;
|
|
607
|
+
addCard: ({ source, hash }) => {
|
|
527
608
|
return slapiApi.post("/v1/payments/cards", { hash, source }).then((data) => ({ data }));
|
|
528
609
|
},
|
|
529
|
-
validate3DS: (
|
|
530
|
-
|
|
531
|
-
|
|
610
|
+
validate3DS: ({ paymentId }) => {
|
|
611
|
+
return slapiApi.post("/v1/payments/validate", { paymentId, type: "CREDIT_CARD" /* CREDIT_CARD */ }).then((data) => ({ data }));
|
|
612
|
+
},
|
|
613
|
+
validatePoints: ({ paymentId, txHash }) => {
|
|
614
|
+
return slapiApi.post("/v1/payments/validate", { txHash, paymentId, type: "POINTS" /* POINTS */ }).then((data) => ({ data }));
|
|
615
|
+
},
|
|
616
|
+
getStatus: (paymentId) => {
|
|
617
|
+
return slapiApi.get(`/v1/payments/${paymentId}/status`);
|
|
532
618
|
}
|
|
533
619
|
};
|
|
534
620
|
|
|
535
|
-
// src/
|
|
536
|
-
var
|
|
537
|
-
const {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
const { data: paymentResData } = await SlapiPaymentService.createPayment({
|
|
544
|
-
hash,
|
|
545
|
-
capture,
|
|
546
|
-
metadata,
|
|
547
|
-
type: "CREDIT_CARD" /* CREDIT_CARD */,
|
|
548
|
-
card: {
|
|
549
|
-
cardId,
|
|
550
|
-
transactionFee,
|
|
551
|
-
returnUrl: `${window.location.origin}${redirect3dsURI}`
|
|
621
|
+
// src/hooks/useCardPayment.ts
|
|
622
|
+
var useCardPayment = () => {
|
|
623
|
+
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
624
|
+
const { env } = useSpreePayEnv();
|
|
625
|
+
const { appProps } = useStaticConfig();
|
|
626
|
+
const cardPayment = async (params) => {
|
|
627
|
+
if (selectedPaymentMethod.type !== "CREDIT_CARD" /* CREDIT_CARD */ || !selectedPaymentMethod.method) {
|
|
628
|
+
throw new Error("Unsupported payment method");
|
|
552
629
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
if (
|
|
557
|
-
const { data:
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
paymentId: paymentResData.id,
|
|
562
|
-
txId: paymentResData.txId,
|
|
563
|
-
txHash: null
|
|
564
|
-
};
|
|
630
|
+
const { hash, capture, metadata } = params;
|
|
631
|
+
const card = selectedPaymentMethod.method;
|
|
632
|
+
let cardId;
|
|
633
|
+
if ("token" in card) {
|
|
634
|
+
const { data: cardResData } = await SlapiPaymentService.addCard({ hash, source: card.token });
|
|
635
|
+
cardId = cardResData.id;
|
|
636
|
+
} else {
|
|
637
|
+
cardId = card.id;
|
|
565
638
|
}
|
|
566
|
-
|
|
639
|
+
const transactionFee = getTransactionFee(appProps.amount, appProps.transactionFeePercentage);
|
|
640
|
+
const { data: paymentResData } = await SlapiPaymentService.createPayment({
|
|
641
|
+
hash,
|
|
642
|
+
capture,
|
|
643
|
+
metadata,
|
|
644
|
+
type: "CREDIT_CARD" /* CREDIT_CARD */,
|
|
645
|
+
card: {
|
|
646
|
+
cardId,
|
|
647
|
+
transactionFee,
|
|
648
|
+
returnUrl: `${typeof window !== "undefined" ? window.location.origin : ""}${env.redirect3dsURI}`
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
let { status } = paymentResData;
|
|
652
|
+
if (paymentResData.redirectUrl) {
|
|
653
|
+
const paymentIntent = await NiceModal2.show(Iframe3ds, { url: paymentResData.redirectUrl });
|
|
654
|
+
if (paymentIntent) {
|
|
655
|
+
const { data: validateData } = await SlapiPaymentService.validate3DS({ paymentId: paymentResData.id });
|
|
656
|
+
({ status } = validateData);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
return {
|
|
660
|
+
status,
|
|
661
|
+
paymentType: "CREDIT_CARD" /* CREDIT_CARD */,
|
|
662
|
+
paymentId: paymentResData.id,
|
|
663
|
+
txId: paymentResData.txId,
|
|
664
|
+
txHash: null
|
|
665
|
+
};
|
|
666
|
+
};
|
|
667
|
+
return { cardPayment };
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
// src/hooks/useCards.ts
|
|
671
|
+
import useSWR2 from "swr";
|
|
672
|
+
var useCards = () => {
|
|
673
|
+
const { data, isLoading, mutate } = useSWR2(`/v1/payments/cards`);
|
|
567
674
|
return {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
txId: paymentResData.txId,
|
|
572
|
-
txHash: null
|
|
675
|
+
cards: data?.data.filter((c) => c.active) || [],
|
|
676
|
+
cardsIsLoading: isLoading,
|
|
677
|
+
mutateCards: mutate
|
|
573
678
|
};
|
|
574
679
|
};
|
|
575
680
|
|
|
576
|
-
// src/
|
|
577
|
-
import
|
|
681
|
+
// src/hooks/useSplitCardPayments.ts
|
|
682
|
+
import NiceModal3 from "@ebay/nice-modal-react";
|
|
578
683
|
|
|
579
|
-
// src/
|
|
580
|
-
import
|
|
581
|
-
import {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
684
|
+
// src/services/AirWalletService.ts
|
|
685
|
+
import { AirService, BUILD_ENV } from "@mocanetwork/airkit";
|
|
686
|
+
import { createWalletClient, custom, encodeFunctionData, erc20Abi, parseUnits } from "viem";
|
|
687
|
+
var singletonState = null;
|
|
688
|
+
var initPromise = null;
|
|
689
|
+
var cachedKey = null;
|
|
690
|
+
function optionsKey(opts) {
|
|
691
|
+
return `${opts.partnerId}|${opts.mocaChain?.id ?? "unknown"}`;
|
|
692
|
+
}
|
|
693
|
+
async function createAndInit(opts) {
|
|
694
|
+
const air = new AirService({ partnerId: opts.partnerId });
|
|
695
|
+
try {
|
|
696
|
+
await air.init({
|
|
697
|
+
buildEnv: opts.buildEnv ?? BUILD_ENV.SANDBOX,
|
|
698
|
+
enableLogging: opts.enableLogging ?? true,
|
|
699
|
+
skipRehydration: opts.skipRehydration ?? false
|
|
700
|
+
});
|
|
701
|
+
air.preloadWallet().catch(() => {
|
|
702
|
+
});
|
|
703
|
+
const loginRes = await air.login();
|
|
704
|
+
const address = loginRes?.abstractAccountAddress || null;
|
|
705
|
+
const walletClient = address ? createWalletClient({
|
|
706
|
+
transport: custom(air.provider),
|
|
707
|
+
chain: opts.mocaChain,
|
|
708
|
+
account: address
|
|
709
|
+
}) : null;
|
|
710
|
+
return { walletReady: true, address, walletClient, air, chain: opts.mocaChain };
|
|
711
|
+
} catch (e) {
|
|
712
|
+
const msg = e instanceof Error ? e.message : "Unknown error during AirWallet initialization";
|
|
713
|
+
return { walletReady: false, address: null, walletClient: null, air: null, chain: null, error: msg };
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
async function getAirWallet(options) {
|
|
717
|
+
const key = optionsKey(options);
|
|
718
|
+
if (singletonState && cachedKey === key) return singletonState;
|
|
719
|
+
if (initPromise && cachedKey === key) return initPromise;
|
|
720
|
+
cachedKey = key;
|
|
721
|
+
initPromise = createAndInit(options).then((state) => {
|
|
722
|
+
singletonState = state;
|
|
723
|
+
return state;
|
|
724
|
+
});
|
|
725
|
+
return initPromise;
|
|
726
|
+
}
|
|
727
|
+
function peekAirWallet() {
|
|
728
|
+
return singletonState;
|
|
729
|
+
}
|
|
730
|
+
async function handleSendErc20(params) {
|
|
731
|
+
const state = singletonState;
|
|
732
|
+
if (!state?.walletClient) {
|
|
733
|
+
console.error("Air wallet is not initialized");
|
|
734
|
+
throw new Error("Air wallet is not initialized");
|
|
735
|
+
}
|
|
736
|
+
if (!params?.recipient) {
|
|
737
|
+
console.error("Recipient address is not set");
|
|
738
|
+
throw new Error("Recipient address is not set");
|
|
739
|
+
}
|
|
740
|
+
if (!params?.token?.address || !params?.token?.decimals) {
|
|
741
|
+
console.error("Token address or decimals not set");
|
|
742
|
+
throw new Error("Token address or decimals not set");
|
|
743
|
+
}
|
|
744
|
+
try {
|
|
745
|
+
const { walletClient } = state;
|
|
746
|
+
const addresses = await walletClient.getAddresses();
|
|
747
|
+
const value = parseUnits(String(params.amount), params.token.decimals);
|
|
748
|
+
const data = encodeFunctionData({
|
|
749
|
+
abi: erc20Abi,
|
|
750
|
+
functionName: "transfer",
|
|
751
|
+
args: [params.recipient, value]
|
|
752
|
+
});
|
|
753
|
+
const hash = await walletClient.sendTransaction({
|
|
754
|
+
account: addresses[0],
|
|
755
|
+
to: params.token.address,
|
|
756
|
+
data,
|
|
757
|
+
value: 0n,
|
|
758
|
+
chain: state.chain ?? void 0
|
|
759
|
+
});
|
|
760
|
+
return { txHash: hash };
|
|
761
|
+
} catch (error) {
|
|
762
|
+
if (typeof error === "object" && error !== null && "shortMessage" in error) {
|
|
763
|
+
console.error(error.shortMessage);
|
|
764
|
+
} else {
|
|
765
|
+
console.error("Your wallet balances are insufficient to complete this transaction.");
|
|
592
766
|
}
|
|
593
|
-
|
|
767
|
+
}
|
|
594
768
|
}
|
|
595
769
|
|
|
596
|
-
// src/
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
function
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
{
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
606
|
-
className
|
|
607
|
-
),
|
|
608
|
-
...props,
|
|
609
|
-
children: /* @__PURE__ */ jsx8(
|
|
610
|
-
SwitchPrimitive.Thumb,
|
|
611
|
-
{
|
|
612
|
-
"data-slot": "switch-thumb",
|
|
613
|
-
className: "bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
|
|
614
|
-
}
|
|
615
|
-
)
|
|
770
|
+
// src/hooks/useSplitCardPayments.ts
|
|
771
|
+
var REFRESH_INTERVAL = 3 * 1e3;
|
|
772
|
+
var MAX_RETRIES = 10;
|
|
773
|
+
async function longPollPoints(paymentId) {
|
|
774
|
+
let retries = 0;
|
|
775
|
+
while (retries < MAX_RETRIES) {
|
|
776
|
+
const { detail } = await SlapiPaymentService.getStatus(paymentId);
|
|
777
|
+
if (detail.status === "FAILED" /* FAILED */) {
|
|
778
|
+
throw new Error("Something went wrong with the payment");
|
|
616
779
|
}
|
|
617
|
-
|
|
780
|
+
if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(detail.status)) {
|
|
781
|
+
return detail.status;
|
|
782
|
+
}
|
|
783
|
+
await new Promise((res) => setTimeout(res, REFRESH_INTERVAL));
|
|
784
|
+
retries++;
|
|
785
|
+
}
|
|
786
|
+
throw new Error("Points Payment polling timed out");
|
|
618
787
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
788
|
+
async function longPollCardStatus(paymentId) {
|
|
789
|
+
let retries = 0;
|
|
790
|
+
let shown3ds = false;
|
|
791
|
+
while (retries < MAX_RETRIES) {
|
|
792
|
+
const { detail } = await SlapiPaymentService.getStatus(paymentId);
|
|
793
|
+
if (detail.status === "FAILED" /* FAILED */) {
|
|
794
|
+
throw new Error(`Something went wrong with the ${detail.validationType} payment`);
|
|
795
|
+
}
|
|
796
|
+
if (detail.validationType === "POINTS") {
|
|
797
|
+
return detail.status;
|
|
798
|
+
}
|
|
799
|
+
if (!shown3ds && detail.card?.redirectUrl) {
|
|
800
|
+
const paymentIntent = await NiceModal3.show(Iframe3ds, { url: detail.card?.redirectUrl });
|
|
801
|
+
shown3ds = true;
|
|
802
|
+
if (paymentIntent) {
|
|
803
|
+
await SlapiPaymentService.validate3DS({ paymentId });
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
await new Promise((res) => setTimeout(res, REFRESH_INTERVAL));
|
|
807
|
+
retries++;
|
|
808
|
+
}
|
|
809
|
+
throw new Error("Payment polling timed out");
|
|
810
|
+
}
|
|
811
|
+
var useSplitCardPayments = () => {
|
|
812
|
+
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
813
|
+
const { env } = useSpreePayEnv();
|
|
814
|
+
const { appProps, staticConfig } = useStaticConfig();
|
|
815
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
816
|
+
const splitPayment = async (params) => {
|
|
817
|
+
if (selectedPaymentMethod.type !== "CREDIT_CARD" /* CREDIT_CARD */ || !selectedPaymentMethod.method || !params.points) {
|
|
818
|
+
throw new Error("Unsupported payment method");
|
|
819
|
+
}
|
|
820
|
+
const { hash, capture, metadata, points } = params;
|
|
821
|
+
const card = selectedPaymentMethod.method;
|
|
822
|
+
let cardId;
|
|
823
|
+
if ("token" in card) {
|
|
824
|
+
const { data: cardResData } = await SlapiPaymentService.addCard({ hash, source: card.token });
|
|
825
|
+
cardId = cardResData.id;
|
|
826
|
+
} else {
|
|
827
|
+
cardId = card.id;
|
|
828
|
+
}
|
|
829
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, points, staticConfig.pointsConversionRatio);
|
|
830
|
+
const transactionFee = getTransactionFee(usdAmount, appProps.transactionFeePercentage);
|
|
831
|
+
const { data: paymentResData } = await SlapiPaymentService.createPayment({
|
|
832
|
+
hash,
|
|
833
|
+
capture,
|
|
834
|
+
metadata,
|
|
835
|
+
type: "CREDIT_CARD" /* CREDIT_CARD */,
|
|
836
|
+
card: {
|
|
837
|
+
cardId,
|
|
838
|
+
transactionFee,
|
|
839
|
+
returnUrl: `${typeof window !== "undefined" ? window.location.origin : ""}${env.redirect3dsURI}`
|
|
840
|
+
},
|
|
841
|
+
points: {
|
|
842
|
+
amount: points
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
await longPollCardStatus(paymentResData.id);
|
|
846
|
+
const wallet = peekAirWallet();
|
|
847
|
+
if (!wallet || !spreePayConfig?.pointsChain) {
|
|
848
|
+
throw new Error("AirWallet not found");
|
|
849
|
+
}
|
|
850
|
+
const transaction = await handleSendErc20({
|
|
851
|
+
amount: params.points,
|
|
852
|
+
token: spreePayConfig.pointsChain.pointsCoin,
|
|
853
|
+
recipient: spreePayConfig.pointsChain.recipientAddress
|
|
854
|
+
});
|
|
855
|
+
if (!transaction) {
|
|
856
|
+
throw new Error("Points transaction failed");
|
|
857
|
+
}
|
|
858
|
+
await SlapiPaymentService.validatePoints({
|
|
859
|
+
paymentId: paymentResData.id,
|
|
860
|
+
txHash: transaction.txHash
|
|
861
|
+
});
|
|
862
|
+
const pointsStatus = await longPollPoints(paymentResData.id);
|
|
863
|
+
return {
|
|
864
|
+
paymentType: "SPLIT" /* SPLIT */,
|
|
865
|
+
status: pointsStatus,
|
|
866
|
+
paymentId: paymentResData.id,
|
|
867
|
+
txId: paymentResData.txId,
|
|
868
|
+
txHash: transaction.txHash
|
|
869
|
+
};
|
|
870
|
+
};
|
|
871
|
+
return { splitPayment };
|
|
640
872
|
};
|
|
641
873
|
|
|
642
874
|
// src/components/CreditCardTab/CreditCard/CreditCard.tsx
|
|
643
|
-
import { useMemo, useState as
|
|
875
|
+
import { useMemo as useMemo2, useState as useState4 } from "react";
|
|
644
876
|
import { Elements } from "@stripe/react-stripe-js";
|
|
645
877
|
import { loadStripe } from "@stripe/stripe-js";
|
|
646
878
|
|
|
647
|
-
// src/hooks/useConfig.ts
|
|
648
|
-
import useSWR3 from "swr";
|
|
649
|
-
var useConfig = () => {
|
|
650
|
-
const { data, isLoading } = useSWR3("/v1/tenants/configs/spree-pay");
|
|
651
|
-
return { config: data, configIsLoading: isLoading };
|
|
652
|
-
};
|
|
653
|
-
|
|
654
879
|
// src/components/CreditCardTab/CreditCard/CardsList.tsx
|
|
655
|
-
import { jsx as
|
|
880
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
656
881
|
var isRemoveDisabled = true;
|
|
657
882
|
var CardListItem = ({ card, isSelected, onSelect }) => {
|
|
658
883
|
const handleSelect = () => {
|
|
@@ -662,17 +887,17 @@ var CardListItem = ({ card, isSelected, onSelect }) => {
|
|
|
662
887
|
e.stopPropagation();
|
|
663
888
|
if (isSelected || isRemoveDisabled) return;
|
|
664
889
|
};
|
|
665
|
-
return /* @__PURE__ */
|
|
666
|
-
/* @__PURE__ */
|
|
890
|
+
return /* @__PURE__ */ jsxs6("button", { type: "button", onClick: handleSelect, className: "bg-primary/8 flex h-11 w-full overflow-hidden rounded-md", children: [
|
|
891
|
+
/* @__PURE__ */ jsx8(
|
|
667
892
|
"div",
|
|
668
893
|
{
|
|
669
894
|
className: cn("flex h-full w-11 items-center justify-center bg-black/10", {
|
|
670
895
|
"bg-primary": isSelected
|
|
671
896
|
}),
|
|
672
|
-
children: /* @__PURE__ */
|
|
897
|
+
children: /* @__PURE__ */ jsx8("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white", children: isSelected && /* @__PURE__ */ jsx8("div", { className: "bg-primary h-2.5 w-2.5 rounded-full" }) })
|
|
673
898
|
}
|
|
674
899
|
),
|
|
675
|
-
/* @__PURE__ */
|
|
900
|
+
/* @__PURE__ */ jsxs6(
|
|
676
901
|
"div",
|
|
677
902
|
{
|
|
678
903
|
className: cn(
|
|
@@ -682,13 +907,13 @@ var CardListItem = ({ card, isSelected, onSelect }) => {
|
|
|
682
907
|
}
|
|
683
908
|
),
|
|
684
909
|
children: [
|
|
685
|
-
/* @__PURE__ */
|
|
686
|
-
/* @__PURE__ */
|
|
687
|
-
/* @__PURE__ */
|
|
910
|
+
/* @__PURE__ */ jsx8("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx8("p", { className: "text-sm font-medium text-black", children: card.schema }) }),
|
|
911
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
912
|
+
/* @__PURE__ */ jsxs6("p", { className: "text-sm font-medium text-black/50", children: [
|
|
688
913
|
"Ending in ",
|
|
689
|
-
/* @__PURE__ */
|
|
914
|
+
/* @__PURE__ */ jsx8("span", { className: "text-black", children: card.lastFourNumbers })
|
|
690
915
|
] }),
|
|
691
|
-
/* @__PURE__ */
|
|
916
|
+
/* @__PURE__ */ jsx8(
|
|
692
917
|
"div",
|
|
693
918
|
{
|
|
694
919
|
onClick: handleRemoveCard,
|
|
@@ -696,9 +921,9 @@ var CardListItem = ({ card, isSelected, onSelect }) => {
|
|
|
696
921
|
"cursor-not-allowed opacity-50": isSelected || isRemoveDisabled
|
|
697
922
|
// 'cursor-pointer': !isSelected || !isRemoveDisabled,
|
|
698
923
|
}),
|
|
699
|
-
children: /* @__PURE__ */
|
|
700
|
-
/* @__PURE__ */
|
|
701
|
-
/* @__PURE__ */
|
|
924
|
+
children: /* @__PURE__ */ jsxs6("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", fill: "none", children: [
|
|
925
|
+
/* @__PURE__ */ jsx8("mask", { id: "mask0_188_5407", width: "20", height: "21", x: "0", y: "-1", maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx8("path", { fill: "#D9D9D9", d: "M0-.5h20v20H0z" }) }),
|
|
926
|
+
/* @__PURE__ */ jsx8("g", { mask: "url(#mask0_188_5407)", children: /* @__PURE__ */ jsx8(
|
|
702
927
|
"path",
|
|
703
928
|
{
|
|
704
929
|
fill: "#000",
|
|
@@ -718,23 +943,23 @@ var CardListItem = ({ card, isSelected, onSelect }) => {
|
|
|
718
943
|
var CardsList = ({ selectedCard, setCard }) => {
|
|
719
944
|
const { cards, cardsIsLoading } = useCards();
|
|
720
945
|
if (cardsIsLoading) {
|
|
721
|
-
return /* @__PURE__ */
|
|
722
|
-
/* @__PURE__ */
|
|
723
|
-
/* @__PURE__ */
|
|
946
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex w-full flex-col gap-1", children: [
|
|
947
|
+
/* @__PURE__ */ jsx8("div", { className: "bg-primary/8 h-11 animate-pulse rounded-md" }),
|
|
948
|
+
/* @__PURE__ */ jsx8("div", { className: "bg-primary/8 h-11 animate-pulse rounded-md" })
|
|
724
949
|
] });
|
|
725
950
|
}
|
|
726
951
|
if (cards.length === 0) return null;
|
|
727
|
-
return /* @__PURE__ */
|
|
952
|
+
return /* @__PURE__ */ jsx8("div", { className: "flex w-full flex-col gap-1", children: cards.map((card) => /* @__PURE__ */ jsx8(CardListItem, { isSelected: selectedCard?.id === card.id, onSelect: setCard, card }, card.id)) });
|
|
728
953
|
};
|
|
729
954
|
|
|
730
955
|
// src/components/CreditCardTab/CreditCard/CreditCardForm.tsx
|
|
731
|
-
import { useId
|
|
956
|
+
import { useId, useState as useState3 } from "react";
|
|
732
957
|
import { CardCvcElement, CardExpiryElement, CardNumberElement, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
733
958
|
|
|
734
959
|
// src/ui/button.tsx
|
|
735
960
|
import { Slot } from "@radix-ui/react-slot";
|
|
736
961
|
import { cva } from "class-variance-authority";
|
|
737
|
-
import { jsx as
|
|
962
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
738
963
|
var buttonVariants = cva(
|
|
739
964
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
740
965
|
{
|
|
@@ -769,15 +994,15 @@ function Button({
|
|
|
769
994
|
...props
|
|
770
995
|
}) {
|
|
771
996
|
const Comp = asChild ? Slot : "button";
|
|
772
|
-
return /* @__PURE__ */
|
|
997
|
+
return /* @__PURE__ */ jsx9(Comp, { "data-slot": "button", className: cn(buttonVariants({ variant, size, className })), ...props });
|
|
773
998
|
}
|
|
774
999
|
|
|
775
1000
|
// src/ui/checkbox.tsx
|
|
776
1001
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
777
1002
|
import { CheckIcon } from "lucide-react";
|
|
778
|
-
import { jsx as
|
|
1003
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
779
1004
|
function Checkbox({ className, ...props }) {
|
|
780
|
-
return /* @__PURE__ */
|
|
1005
|
+
return /* @__PURE__ */ jsx10(
|
|
781
1006
|
CheckboxPrimitive.Root,
|
|
782
1007
|
{
|
|
783
1008
|
"data-slot": "checkbox",
|
|
@@ -786,20 +1011,37 @@ function Checkbox({ className, ...props }) {
|
|
|
786
1011
|
className
|
|
787
1012
|
),
|
|
788
1013
|
...props,
|
|
789
|
-
children: /* @__PURE__ */
|
|
1014
|
+
children: /* @__PURE__ */ jsx10(
|
|
790
1015
|
CheckboxPrimitive.Indicator,
|
|
791
1016
|
{
|
|
792
1017
|
"data-slot": "checkbox-indicator",
|
|
793
1018
|
className: "flex items-center justify-center text-current transition-none",
|
|
794
|
-
children: /* @__PURE__ */
|
|
1019
|
+
children: /* @__PURE__ */ jsx10(CheckIcon, { className: "size-3.5 text-white" })
|
|
795
1020
|
}
|
|
796
1021
|
)
|
|
797
1022
|
}
|
|
798
1023
|
);
|
|
799
1024
|
}
|
|
800
1025
|
|
|
1026
|
+
// src/ui/label.tsx
|
|
1027
|
+
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
1028
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1029
|
+
function Label({ className, ...props }) {
|
|
1030
|
+
return /* @__PURE__ */ jsx11(
|
|
1031
|
+
LabelPrimitive.Root,
|
|
1032
|
+
{
|
|
1033
|
+
"data-slot": "label",
|
|
1034
|
+
className: cn(
|
|
1035
|
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
1036
|
+
className
|
|
1037
|
+
),
|
|
1038
|
+
...props
|
|
1039
|
+
}
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
|
|
801
1043
|
// src/components/CreditCardTab/CreditCard/CreditCardForm.tsx
|
|
802
|
-
import { Fragment, jsx as
|
|
1044
|
+
import { Fragment, jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
803
1045
|
var style = {
|
|
804
1046
|
base: {
|
|
805
1047
|
fontSize: "16px",
|
|
@@ -819,10 +1061,10 @@ var stripeElementClasses = {
|
|
|
819
1061
|
focus: "border-ring ring-ring/50 ring-2"
|
|
820
1062
|
};
|
|
821
1063
|
var CreditCardForm = ({ cancel, saveCard }) => {
|
|
822
|
-
const [cardError, setCardError] =
|
|
1064
|
+
const [cardError, setCardError] = useState3(void 0);
|
|
823
1065
|
const elements = useElements();
|
|
824
1066
|
const stripe = useStripe();
|
|
825
|
-
const id =
|
|
1067
|
+
const id = useId();
|
|
826
1068
|
const handleSaveCard = async () => {
|
|
827
1069
|
if (!elements || !stripe) return;
|
|
828
1070
|
setCardError(void 0);
|
|
@@ -857,9 +1099,9 @@ var CreditCardForm = ({ cancel, saveCard }) => {
|
|
|
857
1099
|
setCardError("An error occurred while processing your card. Please try again.");
|
|
858
1100
|
}
|
|
859
1101
|
};
|
|
860
|
-
return /* @__PURE__ */
|
|
861
|
-
/* @__PURE__ */
|
|
862
|
-
/* @__PURE__ */
|
|
1102
|
+
return /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
1103
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex w-full flex-col gap-1", children: [
|
|
1104
|
+
/* @__PURE__ */ jsx12(
|
|
863
1105
|
CardNumberElement,
|
|
864
1106
|
{
|
|
865
1107
|
options: {
|
|
@@ -869,8 +1111,8 @@ var CreditCardForm = ({ cancel, saveCard }) => {
|
|
|
869
1111
|
}
|
|
870
1112
|
}
|
|
871
1113
|
),
|
|
872
|
-
/* @__PURE__ */
|
|
873
|
-
/* @__PURE__ */
|
|
1114
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex w-full gap-1", children: [
|
|
1115
|
+
/* @__PURE__ */ jsx12(
|
|
874
1116
|
CardExpiryElement,
|
|
875
1117
|
{
|
|
876
1118
|
options: {
|
|
@@ -880,7 +1122,7 @@ var CreditCardForm = ({ cancel, saveCard }) => {
|
|
|
880
1122
|
}
|
|
881
1123
|
}
|
|
882
1124
|
),
|
|
883
|
-
/* @__PURE__ */
|
|
1125
|
+
/* @__PURE__ */ jsx12(
|
|
884
1126
|
CardCvcElement,
|
|
885
1127
|
{
|
|
886
1128
|
options: {
|
|
@@ -891,32 +1133,32 @@ var CreditCardForm = ({ cancel, saveCard }) => {
|
|
|
891
1133
|
}
|
|
892
1134
|
)
|
|
893
1135
|
] }),
|
|
894
|
-
cardError && /* @__PURE__ */
|
|
1136
|
+
cardError && /* @__PURE__ */ jsx12("p", { className: "text-destructive mt-1 text-sm", children: cardError })
|
|
895
1137
|
] }),
|
|
896
|
-
/* @__PURE__ */
|
|
897
|
-
/* @__PURE__ */
|
|
898
|
-
/* @__PURE__ */
|
|
1138
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
1139
|
+
/* @__PURE__ */ jsx12(Checkbox, { disabled: true, checked: true, id: "saveCard" }),
|
|
1140
|
+
/* @__PURE__ */ jsx12(Label, { className: "text-sm font-medium", htmlFor: "saveCard", children: "Save card for future purchases" })
|
|
899
1141
|
] }),
|
|
900
|
-
/* @__PURE__ */
|
|
901
|
-
/* @__PURE__ */
|
|
902
|
-
/* @__PURE__ */
|
|
1142
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex w-full justify-end gap-2", children: [
|
|
1143
|
+
/* @__PURE__ */ jsx12(Button, { variant: "secondary", onClick: cancel, children: "Cancel" }),
|
|
1144
|
+
/* @__PURE__ */ jsx12(Button, { onClick: handleSaveCard, children: "Add Card" })
|
|
903
1145
|
] })
|
|
904
1146
|
] });
|
|
905
1147
|
};
|
|
906
1148
|
|
|
907
1149
|
// src/components/CreditCardTab/CreditCard/CreditCard.tsx
|
|
908
|
-
import { Fragment as Fragment2, jsx as
|
|
909
|
-
var
|
|
910
|
-
const stripePromise =
|
|
911
|
-
return /* @__PURE__ */
|
|
1150
|
+
import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1151
|
+
var StripeWrapper = (props) => {
|
|
1152
|
+
const stripePromise = useMemo2(() => loadStripe(props.publicKey), [props.publicKey]);
|
|
1153
|
+
return /* @__PURE__ */ jsx13(Elements, { stripe: stripePromise, children: /* @__PURE__ */ jsx13(CreditCardForm, { cancel: props.onCancel, saveCard: props.saveNewCard }) });
|
|
912
1154
|
};
|
|
913
1155
|
var CreditCard = () => {
|
|
914
|
-
const [showForm, setShowForm] =
|
|
1156
|
+
const [showForm, setShowForm] = useState4(false);
|
|
915
1157
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
916
1158
|
const { mutateCards } = useCards();
|
|
917
|
-
const {
|
|
1159
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
918
1160
|
const setCard = (card) => {
|
|
919
|
-
setSelectedPaymentMethod({ type: "CREDIT_CARD" /* CREDIT_CARD */, method: card });
|
|
1161
|
+
setSelectedPaymentMethod({ ...selectedPaymentMethod, type: "CREDIT_CARD" /* CREDIT_CARD */, method: card });
|
|
920
1162
|
};
|
|
921
1163
|
const saveNewCard = (newCard) => {
|
|
922
1164
|
mutateCards((data) => ({ ...data, data: [...data?.data ?? [], newCard] }), { revalidate: false });
|
|
@@ -926,130 +1168,1249 @@ var CreditCard = () => {
|
|
|
926
1168
|
const handleCancel = () => {
|
|
927
1169
|
setShowForm(false);
|
|
928
1170
|
};
|
|
929
|
-
return /* @__PURE__ */
|
|
930
|
-
/* @__PURE__ */
|
|
931
|
-
!showForm && /* @__PURE__ */
|
|
932
|
-
/* @__PURE__ */
|
|
1171
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex flex-col items-baseline gap-4", children: [
|
|
1172
|
+
/* @__PURE__ */ jsx13("h3", { className: "text-primary text-xl leading-[34px] font-semibold", children: "Your Credit Cards" }),
|
|
1173
|
+
!showForm && /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
1174
|
+
/* @__PURE__ */ jsx13(
|
|
933
1175
|
CardsList,
|
|
934
1176
|
{
|
|
935
1177
|
selectedCard: selectedPaymentMethod?.type === "CREDIT_CARD" /* CREDIT_CARD */ ? selectedPaymentMethod.method : null,
|
|
936
1178
|
setCard
|
|
937
1179
|
}
|
|
938
1180
|
),
|
|
939
|
-
|
|
1181
|
+
spreePayConfig?.stripePublicKey && /* @__PURE__ */ jsx13("button", { onClick: () => setShowForm(true), className: "text-sm font-medium text-black hover:underline", children: "Add new card" })
|
|
940
1182
|
] }),
|
|
941
|
-
|
|
1183
|
+
spreePayConfig?.stripePublicKey && showForm && /* @__PURE__ */ jsx13(StripeWrapper, { onCancel: handleCancel, saveNewCard, publicKey: spreePayConfig.stripePublicKey })
|
|
942
1184
|
] });
|
|
943
1185
|
};
|
|
944
1186
|
|
|
945
|
-
// src/components/CreditCardTab/
|
|
946
|
-
import {
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
}),
|
|
957
|
-
children: [
|
|
958
|
-
/* @__PURE__ */ jsxs10("div", { className: cn("flex h-11 w-full", { "bg-black/4": isSelected }), children: [
|
|
959
|
-
/* @__PURE__ */ jsx15(
|
|
960
|
-
"div",
|
|
961
|
-
{
|
|
962
|
-
className: cn("flex h-full w-11 items-center justify-center bg-black/10", {
|
|
963
|
-
"bg-primary": isSelected
|
|
964
|
-
}),
|
|
965
|
-
children: /* @__PURE__ */ jsx15("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white", children: isSelected && /* @__PURE__ */ jsx15("div", { className: "bg-primary h-2.5 w-2.5 rounded-full" }) })
|
|
966
|
-
}
|
|
967
|
-
),
|
|
968
|
-
/* @__PURE__ */ jsx15("div", { className: "flex h-full w-full items-center justify-between gap-4 px-3", children })
|
|
969
|
-
] }),
|
|
970
|
-
isSelected && /* @__PURE__ */ jsx15("div", { className: "px-4 pt-6 pb-2", children: /* @__PURE__ */ jsx15("p", { children: "Card" }) })
|
|
971
|
-
]
|
|
972
|
-
}
|
|
973
|
-
)
|
|
974
|
-
);
|
|
1187
|
+
// src/components/CreditCardTab/Points/Points.tsx
|
|
1188
|
+
import { useState as useState10 } from "react";
|
|
1189
|
+
|
|
1190
|
+
// src/components/common/PointsSwitch.tsx
|
|
1191
|
+
import { useId as useId2 } from "react";
|
|
1192
|
+
|
|
1193
|
+
// src/hooks/useSlapiBalance.ts
|
|
1194
|
+
import useSWR3 from "swr";
|
|
1195
|
+
var useSlapiBalance = () => {
|
|
1196
|
+
const { data, isLoading, mutate } = useSWR3(`/v1/loyalty/accounts`);
|
|
1197
|
+
return { balance: data?.detail, isBalanceLoading: isLoading, mutateBalance: mutate };
|
|
975
1198
|
};
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1199
|
+
|
|
1200
|
+
// src/ui/switch.tsx
|
|
1201
|
+
import * as SwitchPrimitive from "@radix-ui/react-switch";
|
|
1202
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1203
|
+
function Switch({ className, ...props }) {
|
|
1204
|
+
return /* @__PURE__ */ jsx14(
|
|
1205
|
+
SwitchPrimitive.Root,
|
|
1206
|
+
{
|
|
1207
|
+
"data-slot": "switch",
|
|
1208
|
+
className: cn(
|
|
1209
|
+
"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
|
1210
|
+
className
|
|
1211
|
+
),
|
|
1212
|
+
...props,
|
|
1213
|
+
children: /* @__PURE__ */ jsx14(
|
|
1214
|
+
SwitchPrimitive.Thumb,
|
|
1215
|
+
{
|
|
1216
|
+
"data-slot": "switch-thumb",
|
|
1217
|
+
className: "bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
|
|
1218
|
+
}
|
|
1219
|
+
)
|
|
1220
|
+
}
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
// src/components/common/PointsSwitch.tsx
|
|
1225
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1226
|
+
var PointsSwitch = (props) => {
|
|
1227
|
+
const { disabled = false, value, onChange } = props;
|
|
1228
|
+
const { staticConfig } = useStaticConfig();
|
|
1229
|
+
const { pointsConversionRatio, pointsTitle } = staticConfig;
|
|
1230
|
+
const { balance } = useSlapiBalance();
|
|
1231
|
+
const id = useId2();
|
|
1232
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between gap-3", children: [
|
|
1233
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3", children: [
|
|
1234
|
+
/* @__PURE__ */ jsx15(Switch, { checked: value, onCheckedChange: onChange, disabled, id }),
|
|
1235
|
+
/* @__PURE__ */ jsxs9(Label, { className: "text-md items-baseline leading-[1.3] font-semibold text-black md:text-xl", htmlFor: id, children: [
|
|
1236
|
+
"Use Points ",
|
|
1237
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs font-medium", children: "Optional" })
|
|
1238
|
+
] })
|
|
1239
|
+
] }),
|
|
1240
|
+
balance?.availablePoints ? /* @__PURE__ */ jsxs9("p", { className: "flex-1 text-right text-sm font-medium text-black", children: [
|
|
1241
|
+
formatPoints(balance.availablePoints, pointsTitle),
|
|
1242
|
+
" ",
|
|
1243
|
+
/* @__PURE__ */ jsx15("span", { className: "text-black/50", children: formatUSD(balance.availablePoints / pointsConversionRatio) })
|
|
1244
|
+
] }) : null
|
|
1245
|
+
] });
|
|
1246
|
+
};
|
|
1247
|
+
|
|
1248
|
+
// src/components/CreditCardTab/Points/SplitBlock.tsx
|
|
1249
|
+
import { useCallback as useCallback4, useEffect as useEffect6, useState as useState9 } from "react";
|
|
1250
|
+
|
|
1251
|
+
// src/components/CreditCardTab/Points/PointsSelector.tsx
|
|
1252
|
+
import { useState as useState8 } from "react";
|
|
1253
|
+
|
|
1254
|
+
// src/ui/input.tsx
|
|
1255
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1256
|
+
function Input({ className, type, ...props }) {
|
|
1257
|
+
return /* @__PURE__ */ jsx16(
|
|
1258
|
+
"input",
|
|
1259
|
+
{
|
|
1260
|
+
type,
|
|
1261
|
+
"data-slot": "input",
|
|
1262
|
+
className: cn(
|
|
1263
|
+
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1264
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
1265
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
1266
|
+
className
|
|
1267
|
+
),
|
|
1268
|
+
...props
|
|
1269
|
+
}
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
// src/ui/slider.tsx
|
|
1274
|
+
import * as React12 from "react";
|
|
1275
|
+
|
|
1276
|
+
// ../../node_modules/@radix-ui/react-slider/dist/index.mjs
|
|
1277
|
+
import * as React11 from "react";
|
|
1278
|
+
|
|
1279
|
+
// ../../node_modules/@radix-ui/number/dist/index.mjs
|
|
1280
|
+
function clamp(value, [min, max]) {
|
|
1281
|
+
return Math.min(max, Math.max(min, value));
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
// ../../node_modules/@radix-ui/react-slider/node_modules/@radix-ui/primitive/dist/index.mjs
|
|
1285
|
+
var canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement);
|
|
1286
|
+
function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
|
|
1287
|
+
return function handleEvent(event) {
|
|
1288
|
+
originalEventHandler?.(event);
|
|
1289
|
+
if (checkForDefaultPrevented === false || !event.defaultPrevented) {
|
|
1290
|
+
return ourEventHandler?.(event);
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
// ../../node_modules/@radix-ui/react-compose-refs/dist/index.mjs
|
|
1296
|
+
import * as React2 from "react";
|
|
1297
|
+
function setRef(ref, value) {
|
|
1298
|
+
if (typeof ref === "function") {
|
|
1299
|
+
return ref(value);
|
|
1300
|
+
} else if (ref !== null && ref !== void 0) {
|
|
1301
|
+
ref.current = value;
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
function composeRefs(...refs) {
|
|
1305
|
+
return (node) => {
|
|
1306
|
+
let hasCleanup = false;
|
|
1307
|
+
const cleanups = refs.map((ref) => {
|
|
1308
|
+
const cleanup = setRef(ref, node);
|
|
1309
|
+
if (!hasCleanup && typeof cleanup == "function") {
|
|
1310
|
+
hasCleanup = true;
|
|
1311
|
+
}
|
|
1312
|
+
return cleanup;
|
|
1313
|
+
});
|
|
1314
|
+
if (hasCleanup) {
|
|
1315
|
+
return () => {
|
|
1316
|
+
for (let i = 0; i < cleanups.length; i++) {
|
|
1317
|
+
const cleanup = cleanups[i];
|
|
1318
|
+
if (typeof cleanup == "function") {
|
|
1319
|
+
cleanup();
|
|
1320
|
+
} else {
|
|
1321
|
+
setRef(refs[i], null);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
function useComposedRefs(...refs) {
|
|
1329
|
+
return React2.useCallback(composeRefs(...refs), refs);
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
// ../../node_modules/@radix-ui/react-context/dist/index.mjs
|
|
1333
|
+
import * as React3 from "react";
|
|
1334
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1335
|
+
function createContextScope(scopeName, createContextScopeDeps = []) {
|
|
1336
|
+
let defaultContexts = [];
|
|
1337
|
+
function createContext32(rootComponentName, defaultContext) {
|
|
1338
|
+
const BaseContext = React3.createContext(defaultContext);
|
|
1339
|
+
const index = defaultContexts.length;
|
|
1340
|
+
defaultContexts = [...defaultContexts, defaultContext];
|
|
1341
|
+
const Provider = (props) => {
|
|
1342
|
+
const { scope, children, ...context } = props;
|
|
1343
|
+
const Context = scope?.[scopeName]?.[index] || BaseContext;
|
|
1344
|
+
const value = React3.useMemo(() => context, Object.values(context));
|
|
1345
|
+
return /* @__PURE__ */ jsx17(Context.Provider, { value, children });
|
|
1346
|
+
};
|
|
1347
|
+
Provider.displayName = rootComponentName + "Provider";
|
|
1348
|
+
function useContext22(consumerName, scope) {
|
|
1349
|
+
const Context = scope?.[scopeName]?.[index] || BaseContext;
|
|
1350
|
+
const context = React3.useContext(Context);
|
|
1351
|
+
if (context) return context;
|
|
1352
|
+
if (defaultContext !== void 0) return defaultContext;
|
|
1353
|
+
throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``);
|
|
1354
|
+
}
|
|
1355
|
+
return [Provider, useContext22];
|
|
1356
|
+
}
|
|
1357
|
+
const createScope = () => {
|
|
1358
|
+
const scopeContexts = defaultContexts.map((defaultContext) => {
|
|
1359
|
+
return React3.createContext(defaultContext);
|
|
1360
|
+
});
|
|
1361
|
+
return function useScope(scope) {
|
|
1362
|
+
const contexts = scope?.[scopeName] || scopeContexts;
|
|
1363
|
+
return React3.useMemo(
|
|
1364
|
+
() => ({ [`__scope${scopeName}`]: { ...scope, [scopeName]: contexts } }),
|
|
1365
|
+
[scope, contexts]
|
|
1366
|
+
);
|
|
1367
|
+
};
|
|
1368
|
+
};
|
|
1369
|
+
createScope.scopeName = scopeName;
|
|
1370
|
+
return [createContext32, composeContextScopes(createScope, ...createContextScopeDeps)];
|
|
1371
|
+
}
|
|
1372
|
+
function composeContextScopes(...scopes) {
|
|
1373
|
+
const baseScope = scopes[0];
|
|
1374
|
+
if (scopes.length === 1) return baseScope;
|
|
1375
|
+
const createScope = () => {
|
|
1376
|
+
const scopeHooks = scopes.map((createScope2) => ({
|
|
1377
|
+
useScope: createScope2(),
|
|
1378
|
+
scopeName: createScope2.scopeName
|
|
1379
|
+
}));
|
|
1380
|
+
return function useComposedScopes(overrideScopes) {
|
|
1381
|
+
const nextScopes = scopeHooks.reduce((nextScopes2, { useScope, scopeName }) => {
|
|
1382
|
+
const scopeProps = useScope(overrideScopes);
|
|
1383
|
+
const currentScope = scopeProps[`__scope${scopeName}`];
|
|
1384
|
+
return { ...nextScopes2, ...currentScope };
|
|
1385
|
+
}, {});
|
|
1386
|
+
return React3.useMemo(() => ({ [`__scope${baseScope.scopeName}`]: nextScopes }), [nextScopes]);
|
|
1387
|
+
};
|
|
1388
|
+
};
|
|
1389
|
+
createScope.scopeName = baseScope.scopeName;
|
|
1390
|
+
return createScope;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
// ../../node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs
|
|
1394
|
+
import * as React5 from "react";
|
|
1395
|
+
|
|
1396
|
+
// ../../node_modules/@radix-ui/react-use-layout-effect/dist/index.mjs
|
|
1397
|
+
import * as React4 from "react";
|
|
1398
|
+
var useLayoutEffect2 = globalThis?.document ? React4.useLayoutEffect : () => {
|
|
1399
|
+
};
|
|
1400
|
+
|
|
1401
|
+
// ../../node_modules/@radix-ui/react-use-controllable-state/dist/index.mjs
|
|
1402
|
+
import * as React22 from "react";
|
|
1403
|
+
var useInsertionEffect = React5[" useInsertionEffect ".trim().toString()] || useLayoutEffect2;
|
|
1404
|
+
function useControllableState({
|
|
1405
|
+
prop,
|
|
1406
|
+
defaultProp,
|
|
1407
|
+
onChange = () => {
|
|
1408
|
+
},
|
|
1409
|
+
caller
|
|
1410
|
+
}) {
|
|
1411
|
+
const [uncontrolledProp, setUncontrolledProp, onChangeRef] = useUncontrolledState({
|
|
1412
|
+
defaultProp,
|
|
1413
|
+
onChange
|
|
1414
|
+
});
|
|
1415
|
+
const isControlled = prop !== void 0;
|
|
1416
|
+
const value = isControlled ? prop : uncontrolledProp;
|
|
1417
|
+
if (true) {
|
|
1418
|
+
const isControlledRef = React5.useRef(prop !== void 0);
|
|
1419
|
+
React5.useEffect(() => {
|
|
1420
|
+
const wasControlled = isControlledRef.current;
|
|
1421
|
+
if (wasControlled !== isControlled) {
|
|
1422
|
+
const from = wasControlled ? "controlled" : "uncontrolled";
|
|
1423
|
+
const to = isControlled ? "controlled" : "uncontrolled";
|
|
1424
|
+
console.warn(
|
|
1425
|
+
`${caller} is changing from ${from} to ${to}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`
|
|
1426
|
+
);
|
|
1427
|
+
}
|
|
1428
|
+
isControlledRef.current = isControlled;
|
|
1429
|
+
}, [isControlled, caller]);
|
|
1430
|
+
}
|
|
1431
|
+
const setValue = React5.useCallback(
|
|
1432
|
+
(nextValue) => {
|
|
1433
|
+
if (isControlled) {
|
|
1434
|
+
const value2 = isFunction(nextValue) ? nextValue(prop) : nextValue;
|
|
1435
|
+
if (value2 !== prop) {
|
|
1436
|
+
onChangeRef.current?.(value2);
|
|
1437
|
+
}
|
|
1438
|
+
} else {
|
|
1439
|
+
setUncontrolledProp(nextValue);
|
|
1440
|
+
}
|
|
1441
|
+
},
|
|
1442
|
+
[isControlled, prop, setUncontrolledProp, onChangeRef]
|
|
1443
|
+
);
|
|
1444
|
+
return [value, setValue];
|
|
1445
|
+
}
|
|
1446
|
+
function useUncontrolledState({
|
|
1447
|
+
defaultProp,
|
|
1448
|
+
onChange
|
|
1449
|
+
}) {
|
|
1450
|
+
const [value, setValue] = React5.useState(defaultProp);
|
|
1451
|
+
const prevValueRef = React5.useRef(value);
|
|
1452
|
+
const onChangeRef = React5.useRef(onChange);
|
|
1453
|
+
useInsertionEffect(() => {
|
|
1454
|
+
onChangeRef.current = onChange;
|
|
1455
|
+
}, [onChange]);
|
|
1456
|
+
React5.useEffect(() => {
|
|
1457
|
+
if (prevValueRef.current !== value) {
|
|
1458
|
+
onChangeRef.current?.(value);
|
|
1459
|
+
prevValueRef.current = value;
|
|
1460
|
+
}
|
|
1461
|
+
}, [value, prevValueRef]);
|
|
1462
|
+
return [value, setValue, onChangeRef];
|
|
1463
|
+
}
|
|
1464
|
+
function isFunction(value) {
|
|
1465
|
+
return typeof value === "function";
|
|
1466
|
+
}
|
|
1467
|
+
var SYNC_STATE = Symbol("RADIX:SYNC_STATE");
|
|
1468
|
+
|
|
1469
|
+
// ../../node_modules/@radix-ui/react-direction/dist/index.mjs
|
|
1470
|
+
import * as React6 from "react";
|
|
1471
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1472
|
+
var DirectionContext = React6.createContext(void 0);
|
|
1473
|
+
function useDirection(localDir) {
|
|
1474
|
+
const globalDir = React6.useContext(DirectionContext);
|
|
1475
|
+
return localDir || globalDir || "ltr";
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
// ../../node_modules/@radix-ui/react-use-previous/dist/index.mjs
|
|
1479
|
+
import * as React7 from "react";
|
|
1480
|
+
function usePrevious(value) {
|
|
1481
|
+
const ref = React7.useRef({ value, previous: value });
|
|
1482
|
+
return React7.useMemo(() => {
|
|
1483
|
+
if (ref.current.value !== value) {
|
|
1484
|
+
ref.current.previous = ref.current.value;
|
|
1485
|
+
ref.current.value = value;
|
|
1486
|
+
}
|
|
1487
|
+
return ref.current.previous;
|
|
1488
|
+
}, [value]);
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
// ../../node_modules/@radix-ui/react-use-size/dist/index.mjs
|
|
1492
|
+
import * as React8 from "react";
|
|
1493
|
+
function useSize(element) {
|
|
1494
|
+
const [size, setSize] = React8.useState(void 0);
|
|
1495
|
+
useLayoutEffect2(() => {
|
|
1496
|
+
if (element) {
|
|
1497
|
+
setSize({ width: element.offsetWidth, height: element.offsetHeight });
|
|
1498
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
1499
|
+
if (!Array.isArray(entries)) {
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1502
|
+
if (!entries.length) {
|
|
1503
|
+
return;
|
|
1504
|
+
}
|
|
1505
|
+
const entry = entries[0];
|
|
1506
|
+
let width;
|
|
1507
|
+
let height;
|
|
1508
|
+
if ("borderBoxSize" in entry) {
|
|
1509
|
+
const borderSizeEntry = entry["borderBoxSize"];
|
|
1510
|
+
const borderSize = Array.isArray(borderSizeEntry) ? borderSizeEntry[0] : borderSizeEntry;
|
|
1511
|
+
width = borderSize["inlineSize"];
|
|
1512
|
+
height = borderSize["blockSize"];
|
|
1513
|
+
} else {
|
|
1514
|
+
width = element.offsetWidth;
|
|
1515
|
+
height = element.offsetHeight;
|
|
1516
|
+
}
|
|
1517
|
+
setSize({ width, height });
|
|
1518
|
+
});
|
|
1519
|
+
resizeObserver.observe(element, { box: "border-box" });
|
|
1520
|
+
return () => resizeObserver.unobserve(element);
|
|
1521
|
+
} else {
|
|
1522
|
+
setSize(void 0);
|
|
1523
|
+
}
|
|
1524
|
+
}, [element]);
|
|
1525
|
+
return size;
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
// ../../node_modules/@radix-ui/react-primitive/dist/index.mjs
|
|
1529
|
+
import * as React9 from "react";
|
|
1530
|
+
import * as ReactDOM from "react-dom";
|
|
1531
|
+
import { createSlot } from "@radix-ui/react-slot";
|
|
1532
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1533
|
+
var NODES = [
|
|
1534
|
+
"a",
|
|
1535
|
+
"button",
|
|
1536
|
+
"div",
|
|
1537
|
+
"form",
|
|
1538
|
+
"h2",
|
|
1539
|
+
"h3",
|
|
1540
|
+
"img",
|
|
1541
|
+
"input",
|
|
1542
|
+
"label",
|
|
1543
|
+
"li",
|
|
1544
|
+
"nav",
|
|
1545
|
+
"ol",
|
|
1546
|
+
"p",
|
|
1547
|
+
"select",
|
|
1548
|
+
"span",
|
|
1549
|
+
"svg",
|
|
1550
|
+
"ul"
|
|
1551
|
+
];
|
|
1552
|
+
var Primitive = NODES.reduce((primitive, node) => {
|
|
1553
|
+
const Slot2 = createSlot(`Primitive.${node}`);
|
|
1554
|
+
const Node2 = React9.forwardRef((props, forwardedRef) => {
|
|
1555
|
+
const { asChild, ...primitiveProps } = props;
|
|
1556
|
+
const Comp = asChild ? Slot2 : node;
|
|
1557
|
+
if (typeof window !== "undefined") {
|
|
1558
|
+
window[Symbol.for("radix-ui")] = true;
|
|
1559
|
+
}
|
|
1560
|
+
return /* @__PURE__ */ jsx19(Comp, { ...primitiveProps, ref: forwardedRef });
|
|
1561
|
+
});
|
|
1562
|
+
Node2.displayName = `Primitive.${node}`;
|
|
1563
|
+
return { ...primitive, [node]: Node2 };
|
|
1564
|
+
}, {});
|
|
1565
|
+
|
|
1566
|
+
// ../../node_modules/@radix-ui/react-collection/dist/index.mjs
|
|
1567
|
+
import React10 from "react";
|
|
1568
|
+
import { createSlot as createSlot2 } from "@radix-ui/react-slot";
|
|
1569
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1570
|
+
import React23 from "react";
|
|
1571
|
+
import { createSlot as createSlot22 } from "@radix-ui/react-slot";
|
|
1572
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1573
|
+
function createCollection(name) {
|
|
1574
|
+
const PROVIDER_NAME = name + "CollectionProvider";
|
|
1575
|
+
const [createCollectionContext, createCollectionScope2] = createContextScope(PROVIDER_NAME);
|
|
1576
|
+
const [CollectionProviderImpl, useCollectionContext] = createCollectionContext(
|
|
1577
|
+
PROVIDER_NAME,
|
|
1578
|
+
{ collectionRef: { current: null }, itemMap: /* @__PURE__ */ new Map() }
|
|
1579
|
+
);
|
|
1580
|
+
const CollectionProvider = (props) => {
|
|
1581
|
+
const { scope, children } = props;
|
|
1582
|
+
const ref = React10.useRef(null);
|
|
1583
|
+
const itemMap = React10.useRef(/* @__PURE__ */ new Map()).current;
|
|
1584
|
+
return /* @__PURE__ */ jsx20(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
|
|
1585
|
+
};
|
|
1586
|
+
CollectionProvider.displayName = PROVIDER_NAME;
|
|
1587
|
+
const COLLECTION_SLOT_NAME = name + "CollectionSlot";
|
|
1588
|
+
const CollectionSlotImpl = createSlot2(COLLECTION_SLOT_NAME);
|
|
1589
|
+
const CollectionSlot = React10.forwardRef(
|
|
1590
|
+
(props, forwardedRef) => {
|
|
1591
|
+
const { scope, children } = props;
|
|
1592
|
+
const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
|
|
1593
|
+
const composedRefs = useComposedRefs(forwardedRef, context.collectionRef);
|
|
1594
|
+
return /* @__PURE__ */ jsx20(CollectionSlotImpl, { ref: composedRefs, children });
|
|
1595
|
+
}
|
|
1596
|
+
);
|
|
1597
|
+
CollectionSlot.displayName = COLLECTION_SLOT_NAME;
|
|
1598
|
+
const ITEM_SLOT_NAME = name + "CollectionItemSlot";
|
|
1599
|
+
const ITEM_DATA_ATTR = "data-radix-collection-item";
|
|
1600
|
+
const CollectionItemSlotImpl = createSlot2(ITEM_SLOT_NAME);
|
|
1601
|
+
const CollectionItemSlot = React10.forwardRef(
|
|
1602
|
+
(props, forwardedRef) => {
|
|
1603
|
+
const { scope, children, ...itemData } = props;
|
|
1604
|
+
const ref = React10.useRef(null);
|
|
1605
|
+
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
1606
|
+
const context = useCollectionContext(ITEM_SLOT_NAME, scope);
|
|
1607
|
+
React10.useEffect(() => {
|
|
1608
|
+
context.itemMap.set(ref, { ref, ...itemData });
|
|
1609
|
+
return () => void context.itemMap.delete(ref);
|
|
1610
|
+
});
|
|
1611
|
+
return /* @__PURE__ */ jsx20(CollectionItemSlotImpl, { ...{ [ITEM_DATA_ATTR]: "" }, ref: composedRefs, children });
|
|
1612
|
+
}
|
|
1613
|
+
);
|
|
1614
|
+
CollectionItemSlot.displayName = ITEM_SLOT_NAME;
|
|
1615
|
+
function useCollection2(scope) {
|
|
1616
|
+
const context = useCollectionContext(name + "CollectionConsumer", scope);
|
|
1617
|
+
const getItems = React10.useCallback(() => {
|
|
1618
|
+
const collectionNode = context.collectionRef.current;
|
|
1619
|
+
if (!collectionNode) return [];
|
|
1620
|
+
const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
|
|
1621
|
+
const items = Array.from(context.itemMap.values());
|
|
1622
|
+
const orderedItems = items.sort(
|
|
1623
|
+
(a, b) => orderedNodes.indexOf(a.ref.current) - orderedNodes.indexOf(b.ref.current)
|
|
1624
|
+
);
|
|
1625
|
+
return orderedItems;
|
|
1626
|
+
}, [context.collectionRef, context.itemMap]);
|
|
1627
|
+
return getItems;
|
|
1628
|
+
}
|
|
1629
|
+
return [
|
|
1630
|
+
{ Provider: CollectionProvider, Slot: CollectionSlot, ItemSlot: CollectionItemSlot },
|
|
1631
|
+
useCollection2,
|
|
1632
|
+
createCollectionScope2
|
|
1633
|
+
];
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
// ../../node_modules/@radix-ui/react-slider/dist/index.mjs
|
|
1637
|
+
import { jsx as jsx21, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1638
|
+
var PAGE_KEYS = ["PageUp", "PageDown"];
|
|
1639
|
+
var ARROW_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
|
|
1640
|
+
var BACK_KEYS = {
|
|
1641
|
+
"from-left": ["Home", "PageDown", "ArrowDown", "ArrowLeft"],
|
|
1642
|
+
"from-right": ["Home", "PageDown", "ArrowDown", "ArrowRight"],
|
|
1643
|
+
"from-bottom": ["Home", "PageDown", "ArrowDown", "ArrowLeft"],
|
|
1644
|
+
"from-top": ["Home", "PageDown", "ArrowUp", "ArrowLeft"]
|
|
1645
|
+
};
|
|
1646
|
+
var SLIDER_NAME = "Slider";
|
|
1647
|
+
var [Collection, useCollection, createCollectionScope] = createCollection(SLIDER_NAME);
|
|
1648
|
+
var [createSliderContext, createSliderScope] = createContextScope(SLIDER_NAME, [
|
|
1649
|
+
createCollectionScope
|
|
1650
|
+
]);
|
|
1651
|
+
var [SliderProvider, useSliderContext] = createSliderContext(SLIDER_NAME);
|
|
1652
|
+
var Slider = React11.forwardRef(
|
|
1653
|
+
(props, forwardedRef) => {
|
|
1654
|
+
const {
|
|
1655
|
+
name,
|
|
1656
|
+
min = 0,
|
|
1657
|
+
max = 100,
|
|
1658
|
+
step = 1,
|
|
1659
|
+
orientation = "horizontal",
|
|
1660
|
+
disabled = false,
|
|
1661
|
+
minStepsBetweenThumbs = 0,
|
|
1662
|
+
defaultValue = [min],
|
|
1663
|
+
value,
|
|
1664
|
+
onValueChange = () => {
|
|
1665
|
+
},
|
|
1666
|
+
onValueCommit = () => {
|
|
1667
|
+
},
|
|
1668
|
+
inverted = false,
|
|
1669
|
+
form,
|
|
1670
|
+
...sliderProps
|
|
1671
|
+
} = props;
|
|
1672
|
+
const thumbRefs = React11.useRef(/* @__PURE__ */ new Set());
|
|
1673
|
+
const valueIndexToChangeRef = React11.useRef(0);
|
|
1674
|
+
const isHorizontal = orientation === "horizontal";
|
|
1675
|
+
const SliderOrientation = isHorizontal ? SliderHorizontal : SliderVertical;
|
|
1676
|
+
const [values = [], setValues] = useControllableState({
|
|
1677
|
+
prop: value,
|
|
1678
|
+
defaultProp: defaultValue,
|
|
1679
|
+
onChange: (value2) => {
|
|
1680
|
+
const thumbs = [...thumbRefs.current];
|
|
1681
|
+
thumbs[valueIndexToChangeRef.current]?.focus();
|
|
1682
|
+
onValueChange(value2);
|
|
1683
|
+
}
|
|
1684
|
+
});
|
|
1685
|
+
const valuesBeforeSlideStartRef = React11.useRef(values);
|
|
1686
|
+
function handleSlideStart(value2) {
|
|
1687
|
+
const closestIndex = getClosestValueIndex(values, value2);
|
|
1688
|
+
updateValues(value2, closestIndex);
|
|
1689
|
+
}
|
|
1690
|
+
function handleSlideMove(value2) {
|
|
1691
|
+
updateValues(value2, valueIndexToChangeRef.current);
|
|
1692
|
+
}
|
|
1693
|
+
function handleSlideEnd() {
|
|
1694
|
+
const prevValue = valuesBeforeSlideStartRef.current[valueIndexToChangeRef.current];
|
|
1695
|
+
const nextValue = values[valueIndexToChangeRef.current];
|
|
1696
|
+
const hasChanged = nextValue !== prevValue;
|
|
1697
|
+
if (hasChanged) onValueCommit(values);
|
|
1698
|
+
}
|
|
1699
|
+
function updateValues(value2, atIndex, { commit } = { commit: false }) {
|
|
1700
|
+
const decimalCount = getDecimalCount(step);
|
|
1701
|
+
const snapToStep = roundValue(Math.round((value2 - min) / step) * step + min, decimalCount);
|
|
1702
|
+
const nextValue = clamp(snapToStep, [min, max]);
|
|
1703
|
+
setValues((prevValues = []) => {
|
|
1704
|
+
const nextValues = getNextSortedValues(prevValues, nextValue, atIndex);
|
|
1705
|
+
if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) {
|
|
1706
|
+
valueIndexToChangeRef.current = nextValues.indexOf(nextValue);
|
|
1707
|
+
const hasChanged = String(nextValues) !== String(prevValues);
|
|
1708
|
+
if (hasChanged && commit) onValueCommit(nextValues);
|
|
1709
|
+
return hasChanged ? nextValues : prevValues;
|
|
1710
|
+
} else {
|
|
1711
|
+
return prevValues;
|
|
1712
|
+
}
|
|
1713
|
+
});
|
|
1714
|
+
}
|
|
1715
|
+
return /* @__PURE__ */ jsx21(
|
|
1716
|
+
SliderProvider,
|
|
1717
|
+
{
|
|
1718
|
+
scope: props.__scopeSlider,
|
|
1719
|
+
name,
|
|
1720
|
+
disabled,
|
|
1721
|
+
min,
|
|
1722
|
+
max,
|
|
1723
|
+
valueIndexToChangeRef,
|
|
1724
|
+
thumbs: thumbRefs.current,
|
|
1725
|
+
values,
|
|
1726
|
+
orientation,
|
|
1727
|
+
form,
|
|
1728
|
+
children: /* @__PURE__ */ jsx21(Collection.Provider, { scope: props.__scopeSlider, children: /* @__PURE__ */ jsx21(Collection.Slot, { scope: props.__scopeSlider, children: /* @__PURE__ */ jsx21(
|
|
1729
|
+
SliderOrientation,
|
|
1730
|
+
{
|
|
1731
|
+
"aria-disabled": disabled,
|
|
1732
|
+
"data-disabled": disabled ? "" : void 0,
|
|
1733
|
+
...sliderProps,
|
|
1734
|
+
ref: forwardedRef,
|
|
1735
|
+
onPointerDown: composeEventHandlers(sliderProps.onPointerDown, () => {
|
|
1736
|
+
if (!disabled) valuesBeforeSlideStartRef.current = values;
|
|
1737
|
+
}),
|
|
1738
|
+
min,
|
|
1739
|
+
max,
|
|
1740
|
+
inverted,
|
|
1741
|
+
onSlideStart: disabled ? void 0 : handleSlideStart,
|
|
1742
|
+
onSlideMove: disabled ? void 0 : handleSlideMove,
|
|
1743
|
+
onSlideEnd: disabled ? void 0 : handleSlideEnd,
|
|
1744
|
+
onHomeKeyDown: () => !disabled && updateValues(min, 0, { commit: true }),
|
|
1745
|
+
onEndKeyDown: () => !disabled && updateValues(max, values.length - 1, { commit: true }),
|
|
1746
|
+
onStepKeyDown: ({ event, direction: stepDirection }) => {
|
|
1747
|
+
if (!disabled) {
|
|
1748
|
+
const isPageKey = PAGE_KEYS.includes(event.key);
|
|
1749
|
+
const isSkipKey = isPageKey || event.shiftKey && ARROW_KEYS.includes(event.key);
|
|
1750
|
+
const multiplier = isSkipKey ? 10 : 1;
|
|
1751
|
+
const atIndex = valueIndexToChangeRef.current;
|
|
1752
|
+
const value2 = values[atIndex];
|
|
1753
|
+
const stepInDirection = step * multiplier * stepDirection;
|
|
1754
|
+
updateValues(value2 + stepInDirection, atIndex, { commit: true });
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
) }) })
|
|
1759
|
+
}
|
|
1760
|
+
);
|
|
1761
|
+
}
|
|
1762
|
+
);
|
|
1763
|
+
Slider.displayName = SLIDER_NAME;
|
|
1764
|
+
var [SliderOrientationProvider, useSliderOrientationContext] = createSliderContext(SLIDER_NAME, {
|
|
1765
|
+
startEdge: "left",
|
|
1766
|
+
endEdge: "right",
|
|
1767
|
+
size: "width",
|
|
1768
|
+
direction: 1
|
|
1769
|
+
});
|
|
1770
|
+
var SliderHorizontal = React11.forwardRef(
|
|
1771
|
+
(props, forwardedRef) => {
|
|
1772
|
+
const {
|
|
1773
|
+
min,
|
|
1774
|
+
max,
|
|
1775
|
+
dir,
|
|
1776
|
+
inverted,
|
|
1777
|
+
onSlideStart,
|
|
1778
|
+
onSlideMove,
|
|
1779
|
+
onSlideEnd,
|
|
1780
|
+
onStepKeyDown,
|
|
1781
|
+
...sliderProps
|
|
1782
|
+
} = props;
|
|
1783
|
+
const [slider, setSlider] = React11.useState(null);
|
|
1784
|
+
const composedRefs = useComposedRefs(forwardedRef, (node) => setSlider(node));
|
|
1785
|
+
const rectRef = React11.useRef(void 0);
|
|
1786
|
+
const direction = useDirection(dir);
|
|
1787
|
+
const isDirectionLTR = direction === "ltr";
|
|
1788
|
+
const isSlidingFromLeft = isDirectionLTR && !inverted || !isDirectionLTR && inverted;
|
|
1789
|
+
function getValueFromPointer(pointerPosition) {
|
|
1790
|
+
const rect = rectRef.current || slider.getBoundingClientRect();
|
|
1791
|
+
const input = [0, rect.width];
|
|
1792
|
+
const output = isSlidingFromLeft ? [min, max] : [max, min];
|
|
1793
|
+
const value = linearScale(input, output);
|
|
1794
|
+
rectRef.current = rect;
|
|
1795
|
+
return value(pointerPosition - rect.left);
|
|
1796
|
+
}
|
|
1797
|
+
return /* @__PURE__ */ jsx21(
|
|
1798
|
+
SliderOrientationProvider,
|
|
1799
|
+
{
|
|
1800
|
+
scope: props.__scopeSlider,
|
|
1801
|
+
startEdge: isSlidingFromLeft ? "left" : "right",
|
|
1802
|
+
endEdge: isSlidingFromLeft ? "right" : "left",
|
|
1803
|
+
direction: isSlidingFromLeft ? 1 : -1,
|
|
1804
|
+
size: "width",
|
|
1805
|
+
children: /* @__PURE__ */ jsx21(
|
|
1806
|
+
SliderImpl,
|
|
1807
|
+
{
|
|
1808
|
+
dir: direction,
|
|
1809
|
+
"data-orientation": "horizontal",
|
|
1810
|
+
...sliderProps,
|
|
1811
|
+
ref: composedRefs,
|
|
1812
|
+
style: {
|
|
1813
|
+
...sliderProps.style,
|
|
1814
|
+
["--radix-slider-thumb-transform"]: "translateX(-50%)"
|
|
1815
|
+
},
|
|
1816
|
+
onSlideStart: (event) => {
|
|
1817
|
+
const value = getValueFromPointer(event.clientX);
|
|
1818
|
+
onSlideStart?.(value);
|
|
1819
|
+
},
|
|
1820
|
+
onSlideMove: (event) => {
|
|
1821
|
+
const value = getValueFromPointer(event.clientX);
|
|
1822
|
+
onSlideMove?.(value);
|
|
1823
|
+
},
|
|
1824
|
+
onSlideEnd: () => {
|
|
1825
|
+
rectRef.current = void 0;
|
|
1826
|
+
onSlideEnd?.();
|
|
1827
|
+
},
|
|
1828
|
+
onStepKeyDown: (event) => {
|
|
1829
|
+
const slideDirection = isSlidingFromLeft ? "from-left" : "from-right";
|
|
1830
|
+
const isBackKey = BACK_KEYS[slideDirection].includes(event.key);
|
|
1831
|
+
onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
)
|
|
1835
|
+
}
|
|
1836
|
+
);
|
|
1837
|
+
}
|
|
1838
|
+
);
|
|
1839
|
+
var SliderVertical = React11.forwardRef(
|
|
1840
|
+
(props, forwardedRef) => {
|
|
1841
|
+
const {
|
|
1842
|
+
min,
|
|
1843
|
+
max,
|
|
1844
|
+
inverted,
|
|
1845
|
+
onSlideStart,
|
|
1846
|
+
onSlideMove,
|
|
1847
|
+
onSlideEnd,
|
|
1848
|
+
onStepKeyDown,
|
|
1849
|
+
...sliderProps
|
|
1850
|
+
} = props;
|
|
1851
|
+
const sliderRef = React11.useRef(null);
|
|
1852
|
+
const ref = useComposedRefs(forwardedRef, sliderRef);
|
|
1853
|
+
const rectRef = React11.useRef(void 0);
|
|
1854
|
+
const isSlidingFromBottom = !inverted;
|
|
1855
|
+
function getValueFromPointer(pointerPosition) {
|
|
1856
|
+
const rect = rectRef.current || sliderRef.current.getBoundingClientRect();
|
|
1857
|
+
const input = [0, rect.height];
|
|
1858
|
+
const output = isSlidingFromBottom ? [max, min] : [min, max];
|
|
1859
|
+
const value = linearScale(input, output);
|
|
1860
|
+
rectRef.current = rect;
|
|
1861
|
+
return value(pointerPosition - rect.top);
|
|
1862
|
+
}
|
|
1863
|
+
return /* @__PURE__ */ jsx21(
|
|
1864
|
+
SliderOrientationProvider,
|
|
1865
|
+
{
|
|
1866
|
+
scope: props.__scopeSlider,
|
|
1867
|
+
startEdge: isSlidingFromBottom ? "bottom" : "top",
|
|
1868
|
+
endEdge: isSlidingFromBottom ? "top" : "bottom",
|
|
1869
|
+
size: "height",
|
|
1870
|
+
direction: isSlidingFromBottom ? 1 : -1,
|
|
1871
|
+
children: /* @__PURE__ */ jsx21(
|
|
1872
|
+
SliderImpl,
|
|
1873
|
+
{
|
|
1874
|
+
"data-orientation": "vertical",
|
|
1875
|
+
...sliderProps,
|
|
1876
|
+
ref,
|
|
1877
|
+
style: {
|
|
1878
|
+
...sliderProps.style,
|
|
1879
|
+
["--radix-slider-thumb-transform"]: "translateY(50%)"
|
|
1880
|
+
},
|
|
1881
|
+
onSlideStart: (event) => {
|
|
1882
|
+
const value = getValueFromPointer(event.clientY);
|
|
1883
|
+
onSlideStart?.(value);
|
|
1884
|
+
},
|
|
1885
|
+
onSlideMove: (event) => {
|
|
1886
|
+
const value = getValueFromPointer(event.clientY);
|
|
1887
|
+
onSlideMove?.(value);
|
|
1888
|
+
},
|
|
1889
|
+
onSlideEnd: () => {
|
|
1890
|
+
rectRef.current = void 0;
|
|
1891
|
+
onSlideEnd?.();
|
|
1892
|
+
},
|
|
1893
|
+
onStepKeyDown: (event) => {
|
|
1894
|
+
const slideDirection = isSlidingFromBottom ? "from-bottom" : "from-top";
|
|
1895
|
+
const isBackKey = BACK_KEYS[slideDirection].includes(event.key);
|
|
1896
|
+
onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
)
|
|
1900
|
+
}
|
|
1901
|
+
);
|
|
1902
|
+
}
|
|
1903
|
+
);
|
|
1904
|
+
var SliderImpl = React11.forwardRef(
|
|
1905
|
+
(props, forwardedRef) => {
|
|
1906
|
+
const {
|
|
1907
|
+
__scopeSlider,
|
|
1908
|
+
onSlideStart,
|
|
1909
|
+
onSlideMove,
|
|
1910
|
+
onSlideEnd,
|
|
1911
|
+
onHomeKeyDown,
|
|
1912
|
+
onEndKeyDown,
|
|
1913
|
+
onStepKeyDown,
|
|
1914
|
+
...sliderProps
|
|
1915
|
+
} = props;
|
|
1916
|
+
const context = useSliderContext(SLIDER_NAME, __scopeSlider);
|
|
1917
|
+
return /* @__PURE__ */ jsx21(
|
|
1918
|
+
Primitive.span,
|
|
1919
|
+
{
|
|
1920
|
+
...sliderProps,
|
|
1921
|
+
ref: forwardedRef,
|
|
1922
|
+
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
1923
|
+
if (event.key === "Home") {
|
|
1924
|
+
onHomeKeyDown(event);
|
|
1925
|
+
event.preventDefault();
|
|
1926
|
+
} else if (event.key === "End") {
|
|
1927
|
+
onEndKeyDown(event);
|
|
1928
|
+
event.preventDefault();
|
|
1929
|
+
} else if (PAGE_KEYS.concat(ARROW_KEYS).includes(event.key)) {
|
|
1930
|
+
onStepKeyDown(event);
|
|
1931
|
+
event.preventDefault();
|
|
1932
|
+
}
|
|
1933
|
+
}),
|
|
1934
|
+
onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {
|
|
1935
|
+
const target = event.target;
|
|
1936
|
+
target.setPointerCapture(event.pointerId);
|
|
1937
|
+
event.preventDefault();
|
|
1938
|
+
if (context.thumbs.has(target)) {
|
|
1939
|
+
target.focus();
|
|
1940
|
+
} else {
|
|
1941
|
+
onSlideStart(event);
|
|
1942
|
+
}
|
|
1943
|
+
}),
|
|
1944
|
+
onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {
|
|
1945
|
+
const target = event.target;
|
|
1946
|
+
if (target.hasPointerCapture(event.pointerId)) onSlideMove(event);
|
|
1947
|
+
}),
|
|
1948
|
+
onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {
|
|
1949
|
+
const target = event.target;
|
|
1950
|
+
if (target.hasPointerCapture(event.pointerId)) {
|
|
1951
|
+
target.releasePointerCapture(event.pointerId);
|
|
1952
|
+
onSlideEnd(event);
|
|
1953
|
+
}
|
|
1954
|
+
})
|
|
1955
|
+
}
|
|
1956
|
+
);
|
|
1957
|
+
}
|
|
1958
|
+
);
|
|
1959
|
+
var TRACK_NAME = "SliderTrack";
|
|
1960
|
+
var SliderTrack = React11.forwardRef(
|
|
1961
|
+
(props, forwardedRef) => {
|
|
1962
|
+
const { __scopeSlider, ...trackProps } = props;
|
|
1963
|
+
const context = useSliderContext(TRACK_NAME, __scopeSlider);
|
|
1964
|
+
return /* @__PURE__ */ jsx21(
|
|
1965
|
+
Primitive.span,
|
|
1966
|
+
{
|
|
1967
|
+
"data-disabled": context.disabled ? "" : void 0,
|
|
1968
|
+
"data-orientation": context.orientation,
|
|
1969
|
+
...trackProps,
|
|
1970
|
+
ref: forwardedRef
|
|
1971
|
+
}
|
|
1972
|
+
);
|
|
1973
|
+
}
|
|
1974
|
+
);
|
|
1975
|
+
SliderTrack.displayName = TRACK_NAME;
|
|
1976
|
+
var RANGE_NAME = "SliderRange";
|
|
1977
|
+
var SliderRange = React11.forwardRef(
|
|
1978
|
+
(props, forwardedRef) => {
|
|
1979
|
+
const { __scopeSlider, ...rangeProps } = props;
|
|
1980
|
+
const context = useSliderContext(RANGE_NAME, __scopeSlider);
|
|
1981
|
+
const orientation = useSliderOrientationContext(RANGE_NAME, __scopeSlider);
|
|
1982
|
+
const ref = React11.useRef(null);
|
|
1983
|
+
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
1984
|
+
const valuesCount = context.values.length;
|
|
1985
|
+
const percentages = context.values.map(
|
|
1986
|
+
(value) => convertValueToPercentage(value, context.min, context.max)
|
|
1987
|
+
);
|
|
1988
|
+
const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0;
|
|
1989
|
+
const offsetEnd = 100 - Math.max(...percentages);
|
|
1990
|
+
return /* @__PURE__ */ jsx21(
|
|
1991
|
+
Primitive.span,
|
|
1992
|
+
{
|
|
1993
|
+
"data-orientation": context.orientation,
|
|
1994
|
+
"data-disabled": context.disabled ? "" : void 0,
|
|
1995
|
+
...rangeProps,
|
|
1996
|
+
ref: composedRefs,
|
|
1997
|
+
style: {
|
|
1998
|
+
...props.style,
|
|
1999
|
+
[orientation.startEdge]: offsetStart + "%",
|
|
2000
|
+
[orientation.endEdge]: offsetEnd + "%"
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
);
|
|
2004
|
+
}
|
|
2005
|
+
);
|
|
2006
|
+
SliderRange.displayName = RANGE_NAME;
|
|
2007
|
+
var THUMB_NAME = "SliderThumb";
|
|
2008
|
+
var SliderThumb = React11.forwardRef(
|
|
2009
|
+
(props, forwardedRef) => {
|
|
2010
|
+
const getItems = useCollection(props.__scopeSlider);
|
|
2011
|
+
const [thumb, setThumb] = React11.useState(null);
|
|
2012
|
+
const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));
|
|
2013
|
+
const index = React11.useMemo(
|
|
2014
|
+
() => thumb ? getItems().findIndex((item) => item.ref.current === thumb) : -1,
|
|
2015
|
+
[getItems, thumb]
|
|
2016
|
+
);
|
|
2017
|
+
return /* @__PURE__ */ jsx21(SliderThumbImpl, { ...props, ref: composedRefs, index });
|
|
2018
|
+
}
|
|
2019
|
+
);
|
|
2020
|
+
var SliderThumbImpl = React11.forwardRef(
|
|
2021
|
+
(props, forwardedRef) => {
|
|
2022
|
+
const { __scopeSlider, index, name, ...thumbProps } = props;
|
|
2023
|
+
const context = useSliderContext(THUMB_NAME, __scopeSlider);
|
|
2024
|
+
const orientation = useSliderOrientationContext(THUMB_NAME, __scopeSlider);
|
|
2025
|
+
const [thumb, setThumb] = React11.useState(null);
|
|
2026
|
+
const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));
|
|
2027
|
+
const isFormControl = thumb ? context.form || !!thumb.closest("form") : true;
|
|
2028
|
+
const size = useSize(thumb);
|
|
2029
|
+
const value = context.values[index];
|
|
2030
|
+
const percent = value === void 0 ? 0 : convertValueToPercentage(value, context.min, context.max);
|
|
2031
|
+
const label = getLabel(index, context.values.length);
|
|
2032
|
+
const orientationSize = size?.[orientation.size];
|
|
2033
|
+
const thumbInBoundsOffset = orientationSize ? getThumbInBoundsOffset(orientationSize, percent, orientation.direction) : 0;
|
|
2034
|
+
React11.useEffect(() => {
|
|
2035
|
+
if (thumb) {
|
|
2036
|
+
context.thumbs.add(thumb);
|
|
2037
|
+
return () => {
|
|
2038
|
+
context.thumbs.delete(thumb);
|
|
2039
|
+
};
|
|
2040
|
+
}
|
|
2041
|
+
}, [thumb, context.thumbs]);
|
|
2042
|
+
return /* @__PURE__ */ jsxs10(
|
|
2043
|
+
"span",
|
|
2044
|
+
{
|
|
2045
|
+
style: {
|
|
2046
|
+
transform: "var(--radix-slider-thumb-transform)",
|
|
2047
|
+
position: "absolute",
|
|
2048
|
+
[orientation.startEdge]: `calc(${percent}% + ${thumbInBoundsOffset}px)`
|
|
2049
|
+
},
|
|
2050
|
+
children: [
|
|
2051
|
+
/* @__PURE__ */ jsx21(Collection.ItemSlot, { scope: props.__scopeSlider, children: /* @__PURE__ */ jsx21(
|
|
2052
|
+
Primitive.span,
|
|
2053
|
+
{
|
|
2054
|
+
role: "slider",
|
|
2055
|
+
"aria-label": props["aria-label"] || label,
|
|
2056
|
+
"aria-valuemin": context.min,
|
|
2057
|
+
"aria-valuenow": value,
|
|
2058
|
+
"aria-valuemax": context.max,
|
|
2059
|
+
"aria-orientation": context.orientation,
|
|
2060
|
+
"data-orientation": context.orientation,
|
|
2061
|
+
"data-disabled": context.disabled ? "" : void 0,
|
|
2062
|
+
tabIndex: context.disabled ? void 0 : 0,
|
|
2063
|
+
...thumbProps,
|
|
2064
|
+
ref: composedRefs,
|
|
2065
|
+
style: value === void 0 ? { display: "none" } : props.style,
|
|
2066
|
+
onFocus: composeEventHandlers(props.onFocus, () => {
|
|
2067
|
+
context.valueIndexToChangeRef.current = index;
|
|
2068
|
+
})
|
|
2069
|
+
}
|
|
2070
|
+
) }),
|
|
2071
|
+
isFormControl && /* @__PURE__ */ jsx21(
|
|
2072
|
+
SliderBubbleInput,
|
|
2073
|
+
{
|
|
2074
|
+
name: name ?? (context.name ? context.name + (context.values.length > 1 ? "[]" : "") : void 0),
|
|
2075
|
+
form: context.form,
|
|
2076
|
+
value
|
|
2077
|
+
},
|
|
2078
|
+
index
|
|
2079
|
+
)
|
|
2080
|
+
]
|
|
2081
|
+
}
|
|
2082
|
+
);
|
|
2083
|
+
}
|
|
2084
|
+
);
|
|
2085
|
+
SliderThumb.displayName = THUMB_NAME;
|
|
2086
|
+
var BUBBLE_INPUT_NAME = "RadioBubbleInput";
|
|
2087
|
+
var SliderBubbleInput = React11.forwardRef(
|
|
2088
|
+
({ __scopeSlider, value, ...props }, forwardedRef) => {
|
|
2089
|
+
const ref = React11.useRef(null);
|
|
2090
|
+
const composedRefs = useComposedRefs(ref, forwardedRef);
|
|
2091
|
+
const prevValue = usePrevious(value);
|
|
2092
|
+
React11.useEffect(() => {
|
|
2093
|
+
const input = ref.current;
|
|
2094
|
+
if (!input) return;
|
|
2095
|
+
const inputProto = window.HTMLInputElement.prototype;
|
|
2096
|
+
const descriptor = Object.getOwnPropertyDescriptor(inputProto, "value");
|
|
2097
|
+
const setValue = descriptor.set;
|
|
2098
|
+
if (prevValue !== value && setValue) {
|
|
2099
|
+
const event = new Event("input", { bubbles: true });
|
|
2100
|
+
setValue.call(input, value);
|
|
2101
|
+
input.dispatchEvent(event);
|
|
2102
|
+
}
|
|
2103
|
+
}, [prevValue, value]);
|
|
2104
|
+
return /* @__PURE__ */ jsx21(
|
|
2105
|
+
Primitive.input,
|
|
2106
|
+
{
|
|
2107
|
+
style: { display: "none" },
|
|
2108
|
+
...props,
|
|
2109
|
+
ref: composedRefs,
|
|
2110
|
+
defaultValue: value
|
|
2111
|
+
}
|
|
2112
|
+
);
|
|
2113
|
+
}
|
|
2114
|
+
);
|
|
2115
|
+
SliderBubbleInput.displayName = BUBBLE_INPUT_NAME;
|
|
2116
|
+
function getNextSortedValues(prevValues = [], nextValue, atIndex) {
|
|
2117
|
+
const nextValues = [...prevValues];
|
|
2118
|
+
nextValues[atIndex] = nextValue;
|
|
2119
|
+
return nextValues.sort((a, b) => a - b);
|
|
2120
|
+
}
|
|
2121
|
+
function convertValueToPercentage(value, min, max) {
|
|
2122
|
+
const maxSteps = max - min;
|
|
2123
|
+
const percentPerStep = 100 / maxSteps;
|
|
2124
|
+
const percentage = percentPerStep * (value - min);
|
|
2125
|
+
return clamp(percentage, [0, 100]);
|
|
2126
|
+
}
|
|
2127
|
+
function getLabel(index, totalValues) {
|
|
2128
|
+
if (totalValues > 2) {
|
|
2129
|
+
return `Value ${index + 1} of ${totalValues}`;
|
|
2130
|
+
} else if (totalValues === 2) {
|
|
2131
|
+
return ["Minimum", "Maximum"][index];
|
|
2132
|
+
} else {
|
|
2133
|
+
return void 0;
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
2136
|
+
function getClosestValueIndex(values, nextValue) {
|
|
2137
|
+
if (values.length === 1) return 0;
|
|
2138
|
+
const distances = values.map((value) => Math.abs(value - nextValue));
|
|
2139
|
+
const closestDistance = Math.min(...distances);
|
|
2140
|
+
return distances.indexOf(closestDistance);
|
|
2141
|
+
}
|
|
2142
|
+
function getThumbInBoundsOffset(width, left, direction) {
|
|
2143
|
+
const halfWidth = width / 2;
|
|
2144
|
+
const halfPercent = 50;
|
|
2145
|
+
const offset = linearScale([0, halfPercent], [0, halfWidth]);
|
|
2146
|
+
return (halfWidth - offset(left) * direction) * direction;
|
|
2147
|
+
}
|
|
2148
|
+
function getStepsBetweenValues(values) {
|
|
2149
|
+
return values.slice(0, -1).map((value, index) => values[index + 1] - value);
|
|
2150
|
+
}
|
|
2151
|
+
function hasMinStepsBetweenValues(values, minStepsBetweenValues) {
|
|
2152
|
+
if (minStepsBetweenValues > 0) {
|
|
2153
|
+
const stepsBetweenValues = getStepsBetweenValues(values);
|
|
2154
|
+
const actualMinStepsBetweenValues = Math.min(...stepsBetweenValues);
|
|
2155
|
+
return actualMinStepsBetweenValues >= minStepsBetweenValues;
|
|
2156
|
+
}
|
|
2157
|
+
return true;
|
|
2158
|
+
}
|
|
2159
|
+
function linearScale(input, output) {
|
|
2160
|
+
return (value) => {
|
|
2161
|
+
if (input[0] === input[1] || output[0] === output[1]) return output[0];
|
|
2162
|
+
const ratio = (output[1] - output[0]) / (input[1] - input[0]);
|
|
2163
|
+
return output[0] + ratio * (value - input[0]);
|
|
2164
|
+
};
|
|
2165
|
+
}
|
|
2166
|
+
function getDecimalCount(value) {
|
|
2167
|
+
return (String(value).split(".")[1] || "").length;
|
|
2168
|
+
}
|
|
2169
|
+
function roundValue(value, decimalCount) {
|
|
2170
|
+
const rounder = Math.pow(10, decimalCount);
|
|
2171
|
+
return Math.round(value * rounder) / rounder;
|
|
2172
|
+
}
|
|
2173
|
+
var Root5 = Slider;
|
|
2174
|
+
var Track = SliderTrack;
|
|
2175
|
+
var Range = SliderRange;
|
|
2176
|
+
var Thumb2 = SliderThumb;
|
|
2177
|
+
|
|
2178
|
+
// ../ui/src/lib/utils.ts
|
|
2179
|
+
import { clsx as clsx2 } from "clsx";
|
|
2180
|
+
import { twMerge as twMerge2 } from "tailwind-merge";
|
|
2181
|
+
function cn2(...inputs) {
|
|
2182
|
+
return twMerge2(clsx2(inputs));
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
// src/ui/slider.tsx
|
|
2186
|
+
import { jsx as jsx23, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2187
|
+
function Slider2({
|
|
2188
|
+
className,
|
|
2189
|
+
defaultValue,
|
|
2190
|
+
value,
|
|
2191
|
+
min = 0,
|
|
2192
|
+
max = 100,
|
|
2193
|
+
...props
|
|
2194
|
+
}) {
|
|
2195
|
+
const _values = React12.useMemo(
|
|
2196
|
+
() => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
|
|
2197
|
+
[value, defaultValue, min, max]
|
|
2198
|
+
);
|
|
2199
|
+
return /* @__PURE__ */ jsxs11(
|
|
2200
|
+
Root5,
|
|
2201
|
+
{
|
|
2202
|
+
"data-slot": "slider",
|
|
2203
|
+
defaultValue,
|
|
2204
|
+
value,
|
|
2205
|
+
min,
|
|
2206
|
+
max,
|
|
2207
|
+
className: cn2(
|
|
2208
|
+
"relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
|
|
2209
|
+
className
|
|
2210
|
+
),
|
|
2211
|
+
...props,
|
|
2212
|
+
children: [
|
|
2213
|
+
/* @__PURE__ */ jsx23(
|
|
2214
|
+
Track,
|
|
2215
|
+
{
|
|
2216
|
+
"data-slot": "slider-track",
|
|
2217
|
+
className: cn2(
|
|
2218
|
+
"bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5"
|
|
2219
|
+
),
|
|
2220
|
+
children: /* @__PURE__ */ jsx23(
|
|
2221
|
+
Range,
|
|
2222
|
+
{
|
|
2223
|
+
"data-slot": "slider-range",
|
|
2224
|
+
className: cn2("bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full")
|
|
2225
|
+
}
|
|
2226
|
+
)
|
|
2227
|
+
}
|
|
2228
|
+
),
|
|
2229
|
+
Array.from({ length: _values.length }, (_, index) => /* @__PURE__ */ jsx23(
|
|
2230
|
+
Thumb2,
|
|
2231
|
+
{
|
|
2232
|
+
"data-slot": "slider-thumb",
|
|
2233
|
+
className: "border-primary bg-background ring-ring/50 block size-4 shrink-0 rounded-full border shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
|
|
2234
|
+
},
|
|
2235
|
+
index
|
|
2236
|
+
))
|
|
2237
|
+
]
|
|
2238
|
+
}
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
2241
|
+
|
|
2242
|
+
// src/components/CreditCardTab/Points/PointsSelector.tsx
|
|
2243
|
+
import { jsx as jsx24, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2244
|
+
var PointsSelector = (props) => {
|
|
2245
|
+
const { isSelected, onSelect, children } = props;
|
|
2246
|
+
const { balance } = useSlapiBalance();
|
|
2247
|
+
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
2248
|
+
const { appProps, staticConfig } = useStaticConfig();
|
|
2249
|
+
const min = 0;
|
|
2250
|
+
const max = Math.min((appProps.amount ?? 0) * staticConfig.pointsConversionRatio, balance?.availablePoints ?? 0);
|
|
2251
|
+
const step = 10;
|
|
2252
|
+
const [splitTokens, setSplitTokens] = useState8(0);
|
|
2253
|
+
const splitAmount = getSplitAmount(appProps.amount ?? 0, splitTokens, staticConfig.pointsConversionRatio);
|
|
2254
|
+
const handleCommit = (value) => {
|
|
2255
|
+
setSelectedPaymentMethod({ ...selectedPaymentMethod, splitAmount: value });
|
|
2256
|
+
};
|
|
2257
|
+
return /* @__PURE__ */ jsxs12(
|
|
2258
|
+
"button",
|
|
2259
|
+
{
|
|
2260
|
+
onClick: onSelect,
|
|
2261
|
+
className: cn("bg-primary/8 cursor-pointer overflow-hidden rounded-md border-1 border-transparent", {
|
|
2262
|
+
"border-primary": isSelected
|
|
2263
|
+
}),
|
|
2264
|
+
children: [
|
|
2265
|
+
/* @__PURE__ */ jsxs12("div", { className: cn("flex h-11 w-full", { "bg-black/4": isSelected }), children: [
|
|
2266
|
+
/* @__PURE__ */ jsx24(
|
|
2267
|
+
"div",
|
|
2268
|
+
{
|
|
2269
|
+
className: cn("flex h-full w-11 items-center justify-center bg-black/10", {
|
|
2270
|
+
"bg-primary": isSelected
|
|
2271
|
+
}),
|
|
2272
|
+
children: /* @__PURE__ */ jsx24("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white", children: isSelected && /* @__PURE__ */ jsx24("div", { className: "bg-primary h-2.5 w-2.5 rounded-full" }) })
|
|
2273
|
+
}
|
|
2274
|
+
),
|
|
2275
|
+
/* @__PURE__ */ jsx24("div", { className: "flex h-full w-full items-center justify-between gap-3 px-3", children })
|
|
2276
|
+
] }),
|
|
2277
|
+
isSelected && /* @__PURE__ */ jsx24("div", { className: "px-3 pt-6 pb-2 md:px-4", children: /* @__PURE__ */ jsxs12("div", { className: "flex justify-between gap-3", children: [
|
|
2278
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex max-w-[100px] flex-col gap-1", children: [
|
|
2279
|
+
/* @__PURE__ */ jsx24(Input, { readOnly: true, value: splitTokens, className: "bg-white text-center font-medium" }),
|
|
2280
|
+
/* @__PURE__ */ jsx24("p", { className: "text-left text-xs leading-[20px] text-black/45", children: "Points" })
|
|
2281
|
+
] }),
|
|
2282
|
+
/* @__PURE__ */ jsx24("div", { className: "flex w-full items-center pb-6", children: /* @__PURE__ */ jsx24(
|
|
2283
|
+
Slider2,
|
|
2284
|
+
{
|
|
2285
|
+
value: [splitTokens],
|
|
2286
|
+
onValueCommit: ([v]) => handleCommit(v),
|
|
2287
|
+
onValueChange: ([v]) => setSplitTokens(v),
|
|
2288
|
+
min,
|
|
2289
|
+
max,
|
|
2290
|
+
step
|
|
2291
|
+
}
|
|
2292
|
+
) }),
|
|
2293
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex max-w-[100px] flex-col gap-1", children: [
|
|
2294
|
+
/* @__PURE__ */ jsx24(
|
|
2295
|
+
Input,
|
|
2296
|
+
{
|
|
2297
|
+
readOnly: true,
|
|
2298
|
+
value: formatUSD(splitAmount + getTransactionFee(splitAmount, appProps.transactionFeePercentage)),
|
|
2299
|
+
className: "bg-white text-center font-medium"
|
|
2300
|
+
}
|
|
2301
|
+
),
|
|
2302
|
+
/* @__PURE__ */ jsx24("p", { className: "text-left text-xs leading-[20px] text-black/45", children: "Card" })
|
|
2303
|
+
] })
|
|
2304
|
+
] }) })
|
|
2305
|
+
]
|
|
2306
|
+
}
|
|
2307
|
+
);
|
|
2308
|
+
};
|
|
2309
|
+
|
|
2310
|
+
// src/components/CreditCardTab/Points/SplitBlock.tsx
|
|
2311
|
+
import { jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2312
|
+
var SplitBlock = (props) => {
|
|
2313
|
+
const { isSelected, onSelect } = props;
|
|
2314
|
+
const { balance, isBalanceLoading } = useSlapiBalance();
|
|
2315
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
2316
|
+
const [address, setAddress] = useState9(null);
|
|
2317
|
+
const { staticConfig } = useStaticConfig();
|
|
2318
|
+
const { pointsConversionRatio, pointsTitle } = staticConfig;
|
|
2319
|
+
const initWallet = useCallback4(async (pointsChain) => {
|
|
2320
|
+
if (!pointsChain) {
|
|
2321
|
+
return;
|
|
2322
|
+
}
|
|
2323
|
+
try {
|
|
2324
|
+
const res = await getAirWallet({
|
|
2325
|
+
mocaChain: pointsChain.mocaChain,
|
|
2326
|
+
partnerId: pointsChain.partnerId
|
|
2327
|
+
});
|
|
2328
|
+
setAddress(res.address ?? null);
|
|
2329
|
+
} catch (e) {
|
|
2330
|
+
console.error("Air Wallet init failed:", e);
|
|
2331
|
+
}
|
|
2332
|
+
}, []);
|
|
2333
|
+
useEffect6(() => {
|
|
2334
|
+
initWallet(spreePayConfig?.pointsChain);
|
|
2335
|
+
}, [spreePayConfig, initWallet]);
|
|
2336
|
+
return /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ jsxs13(PointsSelector, { onSelect: () => onSelect("air"), isSelected, children: [
|
|
2337
|
+
/* @__PURE__ */ jsx25("div", { className: "flex items-center gap-2", children: balance?.availablePoints ? /* @__PURE__ */ jsxs13("p", { className: "text-sm font-medium text-black", children: [
|
|
2338
|
+
/* @__PURE__ */ jsx25("span", { className: "text-black/50", children: "Available" }),
|
|
2339
|
+
" ",
|
|
2340
|
+
formatPoints(balance.availablePoints, pointsTitle),
|
|
2341
|
+
" ",
|
|
2342
|
+
/* @__PURE__ */ jsx25("span", { className: "text-black/50", children: formatUSD(balance.availablePoints / pointsConversionRatio) })
|
|
2343
|
+
] }) : null }),
|
|
2344
|
+
isBalanceLoading ? /* @__PURE__ */ jsx25("div", { className: "h-4 w-6 animate-pulse bg-gray-200" }) : !balance?.availablePoints && /* @__PURE__ */ jsx25("p", { className: "text-sm font-medium text-black", children: "No points available" }),
|
|
2345
|
+
address && /* @__PURE__ */ jsx25("div", { className: "text-sm font-medium text-black", children: address.length > 8 ? `${address.slice(0, 4)}...${address.slice(-4)}` : address })
|
|
2346
|
+
] }) });
|
|
2347
|
+
};
|
|
2348
|
+
|
|
2349
|
+
// src/components/CreditCardTab/Points/Points.tsx
|
|
2350
|
+
import { Fragment as Fragment3, jsx as jsx26, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2351
|
+
var Points = () => {
|
|
2352
|
+
const [usePoints, setUsePoints] = useState10(false);
|
|
2353
|
+
const [selectedPointsType, setSelectedPointsType] = useState10(null);
|
|
2354
|
+
const { setSelectedPaymentMethod, selectedPaymentMethod } = useSpreePaymentMethod();
|
|
2355
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
2356
|
+
const handleTogglePoints = (enabled) => {
|
|
2357
|
+
setUsePoints(enabled);
|
|
2358
|
+
if (!enabled) {
|
|
2359
|
+
setSelectedPointsType(null);
|
|
2360
|
+
setSelectedPaymentMethod({ ...selectedPaymentMethod, splitAmount: void 0 });
|
|
2361
|
+
}
|
|
2362
|
+
};
|
|
2363
|
+
return /* @__PURE__ */ jsxs14(Fragment3, { children: [
|
|
2364
|
+
/* @__PURE__ */ jsx26(PointsSwitch, { disabled: !spreePayConfig?.creditCard.enabled, value: usePoints, onChange: handleTogglePoints }),
|
|
2365
|
+
usePoints && /* @__PURE__ */ jsx26(SplitBlock, { isSelected: selectedPointsType === "air", onSelect: setSelectedPointsType })
|
|
2366
|
+
] });
|
|
2367
|
+
};
|
|
2368
|
+
|
|
2369
|
+
// src/components/CreditCardTab/CreditCardTab.tsx
|
|
2370
|
+
import { jsx as jsx27, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2371
|
+
var CreditCardTab = () => {
|
|
2372
|
+
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
2373
|
+
const { register } = useSpreePayRegister();
|
|
2374
|
+
const { mutateCards } = useCards();
|
|
2375
|
+
const { cardPayment } = useCardPayment();
|
|
2376
|
+
const { splitPayment } = useSplitCardPayments();
|
|
2377
|
+
const handlePay = useCallback5(
|
|
2378
|
+
async (data) => {
|
|
2379
|
+
try {
|
|
2380
|
+
if (selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && selectedPaymentMethod.method) {
|
|
2381
|
+
let res = null;
|
|
2382
|
+
if (selectedPaymentMethod.splitAmount && selectedPaymentMethod.splitAmount > 0) {
|
|
2383
|
+
res = await splitPayment({ ...data, points: selectedPaymentMethod.splitAmount });
|
|
2384
|
+
} else {
|
|
2385
|
+
res = await cardPayment(data);
|
|
2386
|
+
}
|
|
2387
|
+
if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(res.status)) {
|
|
2388
|
+
return Promise.resolve(res);
|
|
2389
|
+
}
|
|
2390
|
+
return Promise.reject(new PaymentError("Card payment failed", res.status));
|
|
997
2391
|
}
|
|
998
2392
|
return Promise.reject(new PaymentError("Unsupported payment method", "FAILED" /* FAILED */));
|
|
999
2393
|
} catch (_) {
|
|
1000
2394
|
return Promise.reject(new PaymentError("Payment failed", "FAILED" /* FAILED */));
|
|
1001
2395
|
} finally {
|
|
1002
|
-
setSelectedPaymentMethod({ type: "CREDIT_CARD" /* CREDIT_CARD */, method: null });
|
|
2396
|
+
setSelectedPaymentMethod({ ...selectedPaymentMethod, type: "CREDIT_CARD" /* CREDIT_CARD */, method: null });
|
|
1003
2397
|
mutateCards();
|
|
1004
2398
|
}
|
|
1005
2399
|
},
|
|
1006
|
-
[
|
|
2400
|
+
[mutateCards, selectedPaymentMethod, setSelectedPaymentMethod, cardPayment, splitPayment]
|
|
1007
2401
|
);
|
|
1008
|
-
|
|
2402
|
+
useEffect7(() => {
|
|
1009
2403
|
register(handlePay);
|
|
1010
2404
|
}, [register, handlePay]);
|
|
1011
|
-
return /* @__PURE__ */
|
|
1012
|
-
/* @__PURE__ */
|
|
1013
|
-
/* @__PURE__ */
|
|
1014
|
-
/* @__PURE__ */ jsx15(
|
|
1015
|
-
PointsSwitch,
|
|
1016
|
-
{
|
|
1017
|
-
disabled: true,
|
|
1018
|
-
value: usePoints,
|
|
1019
|
-
onChange: setUsePoints,
|
|
1020
|
-
pointsTitle,
|
|
1021
|
-
pointsConversionRatio
|
|
1022
|
-
}
|
|
1023
|
-
),
|
|
1024
|
-
usePoints && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-1", children: [
|
|
1025
|
-
/* @__PURE__ */ jsxs10(PointsSelector, { onSelect: () => setSelectedPointsType("slapi"), isSelected: selectedPointsType === "slapi", children: [
|
|
1026
|
-
/* @__PURE__ */ jsx15("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx15("p", { className: "text-sm font-medium text-black", children: "from [Brand] Balance" }) }),
|
|
1027
|
-
isBalanceLoading ? /* @__PURE__ */ jsx15("div", { className: "h-4 w-6 animate-pulse bg-gray-200" }) : !balance?.availablePoints && /* @__PURE__ */ jsx15("p", { className: "text-sm font-medium text-black", children: "No points available" }),
|
|
1028
|
-
balance?.availablePoints ? /* @__PURE__ */ jsxs10("p", { className: "text-sm font-medium text-black", children: [
|
|
1029
|
-
formatPoints(balance.availablePoints, pointsTitle),
|
|
1030
|
-
" ",
|
|
1031
|
-
/* @__PURE__ */ jsx15("span", { className: "text-black/50", children: formatUSD(balance.availablePoints / pointsConversionRatio) })
|
|
1032
|
-
] }) : null
|
|
1033
|
-
] }),
|
|
1034
|
-
/* @__PURE__ */ jsxs10(
|
|
1035
|
-
PointsSelector,
|
|
1036
|
-
{
|
|
1037
|
-
onSelect: () => setSelectedPointsType("wallet"),
|
|
1038
|
-
isSelected: selectedPointsType === "wallet",
|
|
1039
|
-
children: [
|
|
1040
|
-
/* @__PURE__ */ jsx15("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx15("p", { className: "text-sm font-medium text-black", children: "from Crypto Wallet" }) }),
|
|
1041
|
-
/* @__PURE__ */ jsx15("button", { className: "hover:bg-primary -mr-2 h-[34px] rounded-sm border-1 border-black px-3 text-sm font-medium hover:text-white", children: "Connect a Wallet" })
|
|
1042
|
-
]
|
|
1043
|
-
}
|
|
1044
|
-
)
|
|
1045
|
-
] })
|
|
1046
|
-
] })
|
|
2405
|
+
return /* @__PURE__ */ jsxs15("div", { children: [
|
|
2406
|
+
/* @__PURE__ */ jsx27("div", { className: "border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsx27(CreditCard, {}) }),
|
|
2407
|
+
/* @__PURE__ */ jsx27("div", { className: "flex flex-col gap-6 px-5 pt-5 pb-5 md:px-7 md:pt-6 md:pb-7", children: /* @__PURE__ */ jsx27(Points, {}) })
|
|
1047
2408
|
] });
|
|
1048
2409
|
};
|
|
1049
2410
|
|
|
1050
2411
|
// src/components/CryptoTab/Crypto/CryptoWrapper.tsx
|
|
1051
2412
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
1052
|
-
import
|
|
2413
|
+
import NiceModal6 from "@ebay/nice-modal-react";
|
|
1053
2414
|
import { RainbowKitProvider, connectorsForWallets } from "@rainbow-me/rainbowkit";
|
|
1054
2415
|
import "@rainbow-me/rainbowkit/styles.css";
|
|
1055
2416
|
import { injectedWallet, walletConnectWallet } from "@rainbow-me/rainbowkit/wallets";
|
|
@@ -1057,7 +2418,7 @@ import { WagmiProvider, createConfig, http as http2 } from "wagmi";
|
|
|
1057
2418
|
import { base } from "wagmi/chains";
|
|
1058
2419
|
|
|
1059
2420
|
// src/components/CryptoTab/Crypto/Crypto.tsx
|
|
1060
|
-
import { useCallback as
|
|
2421
|
+
import { useCallback as useCallback6, useEffect as useEffect9 } from "react";
|
|
1061
2422
|
import { useAccount as useAccount3 } from "wagmi";
|
|
1062
2423
|
|
|
1063
2424
|
// ../../node_modules/@wagmi/core/dist/esm/utils/getAction.js
|
|
@@ -1109,11 +2470,11 @@ async function waitForTransactionReceipt(config2, parameters) {
|
|
|
1109
2470
|
}
|
|
1110
2471
|
|
|
1111
2472
|
// ../../node_modules/@wagmi/core/dist/esm/exports/index.js
|
|
1112
|
-
import { custom, http, webSocket } from "viem";
|
|
2473
|
+
import { custom as custom2, http, webSocket } from "viem";
|
|
1113
2474
|
|
|
1114
2475
|
// src/hooks/useCryptoPayment.ts
|
|
1115
|
-
import { erc20Abi } from "viem";
|
|
1116
|
-
import { useConfig
|
|
2476
|
+
import { erc20Abi as erc20Abi2 } from "viem";
|
|
2477
|
+
import { useConfig, useWalletClient } from "wagmi";
|
|
1117
2478
|
|
|
1118
2479
|
// src/config/baseTokens.ts
|
|
1119
2480
|
var BASE_CHAIN_ID = 8453;
|
|
@@ -1157,7 +2518,7 @@ var MAX_UINT256 = BigInt(2) ** BigInt(256) - BigInt(1);
|
|
|
1157
2518
|
var ONE_INCH_AGGREGATION_ROUTER_V6 = "0x111111125421ca6dc452d289314280a0f8842a65";
|
|
1158
2519
|
var useCryptoPayment = () => {
|
|
1159
2520
|
const { data: walletClient } = useWalletClient();
|
|
1160
|
-
const config2 =
|
|
2521
|
+
const config2 = useConfig();
|
|
1161
2522
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
1162
2523
|
const cryptoPayment = async (params) => {
|
|
1163
2524
|
if (!walletClient) {
|
|
@@ -1175,14 +2536,14 @@ var useCryptoPayment = () => {
|
|
|
1175
2536
|
}
|
|
1176
2537
|
const allowance = await readContract(config2, {
|
|
1177
2538
|
address: tokenAddress,
|
|
1178
|
-
abi:
|
|
2539
|
+
abi: erc20Abi2,
|
|
1179
2540
|
functionName: "allowance",
|
|
1180
2541
|
args: [walletClient.account.address, ONE_INCH_AGGREGATION_ROUTER_V6]
|
|
1181
2542
|
});
|
|
1182
2543
|
if (allowance <= 0n) {
|
|
1183
2544
|
const result = await walletClient.writeContract({
|
|
1184
2545
|
address: tokenAddress,
|
|
1185
|
-
abi:
|
|
2546
|
+
abi: erc20Abi2,
|
|
1186
2547
|
functionName: "approve",
|
|
1187
2548
|
args: [ONE_INCH_AGGREGATION_ROUTER_V6, MAX_UINT256]
|
|
1188
2549
|
});
|
|
@@ -1226,13 +2587,13 @@ var useCryptoPayment = () => {
|
|
|
1226
2587
|
|
|
1227
2588
|
// src/components/CryptoTab/Crypto/ConnectButton.tsx
|
|
1228
2589
|
import { ConnectButton as RainbowButton } from "@rainbow-me/rainbowkit";
|
|
1229
|
-
import { Fragment as
|
|
2590
|
+
import { Fragment as Fragment4, jsx as jsx28, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1230
2591
|
var ConnectButton = () => {
|
|
1231
|
-
return /* @__PURE__ */
|
|
2592
|
+
return /* @__PURE__ */ jsx28(RainbowButton.Custom, { children: ({ mounted, chain, account, openAccountModal, openChainModal, openConnectModal }) => {
|
|
1232
2593
|
if (!mounted) return null;
|
|
1233
|
-
return /* @__PURE__ */
|
|
2594
|
+
return /* @__PURE__ */ jsx28(Fragment4, { children: (() => {
|
|
1234
2595
|
if (!mounted || !account || !chain) {
|
|
1235
|
-
return /* @__PURE__ */
|
|
2596
|
+
return /* @__PURE__ */ jsx28(
|
|
1236
2597
|
"button",
|
|
1237
2598
|
{
|
|
1238
2599
|
className: "h-[34px] rounded-md border-1 border-black px-3 text-sm font-medium text-black",
|
|
@@ -1242,7 +2603,7 @@ var ConnectButton = () => {
|
|
|
1242
2603
|
);
|
|
1243
2604
|
}
|
|
1244
2605
|
if (chain.unsupported) {
|
|
1245
|
-
return /* @__PURE__ */
|
|
2606
|
+
return /* @__PURE__ */ jsx28(
|
|
1246
2607
|
"button",
|
|
1247
2608
|
{
|
|
1248
2609
|
className: "h-[34px] rounded-md border-1 border-black px-3 text-sm font-medium text-red-500",
|
|
@@ -1251,13 +2612,13 @@ var ConnectButton = () => {
|
|
|
1251
2612
|
}
|
|
1252
2613
|
);
|
|
1253
2614
|
}
|
|
1254
|
-
return /* @__PURE__ */
|
|
2615
|
+
return /* @__PURE__ */ jsxs16(
|
|
1255
2616
|
"button",
|
|
1256
2617
|
{
|
|
1257
2618
|
className: "flex h-[34px] items-center gap-2 rounded-md border-1 border-black px-1.5 text-sm font-medium text-black",
|
|
1258
2619
|
onClick: openAccountModal,
|
|
1259
2620
|
children: [
|
|
1260
|
-
chain.hasIcon && /* @__PURE__ */
|
|
2621
|
+
chain.hasIcon && /* @__PURE__ */ jsx28("div", { className: "h-6 w-6 overflow-hidden rounded-full", style: { background: chain.iconBackground }, children: chain.iconUrl && /* @__PURE__ */ jsx28("img", { alt: chain.name ?? "Chain icon", src: chain.iconUrl }) }),
|
|
1261
2622
|
account.displayName
|
|
1262
2623
|
]
|
|
1263
2624
|
}
|
|
@@ -1267,29 +2628,29 @@ var ConnectButton = () => {
|
|
|
1267
2628
|
};
|
|
1268
2629
|
|
|
1269
2630
|
// src/config/symbolLogos.tsx
|
|
1270
|
-
import { jsx as
|
|
1271
|
-
var MOCA_SVG = /* @__PURE__ */
|
|
1272
|
-
/* @__PURE__ */
|
|
1273
|
-
/* @__PURE__ */
|
|
2631
|
+
import { jsx as jsx29, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2632
|
+
var MOCA_SVG = /* @__PURE__ */ jsxs17("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", fill: "none", children: [
|
|
2633
|
+
/* @__PURE__ */ jsx29("circle", { cx: "14", cy: "14", r: "13.5", fill: "#C15F97" }),
|
|
2634
|
+
/* @__PURE__ */ jsx29(
|
|
1274
2635
|
"path",
|
|
1275
2636
|
{
|
|
1276
2637
|
fill: "#fff",
|
|
1277
2638
|
d: "M16.06 6.65c.3 0 .59.16.74.43l6.06 10.5a.85.85 0 1 1-1.47.84L16.06 9.2l-1.51 2.62-.02.03-3.8 6.57a.85.85 0 0 1-1.47-.84l3.57-6.18-1.27-2.2-5.32 9.22a.85.85 0 0 1-1.48-.84l6.07-10.5.06-.1a.85.85 0 0 1 1.4.1l1.52 2.62 1.52-2.62.06-.1c.16-.2.4-.33.67-.33Z"
|
|
1278
2639
|
}
|
|
1279
2640
|
),
|
|
1280
|
-
/* @__PURE__ */
|
|
2641
|
+
/* @__PURE__ */ jsx29("circle", { cx: "16", cy: "14", r: "1.5", fill: "#fff" })
|
|
1281
2642
|
] });
|
|
1282
|
-
var USDC_SVG = /* @__PURE__ */
|
|
1283
|
-
/* @__PURE__ */
|
|
1284
|
-
/* @__PURE__ */
|
|
1285
|
-
/* @__PURE__ */
|
|
2643
|
+
var USDC_SVG = /* @__PURE__ */ jsxs17("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", fill: "none", children: [
|
|
2644
|
+
/* @__PURE__ */ jsxs17("g", { clipPath: "url(#clip0_528_9163)", children: [
|
|
2645
|
+
/* @__PURE__ */ jsx29("path", { fill: "#2775CA", d: "M14 28c7.76 0 14-6.24 14-14S21.76 0 14 0 0 6.24 0 14s6.24 14 14 14Z" }),
|
|
2646
|
+
/* @__PURE__ */ jsx29(
|
|
1286
2647
|
"path",
|
|
1287
2648
|
{
|
|
1288
2649
|
fill: "#fff",
|
|
1289
2650
|
d: "M17.85 16.22c0-2.04-1.23-2.74-3.68-3.04-1.75-.23-2.1-.7-2.1-1.51 0-.82.59-1.34 1.75-1.34 1.05 0 1.64.35 1.93 1.22.06.18.23.3.4.3h.94a.4.4 0 0 0 .41-.42v-.05a2.91 2.91 0 0 0-2.63-2.4v-1.4c0-.23-.17-.4-.46-.46h-.88c-.23 0-.4.17-.46.46v1.35c-1.75.23-2.86 1.4-2.86 2.85 0 1.93 1.16 2.69 3.61 2.98 1.64.29 2.16.64 2.16 1.57 0 .94-.81 1.58-1.92 1.58-1.52 0-2.04-.64-2.22-1.52-.06-.23-.23-.35-.4-.35h-1a.4.4 0 0 0-.4.41v.06c.23 1.46 1.16 2.5 3.08 2.8v1.4c0 .23.18.4.47.47h.88c.23 0 .4-.18.46-.47v-1.4c1.75-.3 2.92-1.52 2.92-3.1Z"
|
|
1290
2651
|
}
|
|
1291
2652
|
),
|
|
1292
|
-
/* @__PURE__ */
|
|
2653
|
+
/* @__PURE__ */ jsx29(
|
|
1293
2654
|
"path",
|
|
1294
2655
|
{
|
|
1295
2656
|
fill: "#fff",
|
|
@@ -1297,11 +2658,11 @@ var USDC_SVG = /* @__PURE__ */ jsxs12("svg", { xmlns: "http://www.w3.org/2000/sv
|
|
|
1297
2658
|
}
|
|
1298
2659
|
)
|
|
1299
2660
|
] }),
|
|
1300
|
-
/* @__PURE__ */
|
|
2661
|
+
/* @__PURE__ */ jsx29("defs", { children: /* @__PURE__ */ jsx29("clipPath", { id: "clip0_528_9163", children: /* @__PURE__ */ jsx29("path", { fill: "#fff", d: "M0 0h28v28H0z" }) }) })
|
|
1301
2662
|
] });
|
|
1302
|
-
var USDT_SVG = /* @__PURE__ */
|
|
1303
|
-
/* @__PURE__ */
|
|
1304
|
-
/* @__PURE__ */
|
|
2663
|
+
var USDT_SVG = /* @__PURE__ */ jsxs17("svg", { xmlns: "http://www.w3.org/2000/svg", width: "28", height: "28", fill: "none", children: [
|
|
2664
|
+
/* @__PURE__ */ jsx29("path", { fill: "#26A17B", d: "M14 28a14 14 0 1 0 0-28 14 14 0 0 0 0 28Z" }),
|
|
2665
|
+
/* @__PURE__ */ jsx29(
|
|
1305
2666
|
"path",
|
|
1306
2667
|
{
|
|
1307
2668
|
fill: "#fff",
|
|
@@ -1309,23 +2670,23 @@ var USDT_SVG = /* @__PURE__ */ jsxs12("svg", { xmlns: "http://www.w3.org/2000/sv
|
|
|
1309
2670
|
}
|
|
1310
2671
|
)
|
|
1311
2672
|
] });
|
|
1312
|
-
var WETH_SVG = /* @__PURE__ */
|
|
1313
|
-
/* @__PURE__ */
|
|
1314
|
-
/* @__PURE__ */
|
|
2673
|
+
var WETH_SVG = /* @__PURE__ */ jsxs17("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", width: "28", height: "28", viewBox: "0 0 24 24", children: [
|
|
2674
|
+
/* @__PURE__ */ jsxs17("g", { clipPath: "url(#clip0_528_9173)", children: [
|
|
2675
|
+
/* @__PURE__ */ jsx29(
|
|
1315
2676
|
"path",
|
|
1316
2677
|
{
|
|
1317
2678
|
fill: "#000",
|
|
1318
2679
|
d: "M17.14 20.57c0 .95-1.31 2.01-3.39 2.4h-2.59c-4.65 0-8.42-1.07-8.42-2.4 0-1.32 3.77-2.4 8.42-2.4s5.98 1.08 5.98 2.4Z"
|
|
1319
2680
|
}
|
|
1320
2681
|
),
|
|
1321
|
-
/* @__PURE__ */
|
|
2682
|
+
/* @__PURE__ */ jsx29(
|
|
1322
2683
|
"path",
|
|
1323
2684
|
{
|
|
1324
2685
|
fill: "#F61F7D",
|
|
1325
2686
|
d: "M23.31 11c0 5.86-5.18 11.63-11.07 11.63-5.9 0-11.9-6.17-11.9-12.03C.34 4.75 5.12 0 11.01 0s12.3 5.15 12.3 11Z"
|
|
1326
2687
|
}
|
|
1327
2688
|
),
|
|
1328
|
-
/* @__PURE__ */
|
|
2689
|
+
/* @__PURE__ */ jsx29(
|
|
1329
2690
|
"path",
|
|
1330
2691
|
{
|
|
1331
2692
|
fill: "#000",
|
|
@@ -1334,8 +2695,8 @@ var WETH_SVG = /* @__PURE__ */ jsxs12("svg", { xmlns: "http://www.w3.org/2000/sv
|
|
|
1334
2695
|
clipRule: "evenodd"
|
|
1335
2696
|
}
|
|
1336
2697
|
),
|
|
1337
|
-
/* @__PURE__ */
|
|
1338
|
-
/* @__PURE__ */
|
|
2698
|
+
/* @__PURE__ */ jsx29("path", { fill: "#fff", d: "M24 12.17a10.8 10.8 0 1 1-21.6 0 10.8 10.8 0 0 1 21.6 0Z" }),
|
|
2699
|
+
/* @__PURE__ */ jsx29(
|
|
1339
2700
|
"path",
|
|
1340
2701
|
{
|
|
1341
2702
|
fill: "#000",
|
|
@@ -1344,8 +2705,8 @@ var WETH_SVG = /* @__PURE__ */ jsxs12("svg", { xmlns: "http://www.w3.org/2000/sv
|
|
|
1344
2705
|
clipRule: "evenodd"
|
|
1345
2706
|
}
|
|
1346
2707
|
),
|
|
1347
|
-
/* @__PURE__ */
|
|
1348
|
-
/* @__PURE__ */
|
|
2708
|
+
/* @__PURE__ */ jsx29("path", { fill: "#000", fillRule: "evenodd", d: "M3.02 10.63.7 8.75l.74-.86 2.34 1.87-.75.87Z", clipRule: "evenodd" }),
|
|
2709
|
+
/* @__PURE__ */ jsx29(
|
|
1349
2710
|
"path",
|
|
1350
2711
|
{
|
|
1351
2712
|
fill: "#000",
|
|
@@ -1353,7 +2714,7 @@ var WETH_SVG = /* @__PURE__ */ jsxs12("svg", { xmlns: "http://www.w3.org/2000/sv
|
|
|
1353
2714
|
}
|
|
1354
2715
|
)
|
|
1355
2716
|
] }),
|
|
1356
|
-
/* @__PURE__ */
|
|
2717
|
+
/* @__PURE__ */ jsx29("defs", { children: /* @__PURE__ */ jsx29("clipPath", { id: "clip0_528_9173", children: /* @__PURE__ */ jsx29("path", { fill: "#fff", d: "M0 0h24v24H0z" }) }) })
|
|
1357
2718
|
] });
|
|
1358
2719
|
var symbolLogos = {
|
|
1359
2720
|
MOCA: MOCA_SVG,
|
|
@@ -1366,34 +2727,34 @@ function getSymbolLogo(symbol) {
|
|
|
1366
2727
|
}
|
|
1367
2728
|
|
|
1368
2729
|
// src/components/CryptoTab/Crypto/Logos.tsx
|
|
1369
|
-
import { jsx as
|
|
2730
|
+
import { jsx as jsx30, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1370
2731
|
var Logos = () => {
|
|
1371
|
-
return /* @__PURE__ */
|
|
1372
|
-
/* @__PURE__ */
|
|
1373
|
-
/* @__PURE__ */
|
|
1374
|
-
/* @__PURE__ */
|
|
1375
|
-
/* @__PURE__ */
|
|
2732
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex", children: [
|
|
2733
|
+
/* @__PURE__ */ jsx30("div", { className: "rounded-full border border-[#F5F7FA]", children: getSymbolLogo("MOCA") }),
|
|
2734
|
+
/* @__PURE__ */ jsx30("div", { className: "-ml-2.5 rounded-full border border-[#F5F7FA]", children: getSymbolLogo("USDC") }),
|
|
2735
|
+
/* @__PURE__ */ jsx30("div", { className: "-ml-2.5 rounded-full border border-[#F5F7FA]", children: getSymbolLogo("USDT") }),
|
|
2736
|
+
/* @__PURE__ */ jsx30("div", { className: "-ml-2.5 rounded-full border border-[#F5F7FA] bg-[#F5F7FA]", children: getSymbolLogo("WETH") })
|
|
1376
2737
|
] });
|
|
1377
2738
|
};
|
|
1378
2739
|
|
|
1379
2740
|
// src/components/CryptoTab/Crypto/SelectCoinButton.tsx
|
|
1380
|
-
import
|
|
2741
|
+
import NiceModal5 from "@ebay/nice-modal-react";
|
|
1381
2742
|
|
|
1382
2743
|
// src/modals/CryptoSelectModal.tsx
|
|
1383
|
-
import
|
|
2744
|
+
import NiceModal4, { useModal as useModal2 } from "@ebay/nice-modal-react";
|
|
1384
2745
|
|
|
1385
2746
|
// src/hooks/useBaseERC20Token.ts
|
|
1386
|
-
import * as
|
|
1387
|
-
import { erc20Abi as
|
|
2747
|
+
import * as React13 from "react";
|
|
2748
|
+
import { erc20Abi as erc20Abi3, formatUnits, getAddress } from "viem";
|
|
1388
2749
|
import { useAccount, usePublicClient } from "wagmi";
|
|
1389
2750
|
function useBaseERC20Token() {
|
|
1390
2751
|
const { address } = useAccount();
|
|
1391
2752
|
const baseClient = usePublicClient({ chainId: BASE_CHAIN_ID });
|
|
1392
2753
|
const defaultClient = usePublicClient();
|
|
1393
|
-
const [rows, setRows] =
|
|
1394
|
-
const [isLoading, setLoading] =
|
|
1395
|
-
const [error, setError] =
|
|
1396
|
-
|
|
2754
|
+
const [rows, setRows] = React13.useState([]);
|
|
2755
|
+
const [isLoading, setLoading] = React13.useState(false);
|
|
2756
|
+
const [error, setError] = React13.useState(null);
|
|
2757
|
+
React13.useEffect(() => {
|
|
1397
2758
|
let cancelled = false;
|
|
1398
2759
|
async function run() {
|
|
1399
2760
|
const client = baseClient ?? defaultClient;
|
|
@@ -1415,7 +2776,7 @@ function useBaseERC20Token() {
|
|
|
1415
2776
|
allowFailure: true,
|
|
1416
2777
|
contracts: normalizedTokens.map((t) => ({
|
|
1417
2778
|
address: t.address,
|
|
1418
|
-
abi:
|
|
2779
|
+
abi: erc20Abi3,
|
|
1419
2780
|
functionName: "balanceOf",
|
|
1420
2781
|
args: [address]
|
|
1421
2782
|
}))
|
|
@@ -1467,8 +2828,8 @@ function useBaseNativeToken() {
|
|
|
1467
2828
|
}
|
|
1468
2829
|
|
|
1469
2830
|
// src/modals/CryptoSelectModal.tsx
|
|
1470
|
-
import { Fragment as
|
|
1471
|
-
var CryptoSelectModal =
|
|
2831
|
+
import { Fragment as Fragment5, jsx as jsx31, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2832
|
+
var CryptoSelectModal = NiceModal4.create(() => {
|
|
1472
2833
|
const modal = useModal2();
|
|
1473
2834
|
const { isLoading, error, erc20Balances } = useBaseERC20Token();
|
|
1474
2835
|
const { isLoadingNative, nativeError, nativeBalance } = useBaseNativeToken();
|
|
@@ -1477,13 +2838,13 @@ var CryptoSelectModal = NiceModal3.create(() => {
|
|
|
1477
2838
|
modal.remove();
|
|
1478
2839
|
setSelectedPaymentMethod({ type: "CRYPTO" /* CRYPTO */, method: coin });
|
|
1479
2840
|
};
|
|
1480
|
-
return /* @__PURE__ */
|
|
1481
|
-
/* @__PURE__ */
|
|
1482
|
-
/* @__PURE__ */
|
|
1483
|
-
/* @__PURE__ */
|
|
1484
|
-
/* @__PURE__ */
|
|
1485
|
-
/* @__PURE__ */
|
|
1486
|
-
/* @__PURE__ */
|
|
2841
|
+
return /* @__PURE__ */ jsxs19(Dialog, { open: modal.visible, onOpenChange: modal.remove, children: [
|
|
2842
|
+
/* @__PURE__ */ jsx31(DialogDescription, { className: "hidden", children: "Crypto Select Modal" }),
|
|
2843
|
+
/* @__PURE__ */ jsxs19(DialogContent, { showCloseButton: false, className: "gap-0 p-0", children: [
|
|
2844
|
+
/* @__PURE__ */ jsx31("div", { className: "flex flex-col gap-6 px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsxs19("div", { className: "flex items-center justify-between gap-4", children: [
|
|
2845
|
+
/* @__PURE__ */ jsx31("button", { className: "rounded-md hover:bg-gray-100", onClick: modal.remove, children: /* @__PURE__ */ jsx31("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "25", fill: "none", children: /* @__PURE__ */ jsx31("path", { stroke: "#000", d: "m15 6.5-6 6 6 6" }) }) }),
|
|
2846
|
+
/* @__PURE__ */ jsx31(DialogTitle, { className: "text-primary text-2xl font-semibold", children: "Select a token" }),
|
|
2847
|
+
/* @__PURE__ */ jsx31("button", { className: "rounded-md p-1 hover:bg-gray-100", onClick: modal.remove, children: /* @__PURE__ */ jsx31("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "17", fill: "none", children: /* @__PURE__ */ jsx31(
|
|
1487
2848
|
"path",
|
|
1488
2849
|
{
|
|
1489
2850
|
fill: "#000",
|
|
@@ -1491,19 +2852,19 @@ var CryptoSelectModal = NiceModal3.create(() => {
|
|
|
1491
2852
|
}
|
|
1492
2853
|
) }) })
|
|
1493
2854
|
] }) }),
|
|
1494
|
-
/* @__PURE__ */
|
|
1495
|
-
/* @__PURE__ */
|
|
1496
|
-
(error || nativeError) && /* @__PURE__ */
|
|
1497
|
-
/* @__PURE__ */
|
|
1498
|
-
isLoadingNative && /* @__PURE__ */
|
|
1499
|
-
nativeBalance && /* @__PURE__ */
|
|
2855
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-4 px-5 py-5 md:px-7 md:py-6", children: [
|
|
2856
|
+
/* @__PURE__ */ jsx31("h3", { className: "text-primary text-xl font-semibold", children: "Tokens with wallet balance" }),
|
|
2857
|
+
(error || nativeError) && /* @__PURE__ */ jsx31("p", { className: "text-center text-sm text-red-500", children: "Something wrong" }),
|
|
2858
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex w-full flex-col gap-1", children: [
|
|
2859
|
+
isLoadingNative && /* @__PURE__ */ jsx31("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" }),
|
|
2860
|
+
nativeBalance && /* @__PURE__ */ jsxs19(
|
|
1500
2861
|
"button",
|
|
1501
2862
|
{
|
|
1502
2863
|
className: "flex h-11 w-full items-center justify-between gap-4 rounded-sm px-1.5 text-black hover:bg-gray-100",
|
|
1503
2864
|
onClick: () => handleSelect(nativeBalance),
|
|
1504
2865
|
children: [
|
|
1505
|
-
/* @__PURE__ */
|
|
1506
|
-
nativeBalance.logoURI && /* @__PURE__ */
|
|
2866
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
|
|
2867
|
+
nativeBalance.logoURI && /* @__PURE__ */ jsx31(
|
|
1507
2868
|
"img",
|
|
1508
2869
|
{
|
|
1509
2870
|
className: "h-8 w-8 shrink-0",
|
|
@@ -1511,31 +2872,31 @@ var CryptoSelectModal = NiceModal3.create(() => {
|
|
|
1511
2872
|
alt: `${nativeBalance.symbol} logo`
|
|
1512
2873
|
}
|
|
1513
2874
|
),
|
|
1514
|
-
/* @__PURE__ */
|
|
2875
|
+
/* @__PURE__ */ jsx31("p", { className: "text-sm font-medium", children: nativeBalance.symbol })
|
|
1515
2876
|
] }),
|
|
1516
|
-
/* @__PURE__ */
|
|
2877
|
+
/* @__PURE__ */ jsx31("p", { className: "text-sm font-medium", children: nativeBalance.formatted })
|
|
1517
2878
|
]
|
|
1518
2879
|
},
|
|
1519
2880
|
nativeBalance.symbol
|
|
1520
2881
|
),
|
|
1521
|
-
isLoading && /* @__PURE__ */
|
|
1522
|
-
/* @__PURE__ */
|
|
1523
|
-
/* @__PURE__ */
|
|
1524
|
-
/* @__PURE__ */
|
|
2882
|
+
isLoading && /* @__PURE__ */ jsxs19(Fragment5, { children: [
|
|
2883
|
+
/* @__PURE__ */ jsx31("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" }),
|
|
2884
|
+
/* @__PURE__ */ jsx31("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" }),
|
|
2885
|
+
/* @__PURE__ */ jsx31("div", { className: "h-11 animate-pulse rounded-md bg-gray-100" })
|
|
1525
2886
|
] }),
|
|
1526
2887
|
erc20Balances.map((coin) => {
|
|
1527
2888
|
const Icon = getSymbolLogo(coin.symbol);
|
|
1528
|
-
return /* @__PURE__ */
|
|
2889
|
+
return /* @__PURE__ */ jsxs19(
|
|
1529
2890
|
"button",
|
|
1530
2891
|
{
|
|
1531
2892
|
className: "flex h-11 w-full items-center justify-between gap-4 rounded-sm px-1.5 text-black hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50",
|
|
1532
2893
|
onClick: () => handleSelect(coin),
|
|
1533
2894
|
children: [
|
|
1534
|
-
/* @__PURE__ */
|
|
2895
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
|
|
1535
2896
|
Boolean(Icon) && Icon,
|
|
1536
|
-
/* @__PURE__ */
|
|
2897
|
+
/* @__PURE__ */ jsx31("p", { className: "text-sm font-medium", children: coin.symbol })
|
|
1537
2898
|
] }),
|
|
1538
|
-
/* @__PURE__ */
|
|
2899
|
+
/* @__PURE__ */ jsx31("p", { className: "text-sm font-medium", children: coin.formatted })
|
|
1539
2900
|
]
|
|
1540
2901
|
},
|
|
1541
2902
|
coin.symbol
|
|
@@ -1549,51 +2910,51 @@ var CryptoSelectModal = NiceModal3.create(() => {
|
|
|
1549
2910
|
CryptoSelectModal.displayName = "CryptoSelectModal";
|
|
1550
2911
|
|
|
1551
2912
|
// src/components/CryptoTab/Crypto/SelectCoinButton.tsx
|
|
1552
|
-
import { jsx as
|
|
2913
|
+
import { jsx as jsx32, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1553
2914
|
var SelectCoinButton = () => {
|
|
1554
2915
|
const openModal = () => {
|
|
1555
|
-
|
|
2916
|
+
NiceModal5.show(CryptoSelectModal);
|
|
1556
2917
|
};
|
|
1557
|
-
return /* @__PURE__ */
|
|
1558
|
-
/* @__PURE__ */
|
|
1559
|
-
/* @__PURE__ */
|
|
1560
|
-
/* @__PURE__ */
|
|
1561
|
-
/* @__PURE__ */
|
|
2918
|
+
return /* @__PURE__ */ jsxs20("button", { onClick: openModal, type: "button", className: "bg-primary/8 flex h-11 w-full overflow-hidden rounded-md", children: [
|
|
2919
|
+
/* @__PURE__ */ jsx32("div", { className: "bg-primary flex h-full w-11 items-center justify-center", children: /* @__PURE__ */ jsx32("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white" }) }),
|
|
2920
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex h-full w-full items-center justify-between px-3", children: [
|
|
2921
|
+
/* @__PURE__ */ jsx32("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx32("p", { className: "font-medium text-black/50", children: "Select a token" }) }),
|
|
2922
|
+
/* @__PURE__ */ jsx32("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", fill: "none", children: /* @__PURE__ */ jsx32("path", { stroke: "#000", strokeLinecap: "round", d: "m6 12.43 4-4-4-4" }) })
|
|
1562
2923
|
] })
|
|
1563
2924
|
] });
|
|
1564
2925
|
};
|
|
1565
2926
|
|
|
1566
2927
|
// src/components/CryptoTab/Crypto/SelectedCoin.tsx
|
|
1567
|
-
import { jsx as
|
|
2928
|
+
import { jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1568
2929
|
var SelectedCoin = (props) => {
|
|
1569
2930
|
const { coin, balance, logoURI } = props;
|
|
1570
2931
|
const Icon = getSymbolLogo(coin);
|
|
1571
|
-
return /* @__PURE__ */
|
|
1572
|
-
/* @__PURE__ */
|
|
1573
|
-
/* @__PURE__ */
|
|
1574
|
-
/* @__PURE__ */
|
|
2932
|
+
return /* @__PURE__ */ jsxs21("div", { className: "bg-primary/8 flex h-11 w-full overflow-hidden rounded-md", children: [
|
|
2933
|
+
/* @__PURE__ */ jsx33("div", { className: "bg-primary flex h-full w-11 items-center justify-center", children: /* @__PURE__ */ jsx33("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-white", children: /* @__PURE__ */ jsx33("div", { className: "bg-primary h-2.5 w-2.5 rounded-full" }) }) }),
|
|
2934
|
+
/* @__PURE__ */ jsxs21("div", { className: "border-primary flex h-full w-full items-center justify-between rounded-r-md border-1 !border-l-0 px-3", children: [
|
|
2935
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-1", children: [
|
|
1575
2936
|
Icon,
|
|
1576
|
-
!Icon && logoURI && /* @__PURE__ */
|
|
1577
|
-
/* @__PURE__ */
|
|
1578
|
-
/* @__PURE__ */
|
|
2937
|
+
!Icon && logoURI && /* @__PURE__ */ jsx33("img", { className: "mr-1 h-8 w-8 shrink-0", src: logoURI, alt: `${coin} logo` }),
|
|
2938
|
+
/* @__PURE__ */ jsx33("p", { className: "font-semibold text-black", children: coin }),
|
|
2939
|
+
/* @__PURE__ */ jsx33("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx33("path", { d: "M6 12.4341L10 8.43408L6 4.43408", stroke: "black", strokeLinecap: "round" }) })
|
|
1579
2940
|
] }),
|
|
1580
|
-
/* @__PURE__ */
|
|
2941
|
+
/* @__PURE__ */ jsxs21("p", { className: "text-xs font-medium text-black/50", children: [
|
|
1581
2942
|
"Wallet balance ",
|
|
1582
|
-
/* @__PURE__ */
|
|
2943
|
+
/* @__PURE__ */ jsx33("span", { className: "text-black", children: balance })
|
|
1583
2944
|
] })
|
|
1584
2945
|
] })
|
|
1585
2946
|
] });
|
|
1586
2947
|
};
|
|
1587
2948
|
|
|
1588
2949
|
// src/components/CryptoTab/Crypto/Crypto.tsx
|
|
1589
|
-
import { jsx as
|
|
2950
|
+
import { jsx as jsx34, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1590
2951
|
var Crypto = () => {
|
|
1591
2952
|
const { address } = useAccount3();
|
|
1592
2953
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
1593
2954
|
const { cryptoPayment } = useCryptoPayment();
|
|
1594
2955
|
const isWalletConnected = Boolean(address);
|
|
1595
2956
|
const { register } = useSpreePayRegister();
|
|
1596
|
-
const handlePay =
|
|
2957
|
+
const handlePay = useCallback6(
|
|
1597
2958
|
async (data) => {
|
|
1598
2959
|
try {
|
|
1599
2960
|
const res = await cryptoPayment(data);
|
|
@@ -1607,17 +2968,17 @@ var Crypto = () => {
|
|
|
1607
2968
|
},
|
|
1608
2969
|
[cryptoPayment]
|
|
1609
2970
|
);
|
|
1610
|
-
|
|
2971
|
+
useEffect9(() => {
|
|
1611
2972
|
register(handlePay);
|
|
1612
2973
|
}, [register, handlePay]);
|
|
1613
|
-
return /* @__PURE__ */
|
|
1614
|
-
/* @__PURE__ */
|
|
1615
|
-
/* @__PURE__ */
|
|
1616
|
-
/* @__PURE__ */
|
|
2974
|
+
return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col items-baseline gap-4", children: [
|
|
2975
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex w-full items-center justify-between gap-4", children: [
|
|
2976
|
+
/* @__PURE__ */ jsx34("h3", { className: "text-primary text-xl leading-[1.7] font-semibold", children: "Pay with Crypto" }),
|
|
2977
|
+
/* @__PURE__ */ jsx34(ConnectButton, {})
|
|
1617
2978
|
] }),
|
|
1618
|
-
!isWalletConnected && /* @__PURE__ */
|
|
1619
|
-
isWalletConnected && /* @__PURE__ */
|
|
1620
|
-
selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && selectedPaymentMethod.method && /* @__PURE__ */
|
|
2979
|
+
!isWalletConnected && /* @__PURE__ */ jsx34(Logos, {}),
|
|
2980
|
+
isWalletConnected && /* @__PURE__ */ jsxs22("div", { className: "flex w-full flex-col gap-1", children: [
|
|
2981
|
+
selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && selectedPaymentMethod.method && /* @__PURE__ */ jsx34(
|
|
1621
2982
|
SelectedCoin,
|
|
1622
2983
|
{
|
|
1623
2984
|
coin: selectedPaymentMethod.method.symbol,
|
|
@@ -1625,13 +2986,13 @@ var Crypto = () => {
|
|
|
1625
2986
|
logoURI: selectedPaymentMethod.method.logoURI
|
|
1626
2987
|
}
|
|
1627
2988
|
),
|
|
1628
|
-
/* @__PURE__ */
|
|
2989
|
+
/* @__PURE__ */ jsx34(SelectCoinButton, {})
|
|
1629
2990
|
] })
|
|
1630
2991
|
] });
|
|
1631
2992
|
};
|
|
1632
2993
|
|
|
1633
2994
|
// src/components/CryptoTab/Crypto/CryptoWrapper.tsx
|
|
1634
|
-
import { jsx as
|
|
2995
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
1635
2996
|
var queryClient = new QueryClient();
|
|
1636
2997
|
var connectors = connectorsForWallets(
|
|
1637
2998
|
[
|
|
@@ -1649,29 +3010,30 @@ var config = createConfig({
|
|
|
1649
3010
|
ssr: true
|
|
1650
3011
|
});
|
|
1651
3012
|
var CryptoWrapper = () => {
|
|
1652
|
-
return /* @__PURE__ */
|
|
3013
|
+
return /* @__PURE__ */ jsx35(WagmiProvider, { config, children: /* @__PURE__ */ jsx35(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx35(RainbowKitProvider, { children: /* @__PURE__ */ jsx35(NiceModal6.Provider, { children: /* @__PURE__ */ jsx35(Crypto, {}) }) }) }) });
|
|
1653
3014
|
};
|
|
1654
3015
|
|
|
1655
3016
|
// src/components/CryptoTab/CryptoTab.tsx
|
|
1656
|
-
import { jsx as
|
|
1657
|
-
var CryptoTab = (
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
/* @__PURE__ */
|
|
1661
|
-
/* @__PURE__ */ jsx24("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsx24(PointsSwitch, { disabled: true, pointsTitle, pointsConversionRatio }) })
|
|
3017
|
+
import { jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
3018
|
+
var CryptoTab = () => {
|
|
3019
|
+
return /* @__PURE__ */ jsxs23("div", { children: [
|
|
3020
|
+
/* @__PURE__ */ jsx36("div", { className: "border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-5", children: /* @__PURE__ */ jsx36(CryptoWrapper, {}) }),
|
|
3021
|
+
/* @__PURE__ */ jsx36("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsx36(PointsSwitch, { disabled: true }) })
|
|
1662
3022
|
] });
|
|
1663
3023
|
};
|
|
1664
3024
|
|
|
1665
3025
|
// src/components/TabButtons.tsx
|
|
1666
|
-
import { jsx as
|
|
1667
|
-
var TabButton = ({ isActive, children, onClick }) => {
|
|
1668
|
-
return /* @__PURE__ */
|
|
3026
|
+
import { jsx as jsx37, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
3027
|
+
var TabButton = ({ isDisabled = true, isActive, children, onClick }) => {
|
|
3028
|
+
return /* @__PURE__ */ jsx37(
|
|
1669
3029
|
"button",
|
|
1670
3030
|
{
|
|
3031
|
+
disabled: isDisabled,
|
|
1671
3032
|
onClick,
|
|
1672
3033
|
className: cn(
|
|
1673
3034
|
"flex w-[132px] flex-col items-baseline rounded-sm border-1 border-black/50 px-2.5 py-1.5 text-sm text-black",
|
|
1674
|
-
{ "opacity-50": !isActive },
|
|
3035
|
+
{ "opacity-50": !isActive || isDisabled },
|
|
3036
|
+
{ "cursor-not-allowed": isDisabled },
|
|
1675
3037
|
{ "bg-primary/7 border-primary text-primary": isActive }
|
|
1676
3038
|
),
|
|
1677
3039
|
children
|
|
@@ -1680,84 +3042,99 @@ var TabButton = ({ isActive, children, onClick }) => {
|
|
|
1680
3042
|
};
|
|
1681
3043
|
var TabButtons = (props) => {
|
|
1682
3044
|
const { value, onChange } = props;
|
|
3045
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
1683
3046
|
const handleChange = (type) => () => {
|
|
1684
3047
|
if (value !== type) {
|
|
1685
3048
|
onChange({ type, method: null });
|
|
1686
3049
|
}
|
|
1687
3050
|
};
|
|
1688
|
-
return /* @__PURE__ */
|
|
1689
|
-
/* @__PURE__ */
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
{
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
3051
|
+
return /* @__PURE__ */ jsxs24("div", { className: "flex gap-2", children: [
|
|
3052
|
+
/* @__PURE__ */ jsxs24(
|
|
3053
|
+
TabButton,
|
|
3054
|
+
{
|
|
3055
|
+
isDisabled: !spreePayConfig?.creditCard.enabled,
|
|
3056
|
+
onClick: handleChange("CREDIT_CARD" /* CREDIT_CARD */),
|
|
3057
|
+
isActive: value === "CREDIT_CARD" /* CREDIT_CARD */,
|
|
3058
|
+
children: [
|
|
3059
|
+
/* @__PURE__ */ jsx37("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", fill: "none", children: /* @__PURE__ */ jsx37(
|
|
3060
|
+
"path",
|
|
3061
|
+
{
|
|
3062
|
+
fill: "currentColor",
|
|
3063
|
+
d: "M22 6v12c0 .55-.2 1.02-.59 1.41-.39.4-.86.59-1.41.59H4c-.55 0-1.02-.2-1.41-.59-.4-.39-.59-.86-.59-1.41V6c0-.55.2-1.02.59-1.41C2.98 4.19 3.45 4 4 4h16c.55 0 1.02.2 1.41.59.4.39.59.86.59 1.41ZM4 8h16V6H4v2Zm0 4v6h16v-6H4Z"
|
|
3064
|
+
}
|
|
3065
|
+
) }),
|
|
3066
|
+
/* @__PURE__ */ jsx37("p", { className: "text-sm font-medium", children: "Card" })
|
|
3067
|
+
]
|
|
3068
|
+
}
|
|
3069
|
+
),
|
|
3070
|
+
/* @__PURE__ */ jsxs24(
|
|
3071
|
+
TabButton,
|
|
3072
|
+
{
|
|
3073
|
+
isDisabled: !spreePayConfig?.creditCard.enabled,
|
|
3074
|
+
onClick: handleChange("CRYPTO" /* CRYPTO */),
|
|
3075
|
+
isActive: value === "CRYPTO" /* CRYPTO */,
|
|
3076
|
+
children: [
|
|
3077
|
+
/* @__PURE__ */ jsxs24("svg", { className: "my-1", xmlns: "http://www.w3.org/2000/svg", width: "30", height: "16", fill: "none", children: [
|
|
3078
|
+
/* @__PURE__ */ jsx37(
|
|
3079
|
+
"path",
|
|
3080
|
+
{
|
|
3081
|
+
fill: "currentColor",
|
|
3082
|
+
d: "M14.5 0C19.2 0 23 3.58 23 8s-3.8 8-8.5 8a8.93 8.93 0 0 1-3.35-.65 8 8 0 0 0 2.24-1.44c.36.06.73.09 1.11.09 3.7 0 6.5-2.8 6.5-6s-2.8-6-6.5-6c-.38 0-.75.03-1.11.09A8 8 0 0 0 11.15.65 8.93 8.93 0 0 1 14.5 0Z"
|
|
3083
|
+
}
|
|
3084
|
+
),
|
|
3085
|
+
/* @__PURE__ */ jsx37(
|
|
3086
|
+
"path",
|
|
3087
|
+
{
|
|
3088
|
+
fill: "currentColor",
|
|
3089
|
+
d: "M21.15 0c4.7 0 8.5 3.58 8.5 8s-3.8 8-8.5 8a8.93 8.93 0 0 1-3.35-.65 8 8 0 0 0 2.24-1.44c.36.06.73.09 1.1.09 3.71 0 6.5-2.8 6.5-6s-2.79-6-6.5-6c-.37 0-.74.03-1.1.09A8 8 0 0 0 17.8.65 8.93 8.93 0 0 1 21.15 0Z"
|
|
3090
|
+
}
|
|
3091
|
+
),
|
|
3092
|
+
/* @__PURE__ */ jsx37("circle", { cx: "8", cy: "8", r: "7", stroke: "currentColor", strokeWidth: "2" })
|
|
3093
|
+
] }),
|
|
3094
|
+
/* @__PURE__ */ jsx37("p", { className: "text-sm font-medium", children: "Crypto" })
|
|
3095
|
+
]
|
|
3096
|
+
}
|
|
3097
|
+
)
|
|
1719
3098
|
] });
|
|
1720
3099
|
};
|
|
1721
3100
|
|
|
1722
3101
|
// src/components/Tabs.tsx
|
|
1723
|
-
import { jsx as
|
|
1724
|
-
var Tabs = (
|
|
3102
|
+
import { jsx as jsx38, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
3103
|
+
var Tabs = () => {
|
|
1725
3104
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
/* @__PURE__ */
|
|
1730
|
-
/* @__PURE__ */ jsx26(TabButtons, { value: selectedPaymentMethod.type, onChange: setSelectedPaymentMethod })
|
|
3105
|
+
return /* @__PURE__ */ jsxs25("div", { className: "mb-4 rounded-3xl border border-black/25 bg-white", children: [
|
|
3106
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex w-full flex-col gap-4 border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-6", children: [
|
|
3107
|
+
/* @__PURE__ */ jsx38("h2", { className: "text-primary text-2xl font-semibold", children: "Choose a Payment Method" }),
|
|
3108
|
+
/* @__PURE__ */ jsx38(TabButtons, { value: selectedPaymentMethod.type, onChange: setSelectedPaymentMethod })
|
|
1731
3109
|
] }),
|
|
1732
|
-
selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && /* @__PURE__ */
|
|
1733
|
-
selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && /* @__PURE__ */
|
|
3110
|
+
selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && /* @__PURE__ */ jsx38(CreditCardTab, {}),
|
|
3111
|
+
selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && /* @__PURE__ */ jsx38(CryptoTab, {})
|
|
1734
3112
|
] });
|
|
1735
3113
|
};
|
|
1736
3114
|
|
|
1737
3115
|
// src/SpreePayContent.tsx
|
|
1738
|
-
import { jsx as
|
|
1739
|
-
var SpreePayContent = (
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
/* @__PURE__ */
|
|
1743
|
-
/* @__PURE__ */
|
|
1744
|
-
/* @__PURE__ */ jsx27(SpreeLegal, {})
|
|
3116
|
+
import { jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
3117
|
+
var SpreePayContent = ({ isLoggedIn }) => {
|
|
3118
|
+
return /* @__PURE__ */ jsxs26("div", { className: "w-full", children: [
|
|
3119
|
+
/* @__PURE__ */ jsx39(Tabs, {}),
|
|
3120
|
+
/* @__PURE__ */ jsx39(CheckoutButton, { isLoggedIn }),
|
|
3121
|
+
/* @__PURE__ */ jsx39(SpreeLegal, {})
|
|
1745
3122
|
] });
|
|
1746
3123
|
};
|
|
1747
3124
|
|
|
1748
3125
|
// src/hooks/useKeycloakSSO.ts
|
|
1749
|
-
import { useCallback as
|
|
3126
|
+
import { useCallback as useCallback7, useEffect as useEffect10, useRef as useRef6, useState as useState12 } from "react";
|
|
1750
3127
|
import Keycloak from "keycloak-js";
|
|
1751
3128
|
var refreshAheadSeconds = 60;
|
|
1752
3129
|
function useKeycloakSSO(config2) {
|
|
1753
3130
|
const { url, realm, clientId, ssoPageURI, enabled } = config2;
|
|
1754
|
-
const initRef =
|
|
1755
|
-
const kcRef =
|
|
1756
|
-
const refreshTimerRef =
|
|
1757
|
-
const [error, setError] =
|
|
1758
|
-
const [isChecking, setIsChecking] =
|
|
1759
|
-
const [accessToken, setAccessToken] =
|
|
1760
|
-
const scheduleRefresh =
|
|
3131
|
+
const initRef = useRef6(false);
|
|
3132
|
+
const kcRef = useRef6(null);
|
|
3133
|
+
const refreshTimerRef = useRef6(null);
|
|
3134
|
+
const [error, setError] = useState12(null);
|
|
3135
|
+
const [isChecking, setIsChecking] = useState12(enabled);
|
|
3136
|
+
const [accessToken, setAccessToken] = useState12(null);
|
|
3137
|
+
const scheduleRefresh = useCallback7(() => {
|
|
1761
3138
|
const kc = kcRef.current;
|
|
1762
3139
|
if (!kc || !kc.tokenParsed || !kc.tokenParsed.exp) {
|
|
1763
3140
|
return;
|
|
@@ -1778,7 +3155,7 @@ function useKeycloakSSO(config2) {
|
|
|
1778
3155
|
});
|
|
1779
3156
|
}, delayMs);
|
|
1780
3157
|
}, []);
|
|
1781
|
-
|
|
3158
|
+
useEffect10(() => {
|
|
1782
3159
|
if (initRef.current || !enabled) return;
|
|
1783
3160
|
initRef.current = true;
|
|
1784
3161
|
setIsChecking(true);
|
|
@@ -1813,94 +3190,43 @@ function useKeycloakSSO(config2) {
|
|
|
1813
3190
|
}
|
|
1814
3191
|
|
|
1815
3192
|
// src/SpreePay.tsx
|
|
1816
|
-
import { jsx as
|
|
1817
|
-
var
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
keyklockUrl: "https://auth.dev.join.bookit.com",
|
|
1822
|
-
keyklockClientId: "oneof-next",
|
|
1823
|
-
pointsConversionRatio: 100,
|
|
1824
|
-
pointsTitle: "AIR SP"
|
|
1825
|
-
},
|
|
1826
|
-
moca: {
|
|
1827
|
-
slapiUrl: "https://slapi.dev.air.shop",
|
|
1828
|
-
keyklockUrl: "https://login.dev.air.shop",
|
|
1829
|
-
keyklockClientId: "oneof-next",
|
|
1830
|
-
pointsConversionRatio: 100,
|
|
1831
|
-
pointsTitle: "AIR SP"
|
|
1832
|
-
}
|
|
1833
|
-
},
|
|
1834
|
-
stg: {
|
|
1835
|
-
bookit: {
|
|
1836
|
-
slapiUrl: "https://slapi.stg.superlogic.com",
|
|
1837
|
-
keyklockUrl: "https://auth.stg.join.bookit.com",
|
|
1838
|
-
keyklockClientId: "oneof-next",
|
|
1839
|
-
pointsConversionRatio: 100,
|
|
1840
|
-
pointsTitle: "AIR SP"
|
|
1841
|
-
},
|
|
1842
|
-
moca: {
|
|
1843
|
-
slapiUrl: "https://slapi.stg.air.shop",
|
|
1844
|
-
keyklockUrl: "https://login.stg.air.shop",
|
|
1845
|
-
keyklockClientId: "oneof-next",
|
|
1846
|
-
pointsConversionRatio: 100,
|
|
1847
|
-
pointsTitle: "AIR SP"
|
|
1848
|
-
}
|
|
1849
|
-
},
|
|
1850
|
-
prod: {
|
|
1851
|
-
bookit: {
|
|
1852
|
-
slapiUrl: "https://slapi.superlogic.com",
|
|
1853
|
-
keyklockUrl: "https://auth.join.bookit.com",
|
|
1854
|
-
keyklockClientId: "oneof-next",
|
|
1855
|
-
pointsConversionRatio: 100,
|
|
1856
|
-
pointsTitle: "AIR SP"
|
|
1857
|
-
},
|
|
1858
|
-
moca: {
|
|
1859
|
-
slapiUrl: "https://slapi.air.shop",
|
|
1860
|
-
keyklockUrl: "https://login.air.shop",
|
|
1861
|
-
keyklockClientId: "oneof-next",
|
|
1862
|
-
pointsConversionRatio: 100,
|
|
1863
|
-
pointsTitle: "AIR SP"
|
|
1864
|
-
}
|
|
1865
|
-
}
|
|
1866
|
-
};
|
|
1867
|
-
var SpreePay = ({ className, ...rest }) => {
|
|
1868
|
-
const rootRef = useRef3(null);
|
|
1869
|
-
const [portalEl, setPortalEl] = useState7(null);
|
|
1870
|
-
useLayoutEffect(() => {
|
|
3193
|
+
import { jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
3194
|
+
var SpreePayInner = () => {
|
|
3195
|
+
const rootRef = useRef7(null);
|
|
3196
|
+
const [portalEl, setPortalEl] = useState13(null);
|
|
3197
|
+
useLayoutEffect3(() => {
|
|
1871
3198
|
if (!rootRef.current) return;
|
|
1872
3199
|
const el = rootRef.current.querySelector(":scope > .sl-spreepay__portal");
|
|
1873
3200
|
setPortalEl(el ?? null);
|
|
1874
3201
|
}, []);
|
|
1875
3202
|
const { env } = useSpreePayEnv();
|
|
1876
|
-
const
|
|
3203
|
+
const { staticConfig, appProps } = useStaticConfig();
|
|
1877
3204
|
const tenantId = env?.tenantId || "bookit";
|
|
1878
|
-
const config2 = CONFIG[environment]?.[tenantId];
|
|
1879
3205
|
const { isChecking, accessToken } = useKeycloakSSO({
|
|
1880
3206
|
realm: tenantId,
|
|
1881
|
-
url:
|
|
1882
|
-
clientId:
|
|
3207
|
+
url: staticConfig.keycloakUrl,
|
|
3208
|
+
clientId: staticConfig.keycloakClientId,
|
|
1883
3209
|
ssoPageURI: env?.ssoPageURI,
|
|
1884
3210
|
enabled: !env?.accessToken
|
|
1885
3211
|
});
|
|
1886
|
-
const slapiFetcher =
|
|
3212
|
+
const slapiFetcher = useMemo8(() => {
|
|
1887
3213
|
if (accessToken || env.accessToken) {
|
|
1888
3214
|
return registerApi({
|
|
1889
3215
|
accessToken: env.accessToken || accessToken,
|
|
1890
3216
|
tenantId,
|
|
1891
|
-
baseUrl:
|
|
3217
|
+
baseUrl: staticConfig.slapiUrl
|
|
1892
3218
|
});
|
|
1893
3219
|
}
|
|
1894
|
-
}, [env.accessToken,
|
|
3220
|
+
}, [env.accessToken, staticConfig, tenantId, accessToken]);
|
|
1895
3221
|
const getContent = () => {
|
|
1896
3222
|
if (isChecking) {
|
|
1897
|
-
return /* @__PURE__ */
|
|
1898
|
-
/* @__PURE__ */
|
|
1899
|
-
/* @__PURE__ */
|
|
1900
|
-
/* @__PURE__ */
|
|
3223
|
+
return /* @__PURE__ */ jsxs27("div", { className: "flex w-full flex-col", children: [
|
|
3224
|
+
/* @__PURE__ */ jsx40("div", { className: "bg-primary/8 mb-4 h-[315px] animate-pulse rounded-3xl" }),
|
|
3225
|
+
/* @__PURE__ */ jsx40("div", { className: "bg-primary/8 h-[135px] animate-pulse rounded-3xl" }),
|
|
3226
|
+
/* @__PURE__ */ jsx40(SpreeLegal, {})
|
|
1901
3227
|
] });
|
|
1902
3228
|
}
|
|
1903
|
-
return /* @__PURE__ */
|
|
3229
|
+
return /* @__PURE__ */ jsx40(
|
|
1904
3230
|
SWRConfig,
|
|
1905
3231
|
{
|
|
1906
3232
|
value: {
|
|
@@ -1909,26 +3235,30 @@ var SpreePay = ({ className, ...rest }) => {
|
|
|
1909
3235
|
revalidateOnFocus: false,
|
|
1910
3236
|
revalidateIfStale: false
|
|
1911
3237
|
},
|
|
1912
|
-
children: /* @__PURE__ */
|
|
3238
|
+
children: /* @__PURE__ */ jsx40(PortalContainerProvider, { container: portalEl, children: /* @__PURE__ */ jsx40(NiceModal7.Provider, { children: /* @__PURE__ */ jsx40(SpreePayContent, { isLoggedIn: Boolean(accessToken || env.accessToken) }) }) })
|
|
1913
3239
|
}
|
|
1914
3240
|
);
|
|
1915
3241
|
};
|
|
1916
|
-
return /* @__PURE__ */
|
|
1917
|
-
/* @__PURE__ */
|
|
3242
|
+
return /* @__PURE__ */ jsxs27("div", { ref: rootRef, className: cn("sl-spreepay", appProps.className), children: [
|
|
3243
|
+
/* @__PURE__ */ jsx40("div", { className: "sl-spreepay__portal" }),
|
|
1918
3244
|
getContent()
|
|
1919
3245
|
] });
|
|
1920
3246
|
};
|
|
3247
|
+
var SpreePay = (props) => {
|
|
3248
|
+
return /* @__PURE__ */ jsx40(StaticConfigProvider, { props, children: /* @__PURE__ */ jsx40(SpreePayInner, {}) });
|
|
3249
|
+
};
|
|
1921
3250
|
|
|
1922
3251
|
// src/hooks/useCapture3DS.ts
|
|
1923
|
-
import { useEffect as
|
|
3252
|
+
import { useEffect as useEffect11 } from "react";
|
|
1924
3253
|
var useCapture3DS = (searchParams) => {
|
|
1925
|
-
|
|
1926
|
-
if (window
|
|
3254
|
+
useEffect11(() => {
|
|
3255
|
+
if (typeof window !== "undefined" && window.parent && searchParams?.paymentIntent) {
|
|
1927
3256
|
window.parent.SP_EVENT_BUS?.emit("paymentIntent", { paymentIntent: searchParams.paymentIntent });
|
|
1928
3257
|
}
|
|
1929
3258
|
}, [searchParams]);
|
|
1930
3259
|
};
|
|
1931
3260
|
export {
|
|
3261
|
+
PaymentType,
|
|
1932
3262
|
SpreePay,
|
|
1933
3263
|
SpreePayProvider,
|
|
1934
3264
|
useCapture3DS,
|